package webserver
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"git.tovijaeschke.xyz/tovi/personal_website/database"
|
|
"git.tovijaeschke.xyz/tovi/personal_website/helper"
|
|
"git.tovijaeschke.xyz/tovi/personal_website/variables"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/gorilla/sessions"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func CheckAuth(w http.ResponseWriter, r *http.Request) bool {
|
|
var (
|
|
session *sessions.Session
|
|
lastLoginUnix int64
|
|
lastLogin time.Time
|
|
auth bool
|
|
exists bool
|
|
e error
|
|
)
|
|
session, e = variables.CookieStore.Get(r, variables.CookieName)
|
|
if e != nil {
|
|
return false
|
|
}
|
|
|
|
auth, exists = session.Values["authenticated"].(bool)
|
|
if !(auth && exists) {
|
|
return false
|
|
}
|
|
|
|
lastLoginUnix, exists = session.Values["lastLogin"].(int64)
|
|
if !exists {
|
|
return false
|
|
}
|
|
lastLogin = time.Unix(lastLoginUnix, 0)
|
|
lastLogin = lastLogin.Add(3 * time.Hour)
|
|
|
|
if time.Now().After(lastLogin) {
|
|
session.Values = make(map[interface{}]interface{})
|
|
session.Values["authenticated"] = false
|
|
session.AddFlash("Login Expired")
|
|
e = session.Save(r, w)
|
|
if e != nil {
|
|
log.Println(e.Error())
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func AdminView(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
v = make(map[string]interface{})
|
|
urlParams map[string]string
|
|
page string
|
|
pageInt int
|
|
pageOffset int
|
|
posts []database.Post
|
|
exists bool
|
|
e error
|
|
)
|
|
|
|
if !CheckAuth(w, r) {
|
|
http.Redirect(w, r, "/admin/login", 302)
|
|
return
|
|
}
|
|
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
|
|
urlParams = mux.Vars(r)
|
|
|
|
page, exists = urlParams["page"]
|
|
if exists {
|
|
pageInt, e = strconv.Atoi(page)
|
|
if e != nil {
|
|
log.Fatal("Url Parameter page cannot be converted to an int")
|
|
}
|
|
} else {
|
|
pageInt = 0
|
|
}
|
|
|
|
pageOffset = pageInt * 10
|
|
|
|
posts, e = database.GetPostsList(10, pageOffset)
|
|
|
|
v["Posts"] = posts
|
|
|
|
ServeTemplate(w, r, "html/admin/admin-index.gohtml", v)
|
|
return
|
|
}
|
|
}
|
|
|
|
func comparePasswords(hashedPwd, plainPwd string) bool {
|
|
var (
|
|
e error
|
|
)
|
|
e = bcrypt.CompareHashAndPassword(
|
|
[]byte(hashedPwd),
|
|
[]byte(plainPwd),
|
|
)
|
|
if e != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func AdminLogout(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
session *sessions.Session
|
|
e error
|
|
)
|
|
|
|
if !CheckAuth(w, r) {
|
|
http.Redirect(w, r, "/admin/login", 302)
|
|
return
|
|
}
|
|
|
|
session, e = variables.CookieStore.Get(r, variables.CookieName)
|
|
if e != nil {
|
|
log.Println("Could not get session cookie")
|
|
http.Error(w, "Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
session.Values["authenticated"] = false
|
|
session.Values["lastLogin"] = nil
|
|
session.Save(r, w)
|
|
|
|
http.Redirect(w, r, "/admin/logout", 302)
|
|
return
|
|
}
|
|
|
|
func AdminLogin(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
session *sessions.Session
|
|
v = make(map[string]interface{})
|
|
flashes []interface{}
|
|
username string
|
|
password string
|
|
e error
|
|
)
|
|
|
|
if CheckAuth(w, r) {
|
|
http.Redirect(w, r, "/admin", 302)
|
|
return
|
|
}
|
|
|
|
session, e = variables.CookieStore.Get(r, variables.CookieName)
|
|
if e != nil {
|
|
log.Println("Could not get session cookie")
|
|
http.Error(w, "Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
flashes = session.Flashes()
|
|
e = session.Save(r, w)
|
|
if e != nil {
|
|
log.Println(e.Error())
|
|
return
|
|
}
|
|
if len(flashes) > 0 {
|
|
v["FlashMsg"] = flashes[0].(string)
|
|
}
|
|
|
|
ServeTemplate(w, r, "html/admin/admin-login.gohtml", v)
|
|
return
|
|
|
|
case http.MethodPost:
|
|
e = r.ParseForm()
|
|
if e != nil {
|
|
log.Println(e.Error())
|
|
http.Redirect(w, r, "/login", 302)
|
|
}
|
|
|
|
username = r.FormValue("username")
|
|
password = r.FormValue("password")
|
|
|
|
if username != variables.AdminPassword && !comparePasswords(variables.AdminPassword, password) {
|
|
session.AddFlash("Invalid Username or Password")
|
|
e = session.Save(r, w)
|
|
if e != nil {
|
|
log.Println(e.Error())
|
|
}
|
|
http.Redirect(w, r, "/admin/login", 302)
|
|
return
|
|
|
|
}
|
|
|
|
session.Values["authenticated"] = true
|
|
session.Values["lastLogin"] = time.Now().Unix()
|
|
session.Save(r, w)
|
|
|
|
http.Redirect(w, r, "/admin", 302)
|
|
return
|
|
}
|
|
}
|
|
|
|
func AdminNewPost(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
session *sessions.Session
|
|
v = make(map[string]interface{})
|
|
flashes []interface{}
|
|
title, subject, intro, body string
|
|
bodyPath string
|
|
mainFilePath string = ""
|
|
fileUpload []*multipart.FileHeader
|
|
//otherImgs string
|
|
e error
|
|
)
|
|
|
|
if !CheckAuth(w, r) {
|
|
http.Redirect(w, r, "/admin/login", 302)
|
|
return
|
|
}
|
|
|
|
session, e = variables.CookieStore.Get(r, variables.CookieName)
|
|
if e != nil {
|
|
log.Println("Could not get session cookie")
|
|
http.Error(w, "Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
flashes = session.Flashes()
|
|
e = session.Save(r, w)
|
|
if e != nil {
|
|
log.Println(e.Error())
|
|
return
|
|
}
|
|
if len(flashes) > 0 {
|
|
v["FlashMsg"] = flashes[0].(string)
|
|
}
|
|
|
|
ServeTemplate(w, r, "html/admin/admin-new-post.gohtml", v)
|
|
return
|
|
|
|
case http.MethodPost:
|
|
|
|
title = r.FormValue("title")
|
|
subject = r.FormValue("subject")
|
|
intro = r.FormValue("intro")
|
|
body = r.FormValue("body")
|
|
|
|
bodyPath, e = helper.WriteBody(title, body)
|
|
if e != nil {
|
|
log.Fatal(e)
|
|
}
|
|
|
|
r.ParseMultipartForm(32 << 20) // 32MB is the default used by FormFile
|
|
fileUpload = r.MultipartForm.File["img"]
|
|
|
|
helper.UploadFiles(fileUpload)
|
|
|
|
if len(fileUpload) == 1 {
|
|
mainFilePath = fileUpload[0].Filename
|
|
}
|
|
|
|
fileUpload = r.MultipartForm.File["files"]
|
|
|
|
helper.UploadFiles(fileUpload)
|
|
|
|
database.CreatePost(
|
|
database.Post{
|
|
Title: title,
|
|
Subject: subject,
|
|
Intro: intro,
|
|
HtmlPath: bodyPath,
|
|
MainImage: mainFilePath,
|
|
},
|
|
)
|
|
|
|
http.Redirect(w, r, "/admin", 302)
|
|
return
|
|
}
|
|
}
|
|
|
|
func AdminEditPost(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
session *sessions.Session
|
|
v = make(map[string]interface{})
|
|
urlParams map[string]string
|
|
flashes []interface{}
|
|
title, subject, intro, body string
|
|
bodyPath string
|
|
post database.Post
|
|
fileUpload []*multipart.FileHeader
|
|
e error
|
|
)
|
|
|
|
if !CheckAuth(w, r) {
|
|
http.Redirect(w, r, "/admin/login", 302)
|
|
return
|
|
}
|
|
|
|
session, e = variables.CookieStore.Get(r, variables.CookieName)
|
|
if e != nil {
|
|
log.Println("Could not get session cookie")
|
|
http.Error(w, "Error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
flashes = session.Flashes()
|
|
e = session.Save(r, w)
|
|
if e != nil {
|
|
log.Println(e.Error())
|
|
return
|
|
}
|
|
if len(flashes) > 0 {
|
|
v["FlashMsg"] = flashes[0].(string)
|
|
}
|
|
|
|
urlParams = mux.Vars(r)
|
|
|
|
post, e = database.GetPostById(urlParams["id"])
|
|
if e != nil {
|
|
log.Fatal("Cannot get Post by id")
|
|
}
|
|
|
|
post.Body, e = helper.GetFileContents(post.HtmlPath)
|
|
if e != nil {
|
|
log.Fatal("Cannot read body file")
|
|
}
|
|
|
|
v["Post"] = post
|
|
|
|
ServeTemplate(w, r, "html/admin/admin-update-post.gohtml", v)
|
|
return
|
|
|
|
case http.MethodPost:
|
|
|
|
urlParams = mux.Vars(r)
|
|
|
|
post, e = database.GetPostById(urlParams["id"])
|
|
if e != nil {
|
|
log.Fatal("Cannot get Post by id")
|
|
}
|
|
|
|
title = r.FormValue("title")
|
|
subject = r.FormValue("subject")
|
|
intro = r.FormValue("intro")
|
|
body = r.FormValue("body")
|
|
|
|
if title != post.Title {
|
|
defer helper.DeleteOldPostFile(post.Title)
|
|
}
|
|
|
|
bodyPath, e = helper.WriteBody(title, body)
|
|
if e != nil {
|
|
log.Fatal(e)
|
|
}
|
|
|
|
r.ParseMultipartForm(32 << 20) // 32MB is the default used by FormFile
|
|
fileUpload = r.MultipartForm.File["img"]
|
|
|
|
helper.UploadFiles(fileUpload)
|
|
|
|
if len(fileUpload) == 1 {
|
|
post.MainImage = fileUpload[0].Filename
|
|
}
|
|
|
|
fileUpload = r.MultipartForm.File["files"]
|
|
|
|
helper.UploadFiles(fileUpload)
|
|
|
|
post.Title = title
|
|
post.Subject = subject
|
|
post.Intro = intro
|
|
post.HtmlPath = bodyPath
|
|
|
|
database.UpdatePost(
|
|
post,
|
|
)
|
|
|
|
http.Redirect(w, r, fmt.Sprintf("/admin/post/%s/edit", post.ID), 302)
|
|
return
|
|
}
|
|
}
|