Compare commits

...

30 Commits

Author SHA1 Message Date
c32e38ca10 Merge branch 'devel' 2024-08-23 20:57:11 +02:00
c2cadd1542 Add messages for user 2024-08-23 20:56:44 +02:00
4cb2831e9a Minor changes 2024-08-23 20:51:33 +02:00
ee31a9f8e2 create check_dependency function 2024-08-23 20:36:01 +02:00
beec20cdda Make sure bin and service are owned by root 2024-08-23 20:34:13 +02:00
7ef957c2d7 Added comments for during the update for more context 2024-08-18 17:41:54 +02:00
d7c8c7a43a Merge branch 'devel' 2024-08-18 17:31:00 +02:00
d56cdc78eb Use directories that require administrative privileges 2024-08-18 17:30:43 +02:00
151d89d9f0 Create $EXTRACTION_PATH 2024-08-18 17:10:10 +02:00
8d2944d00c Only delete contents of $CPOLIS_PATH 2024-08-18 17:06:49 +02:00
9ddd8198ee Use /tmp directory for downloading .tar.gz archive 2024-08-18 17:03:31 +02:00
ff6c7a66d7 Fixed a typo 2024-08-18 16:59:49 +02:00
129c85929c Small cleanup 2024-08-18 13:56:41 +02:00
b1a6359473 Exit update script if any requirement is not met 2024-08-18 13:53:37 +02:00
b5d979dbf8 Created update script and systemd service 2024-08-18 13:49:31 +02:00
1cd3edc90c Merge branch 'devel' 2024-08-18 12:06:29 +02:00
77e8edbe16 Relocated ShowHub from articles.go to sessions.go because it has even less to do with articles than with sessions 2024-08-18 11:46:23 +02:00
8115c50974 Fixed a bug that let users get around verification. 2024-08-18 11:40:03 +02:00
61bfa85b13 Some cleaning up 2024-08-18 11:21:42 +02:00
cd27349d04 Created package "calls" and verification for frontend and calls 2024-08-18 11:20:06 +02:00
5b41892dff Renamed frontend/firebase.go to frontend/pdf.go 2024-08-17 21:00:00 +02:00
c7add76a12 Deleted ServePDFs() and added ServePDF() 2024-08-17 20:56:45 +02:00
f4ae2f9c04 Added rout for pdf list 2024-08-17 20:41:39 +02:00
0e768c9f61 Merge branch 'devel' 2024-08-08 21:27:07 +02:00
1fcd775cc5 Merge branch 'devel' 2024-08-08 21:14:24 +02:00
203a1ed147 Implemented EasyMDE 2024-08-08 21:13:25 +02:00
ef1914ee5c Implemented article preview 2024-08-08 21:13:25 +02:00
084b101e31 Register f.ArticlePreviewHtmlData in init() 2024-08-08 21:13:25 +02:00
b2db128aa9 Shorten lines by referencing frontend as f and backend as b 2024-08-08 21:13:25 +02:00
081e880fb6 Change structure of code tor frontend and backend one 2024-08-08 21:13:25 +02:00
14 changed files with 281 additions and 160 deletions

View File

@ -1,40 +1,15 @@
package frontend
package calls
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strings"
b "streifling.com/jason/cpolis/cmd/backend"
)
func tokenIsVerified(w http.ResponseWriter, r *http.Request) bool {
idToken := r.Header.Get("Authorization")
if idToken == "" {
log.Println("Authorization header missing")
http.Error(w, "Authorization header missing", http.StatusUnauthorized)
return false
}
client, err := b.NewClient()
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return false
}
_, err = client.Verify(idToken)
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusUnauthorized)
return false
}
return true
}
func ServePDFList(c *b.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if tokenIsVerified(w, r) {
@ -60,15 +35,10 @@ func ServePDFList(c *b.Config) http.HandlerFunc {
}
}
func ServePDFs(c *b.Config) http.HandlerFunc {
func ServePDF(c *b.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if tokenIsVerified(w, r) {
pdfIDsString := r.PathValue("ids")
pdfIDs := strings.Split(pdfIDsString, ",")
for _, id := range pdfIDs {
http.ServeFile(w, r, id)
}
http.ServeFile(w, r, fmt.Sprint(c.PDFDir, "/", r.PathValue("id")))
}
}
}

15
cmd/calls/rss.go Normal file
View File

@ -0,0 +1,15 @@
package calls
import (
"net/http"
b "streifling.com/jason/cpolis/cmd/backend"
)
func ServeRSS(c *b.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if tokenIsVerified(w, r) {
http.ServeFile(w, r, c.RSSFile)
}
}
}

34
cmd/calls/verification.go Normal file
View File

@ -0,0 +1,34 @@
package calls
import (
"log"
"net/http"
b "streifling.com/jason/cpolis/cmd/backend"
)
// tokenIsVerified verifies that a request is authorized. It returns a bool.
func tokenIsVerified(w http.ResponseWriter, r *http.Request) bool {
idToken := r.Header.Get("Authorization")
if idToken == "" {
log.Println("Authorization header missing")
http.Error(w, "Authorization header missing", http.StatusUnauthorized)
return false
}
client, err := b.NewClient()
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return false
}
_, err = client.Verify(idToken)
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusUnauthorized)
return false
}
return true
}

View File

@ -23,29 +23,13 @@ const (
PreviewMode
)
func ShowHub(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := s.Get(r, "cookie")
session, err := getSession(w, r, c, s)
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
session.Values["article"] = nil
if err = session.Save(r, w); err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", session.Values["role"].(int))
}
}
func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
type editorHTMLData struct {
Title string
Description string
@ -55,13 +39,6 @@ func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
Mode int
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
var data editorHTMLData
if session.Values["article"] == nil {
data = editorHTMLData{}
@ -84,11 +61,9 @@ func WriteArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := s.Get(r, "cookie")
session, err := getSession(w, r, c, s)
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
return
}
session.Values["article"] = nil
@ -139,6 +114,11 @@ func SubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
@ -178,21 +158,18 @@ func ResubmitArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])
}
}
func ShowUnpublishedArticles(c *b.Config, db *b.DB) http.HandlerFunc {
func ShowUnpublishedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
unpublishedArticles, err := db.GetCertainArticles(false, false)
if err != nil {
log.Println(err)
@ -208,19 +185,17 @@ func ShowUnpublishedArticles(c *b.Config, db *b.DB) http.HandlerFunc {
func ShowRejectedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
type htmlData struct {
MyIDs map[int64]bool
RejectedArticles []*b.Article
}
data := new(htmlData)
session, err := s.Get(r, "cookie")
if err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
data.RejectedArticles, err = db.GetCertainArticles(false, true)
if err != nil {
log.Println(err)
@ -243,6 +218,10 @@ func ShowRejectedArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerF
func ReviewUnpublishedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
type htmlData struct {
Title string
Description string
@ -305,6 +284,10 @@ func ReviewUnpublishedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Hand
func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
type htmlData struct {
Selected map[int64]bool
Article *b.Article
@ -352,6 +335,11 @@ func ReviewRejectedArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.Handler
func PublishArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
@ -359,13 +347,6 @@ func PublishArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
if err = db.AddArticleToCurrentIssue(id); err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
@ -402,6 +383,11 @@ func PublishArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func RejectArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
@ -409,13 +395,6 @@ func RejectArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
if err = db.UpdateAttributes(
&b.Attribute{Table: "articles", ID: id, AttName: "rejected", Value: true},
); err != nil {
@ -430,8 +409,12 @@ func RejectArticle(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
}
}
func ShowCurrentArticles(c *b.Config, db *b.DB) http.HandlerFunc {
func ShowCurrentArticles(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
articles, err := db.GetCurrentIssueArticles()
if err != nil {
log.Println(err)
@ -444,8 +427,12 @@ func ShowCurrentArticles(c *b.Config, db *b.DB) http.HandlerFunc {
}
}
func UploadImage(c *b.Config) http.HandlerFunc {
func UploadImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
file, header, err := r.FormFile("article-image")
if err != nil {
log.Println(err)

View File

@ -7,8 +7,12 @@ import (
b "streifling.com/jason/cpolis/cmd/backend"
)
func CreateTag(c *b.Config) http.HandlerFunc {
func CreateTag(c *b.Config, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-tag.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
}
@ -16,15 +20,13 @@ func CreateTag(c *b.Config) http.HandlerFunc {
func AddTag(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
db.AddTag(r.PostFormValue("tag"))
session, err := s.Get(r, "cookie")
session, err := getSession(w, r, c, s)
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
return
}
db.AddTag(r.PostFormValue("tag"))
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])

View File

@ -10,6 +10,10 @@ import (
func ServeImage(c *b.Config, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
absFilepath, err := filepath.Abs(c.PicsDir)
if err != nil {
log.Println(err)

View File

@ -10,19 +10,17 @@ import (
func PublishLatestIssue(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
if err := db.PublishLatestIssue(); err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"])

View File

@ -90,11 +90,9 @@ func Login(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func Logout(c *b.Config, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := s.Get(r, "cookie")
session, err := getSession(w, r, c, s)
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
return
}
session.Options.MaxAge = -1
@ -109,3 +107,22 @@ func Logout(c *b.Config, s *b.CookieStore) http.HandlerFunc {
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
}
}
func ShowHub(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
session.Values["article"] = nil
if err = session.Save(r, w); err != nil {
log.Println(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", session.Values["role"].(int))
}
}

View File

@ -30,8 +30,12 @@ func checkUserStrings(user *b.User) (string, int, bool) {
}
}
func CreateUser(c *b.Config) http.HandlerFunc {
func CreateUser(c *b.Config, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/add-user.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", nil)
}
@ -39,6 +43,11 @@ func CreateUser(c *b.Config) http.HandlerFunc {
func AddUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
role, err := strconv.Atoi(r.PostFormValue("role"))
if err != nil {
log.Println(err)
@ -94,13 +103,6 @@ func AddUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
@ -109,11 +111,9 @@ func AddUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func EditSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := s.Get(r, "cookie")
session, err := getSession(w, r, c, s)
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
return
}
user, err := db.GetUser(session.Values["id"].(int64))
@ -130,11 +130,9 @@ func EditSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func UpdateSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := s.Get(r, "cookie")
session, err := getSession(w, r, c, s)
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
return
}
userData := UserData{
@ -200,8 +198,11 @@ func UpdateSelf(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func AddFirstUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var err error
if _, err := getSession(w, r, c, s); err != nil {
return
}
var err error
htmlData := UserData{
User: &b.User{
UserName: r.PostFormValue("username"),
@ -275,7 +276,11 @@ func AddFirstUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func ShowAllUsers(c *b.Config, db *b.DB, s *b.CookieStore, action string) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var err error
session, err := getSession(w, r, c, s)
if err != nil {
return
}
type htmlData struct {
Users map[int64]*b.User
Action string
@ -289,21 +294,18 @@ func ShowAllUsers(c *b.Config, db *b.DB, s *b.CookieStore, action string) http.H
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
delete(data.Users, session.Values["id"].(int64))
tmpl, err := template.ParseFiles(c.WebDir + "/templates/show-all-users.html")
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", data)
}
}
func EditUser(c *b.Config, db *b.DB) http.HandlerFunc {
func EditUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if _, err := getSession(w, r, c, s); err != nil {
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
@ -325,6 +327,11 @@ func EditUser(c *b.Config, db *b.DB) http.HandlerFunc {
func UpdateUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
@ -394,13 +401,6 @@ func UpdateUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", userData)
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))
@ -409,6 +409,11 @@ func UpdateUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
func DeleteUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, err := getSession(w, r, c, s)
if err != nil {
return
}
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
if err != nil {
log.Println(err)
@ -422,13 +427,6 @@ func DeleteUser(c *b.Config, db *b.DB, s *b.CookieStore) http.HandlerFunc {
return
}
session, err := s.Get(r, "cookie")
if err != nil {
tmpl, err := template.ParseFiles(c.WebDir + "/templates/login.html")
msg := "Session nicht mehr gültig. Bitte erneut anmelden."
template.Must(tmpl, err).ExecuteTemplate(w, "page-content", msg)
}
tmpl, err := template.ParseFiles(c.WebDir + "/templates/hub.html")
tmpl = template.Must(tmpl, err)
tmpl.ExecuteTemplate(w, "page-content", session.Values["role"].(int))

View File

@ -0,0 +1,29 @@
package frontend
import (
"errors"
"html/template"
"net/http"
"github.com/gorilla/sessions"
b "streifling.com/jason/cpolis/cmd/backend"
)
// getSession is used for verifying that the user is logged in and returns their session and an error.
func getSession(w http.ResponseWriter, r *http.Request, c *b.Config, s *b.CookieStore) (*sessions.Session, error) {
msg := "Keine gültige Session. Bitte erneut anmelden."
tmpl, tmplErr := template.ParseFiles(c.WebDir+"/templates/index.html", c.WebDir+"/templates/login.html")
session, err := s.Get(r, "cookie")
if err != nil {
template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg)
return nil, err
}
if session.IsNew {
template.Must(tmpl, tmplErr).ExecuteTemplate(w, "page-content", msg)
return session, errors.New("error: no existing session")
}
return session, nil
}

View File

@ -7,6 +7,7 @@ import (
"os"
b "streifling.com/jason/cpolis/cmd/backend"
c "streifling.com/jason/cpolis/cmd/calls"
f "streifling.com/jason/cpolis/cmd/frontend"
)
@ -48,13 +49,15 @@ func main() {
http.FileServer(http.Dir(config.WebDir+"/static/"))))
mux.HandleFunc("/", f.HomePage(config, db, store))
mux.HandleFunc("GET /create-tag", f.CreateTag(config))
mux.HandleFunc("GET /create-user", f.CreateUser(config))
mux.HandleFunc("GET /create-tag", f.CreateTag(config, store))
mux.HandleFunc("GET /create-user", f.CreateUser(config, store))
mux.HandleFunc("GET /edit-self", f.EditSelf(config, db, store))
mux.HandleFunc("GET /edit-user/{id}", f.EditUser(config, db))
mux.HandleFunc("GET /edit-user/{id}", f.EditUser(config, db, store))
mux.HandleFunc("GET /delete-user/{id}", f.DeleteUser(config, db, store))
mux.HandleFunc("GET /hub", f.ShowHub(config, db, store))
mux.HandleFunc("GET /logout", f.Logout(config, store))
mux.HandleFunc("GET /pdf/get-list", c.ServePDFList(config))
mux.HandleFunc("GET /pdf/{id}", c.ServePDF(config))
mux.HandleFunc("GET /pics/{pic}", f.ServeImage(config, store))
mux.HandleFunc("GET /publish-article/{id}", f.PublishArticle(config, db, store))
mux.HandleFunc("GET /publish-issue", f.PublishLatestIssue(config, db, store))
@ -62,11 +65,11 @@ func main() {
mux.HandleFunc("GET /rejected-articles", f.ShowRejectedArticles(config, db, store))
mux.HandleFunc("GET /review-rejected-article/{id}", f.ReviewRejectedArticle(config, db, store))
mux.HandleFunc("GET /review-unpublished-article/{id}", f.ReviewUnpublishedArticle(config, db, store))
mux.HandleFunc("GET /rss", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, config.RSSFile) })
mux.HandleFunc("GET /rss", c.ServeRSS(config))
mux.HandleFunc("GET /show-all-users-edit", f.ShowAllUsers(config, db, store, "edit-user"))
mux.HandleFunc("GET /show-all-users-delete", f.ShowAllUsers(config, db, store, "delete-user"))
mux.HandleFunc("GET /this-issue", f.ShowCurrentArticles(config, db))
mux.HandleFunc("GET /unpublished-articles", f.ShowUnpublishedArticles(config, db))
mux.HandleFunc("GET /this-issue", f.ShowCurrentArticles(config, db, store))
mux.HandleFunc("GET /unpublished-articles", f.ShowUnpublishedArticles(config, db, store))
mux.HandleFunc("GET /write-article", f.WriteArticle(config, db, store))
mux.HandleFunc("POST /add-first-user", f.AddFirstUser(config, db, store))
@ -77,7 +80,7 @@ func main() {
mux.HandleFunc("POST /submit-article", f.SubmitArticle(config, db, store))
mux.HandleFunc("POST /update-self", f.UpdateSelf(config, db, store))
mux.HandleFunc("POST /update-user/{id}", f.UpdateUser(config, db, store))
mux.HandleFunc("POST /upload-image", f.UploadImage(config))
mux.HandleFunc("POST /upload-image", f.UploadImage(config, store))
log.Fatalln(http.ListenAndServe(config.Port, mux))
}

9
cpolis.service Normal file
View File

@ -0,0 +1,9 @@
[Unit]
Description=cpolis
[Service]
ExecStart=/usr/local/bin/cpolis
Restart=on-failure
[Install]
WantedBy=default.target

2
go.mod
View File

@ -13,6 +13,7 @@ require (
github.com/yuin/goldmark v1.7.0
golang.org/x/crypto v0.21.0
golang.org/x/term v0.18.0
google.golang.org/api v0.170.0
)
require (
@ -48,7 +49,6 @@ require (
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/api v0.170.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/appengine/v2 v2.0.2 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect

55
update.sh Executable file
View File

@ -0,0 +1,55 @@
#! /bin/sh -
CPOLIS_REPO_URL="https://git.streifling.com/api/v1/repos/jason/cpolis/releases"
EXTRACTION_DIR=$HOME
CPOLIS_DIR=$EXTRACTION_DIR/cpolis
TAILWINDCSS_REPO_URL=https://api.github.com/repos/tailwindlabs/tailwindcss/releases/latest
TMP_DIR=/tmp
BIN_DIR=/usr/local/bin
check_dependency() {
if ! which $1 >/dev/null 2>&1; then
echo "$1 needs to be installed" >&2
exit 1
fi
}
if ! groups | grep -E 'root|wheel|sudo' >/dev/null; then
echo "You need administrative privileges for this script" >&2
exit 1
fi
check_dependency curl
check_dependency go
check_dependency jq
check_dependency tar
check_dependency xargs
echo -e '\nDownloading cpolis...' >&2
rm -fr $CPOLIS_DIR/*
latest_release=$(curl -s $CPOLIS_REPO_URL | jq -r '.[0].tag_name')
curl -Lo $TMP_DIR/cpolis.tar.gz https://git.streifling.com/jason/cpolis/archive/$latest_release.tar.gz
tar -xzf $TMP_DIR/cpolis.tar.gz -C $EXTRACTION_DIR
rm $TMP_DIR/cpolis.tar.gz
echo -e '\nDownloading TailwindCSS...' >&2
curl -s $TAILWINDCSS_REPO_URL |
grep -F browser_download_url |
grep -F linux-x64 |
cut -d'"' -f4 |
xargs -r curl -Lo $CPOLIS_DIR/tailwindcss
chmod +x $CPOLIS_DIR/tailwindcss
$CPOLIS_DIR/tailwindcss -i web/static/css/input.css -o web/static/css/style.css
echo -e 'Building cpolis...' >&2
go build -o $TMP_DIR/cpolis $CPOLIS_DIR/cmd/main.go
echo -e 'Setting system files up...' >&2
sudo mv $TMP_DIR/cpolis $BIN_DIR/cpolis
sudo chown root:root $BIN_DIR/cpolis
chmod +x $BIN_DIR/cpolis
sudo mv $CPOLIS_DIR/cpolis.service $SYSTEMD_DIR
sudo chown root:root $SYSTEMD_DIR/cpolis.service
sudo systemctl daemon-reload
sudo systemctl is-active --quiet cpolis.service && sudo systemctl restart cpolis.service