You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

375 lines
7.6 KiB

  1. package Webserver
  2. import (
  3. "fmt"
  4. "log"
  5. "mime/multipart"
  6. "net/http"
  7. "strconv"
  8. "time"
  9. "PersonalWebsite/Database"
  10. "PersonalWebsite/Helper"
  11. "PersonalWebsite/Variables"
  12. "github.com/gorilla/mux"
  13. "github.com/gorilla/sessions"
  14. "golang.org/x/crypto/bcrypt"
  15. )
  16. func CheckAuth(w http.ResponseWriter, r *http.Request) bool {
  17. var (
  18. session *sessions.Session
  19. lastActiveUnix int64
  20. lastActive time.Time
  21. auth bool
  22. exists bool
  23. e error
  24. )
  25. session, e = Variables.CookieStore.Get(r, Variables.CookieName)
  26. if e != nil {
  27. return false
  28. }
  29. auth, exists = session.Values["authenticated"].(bool)
  30. if !(auth && exists) {
  31. return false
  32. }
  33. lastActiveUnix, exists = session.Values["lastActive"].(int64)
  34. if !exists {
  35. return false
  36. }
  37. lastActive = time.Unix(lastActiveUnix, 0)
  38. lastActive.Add(12 * time.Hour)
  39. if time.Now().Before(lastActive) {
  40. session.Values = make(map[interface{}]interface{})
  41. session.Values["authenticated"] = false
  42. session.AddFlash("Login Expired")
  43. e = session.Save(r, w)
  44. if e != nil {
  45. log.Println(e.Error())
  46. }
  47. return false
  48. }
  49. session.Values["lastLogin"] = time.Now().Unix()
  50. e = session.Save(r, w)
  51. if e != nil {
  52. log.Println(e.Error())
  53. return false
  54. }
  55. return true
  56. }
  57. func AdminView(w http.ResponseWriter, r *http.Request) {
  58. var (
  59. v = make(map[string]interface{})
  60. urlParams map[string]string
  61. page string
  62. pageInt int
  63. pageOffset int
  64. posts []Database.Post
  65. exists bool
  66. e error
  67. )
  68. if !CheckAuth(w, r) {
  69. http.Redirect(w, r, "/admin/login", 302)
  70. return
  71. }
  72. switch r.Method {
  73. case http.MethodGet:
  74. urlParams = mux.Vars(r)
  75. page, exists = urlParams["page"]
  76. if exists {
  77. pageInt, e = strconv.Atoi(page)
  78. if e != nil {
  79. log.Fatal("Url Parameter page cannot be converted to an int")
  80. }
  81. } else {
  82. pageInt = 0
  83. }
  84. pageOffset = pageInt * 10
  85. posts, e = Database.GetPostsList(10, pageOffset)
  86. v["Posts"] = posts
  87. ServeTemplate(w, r, "html/admin/admin-index.gohtml", v)
  88. return
  89. }
  90. }
  91. func comparePasswords(hashedPwd, plainPwd string) bool {
  92. var (
  93. e error
  94. )
  95. e = bcrypt.CompareHashAndPassword(
  96. []byte(hashedPwd),
  97. []byte(plainPwd),
  98. )
  99. if e != nil {
  100. return false
  101. }
  102. return true
  103. }
  104. func AdminLogin(w http.ResponseWriter, r *http.Request) {
  105. var (
  106. session *sessions.Session
  107. v = make(map[string]interface{})
  108. flashes []interface{}
  109. username string
  110. password string
  111. e error
  112. )
  113. if CheckAuth(w, r) {
  114. http.Redirect(w, r, "/admin", 302)
  115. return
  116. }
  117. session, e = Variables.CookieStore.Get(r, Variables.CookieName)
  118. if e != nil {
  119. log.Println("Could not get session cookie")
  120. http.Error(w, "Error", http.StatusInternalServerError)
  121. return
  122. }
  123. switch r.Method {
  124. case http.MethodGet:
  125. flashes = session.Flashes()
  126. e = session.Save(r, w)
  127. if e != nil {
  128. log.Println(e.Error())
  129. return
  130. }
  131. if len(flashes) > 0 {
  132. v["FlashMsg"] = flashes[0].(string)
  133. }
  134. ServeTemplate(w, r, "html/admin/admin-login.gohtml", v)
  135. return
  136. case http.MethodPost:
  137. e = r.ParseForm()
  138. if e != nil {
  139. log.Println(e.Error())
  140. http.Redirect(w, r, "/login", 302)
  141. }
  142. username = r.FormValue("username")
  143. password = r.FormValue("password")
  144. if username != Variables.AdminPassword && !comparePasswords(Variables.AdminPassword, password) {
  145. session.AddFlash("Invalid Username or Password")
  146. e = session.Save(r, w)
  147. if e != nil {
  148. log.Println(e.Error())
  149. }
  150. http.Redirect(w, r, "/admin/login", 302)
  151. return
  152. }
  153. session.Values["authenticated"] = true
  154. session.Values["lastActive"] = time.Now().Unix()
  155. session.Save(r, w)
  156. http.Redirect(w, r, "/admin", 302)
  157. return
  158. }
  159. }
  160. func AdminNewPost(w http.ResponseWriter, r *http.Request) {
  161. var (
  162. session *sessions.Session
  163. v = make(map[string]interface{})
  164. flashes []interface{}
  165. title, subject, intro, body string
  166. bodyPath string
  167. mainFilePath string = ""
  168. fileUpload []*multipart.FileHeader
  169. //otherImgs string
  170. e error
  171. )
  172. if !CheckAuth(w, r) {
  173. http.Redirect(w, r, "/admin/login", 302)
  174. return
  175. }
  176. session, e = Variables.CookieStore.Get(r, Variables.CookieName)
  177. if e != nil {
  178. log.Println("Could not get session cookie")
  179. http.Error(w, "Error", http.StatusInternalServerError)
  180. return
  181. }
  182. switch r.Method {
  183. case http.MethodGet:
  184. flashes = session.Flashes()
  185. e = session.Save(r, w)
  186. if e != nil {
  187. log.Println(e.Error())
  188. return
  189. }
  190. if len(flashes) > 0 {
  191. v["FlashMsg"] = flashes[0].(string)
  192. }
  193. ServeTemplate(w, r, "html/admin/admin-new-post.gohtml", v)
  194. return
  195. case http.MethodPost:
  196. title = r.FormValue("title")
  197. subject = r.FormValue("subject")
  198. intro = r.FormValue("intro")
  199. body = r.FormValue("body")
  200. bodyPath, e = Helper.WriteBody(title, body)
  201. if e != nil {
  202. log.Fatal(e)
  203. }
  204. r.ParseMultipartForm(32 << 20) // 32MB is the default used by FormFile
  205. fileUpload = r.MultipartForm.File["img"]
  206. Helper.UploadFiles(fileUpload)
  207. if len(fileUpload) == 1 {
  208. mainFilePath = fileUpload[0].Filename
  209. }
  210. fileUpload = r.MultipartForm.File["files"]
  211. Helper.UploadFiles(fileUpload)
  212. Database.CreatePost(
  213. Database.Post{
  214. Title: title,
  215. Subject: subject,
  216. Intro: intro,
  217. HtmlPath: bodyPath,
  218. MainImage: mainFilePath,
  219. },
  220. )
  221. http.Redirect(w, r, "/admin", 302)
  222. return
  223. }
  224. }
  225. func AdminEditPost(w http.ResponseWriter, r *http.Request) {
  226. var (
  227. session *sessions.Session
  228. v = make(map[string]interface{})
  229. urlParams map[string]string
  230. flashes []interface{}
  231. title, subject, intro, body string
  232. bodyPath string
  233. post Database.Post
  234. fileUpload []*multipart.FileHeader
  235. e error
  236. )
  237. if !CheckAuth(w, r) {
  238. http.Redirect(w, r, "/admin/login", 302)
  239. return
  240. }
  241. session, e = Variables.CookieStore.Get(r, Variables.CookieName)
  242. if e != nil {
  243. log.Println("Could not get session cookie")
  244. http.Error(w, "Error", http.StatusInternalServerError)
  245. return
  246. }
  247. switch r.Method {
  248. case http.MethodGet:
  249. flashes = session.Flashes()
  250. e = session.Save(r, w)
  251. if e != nil {
  252. log.Println(e.Error())
  253. return
  254. }
  255. if len(flashes) > 0 {
  256. v["FlashMsg"] = flashes[0].(string)
  257. }
  258. urlParams = mux.Vars(r)
  259. post, e = Database.GetPostById(urlParams["id"])
  260. if e != nil {
  261. log.Fatal("Cannot get Post by id")
  262. }
  263. post.Body, e = Helper.GetFileContents(post.HtmlPath)
  264. if e != nil {
  265. log.Fatal("Cannot read body file")
  266. }
  267. v["Post"] = post
  268. ServeTemplate(w, r, "html/admin/admin-update-post.gohtml", v)
  269. return
  270. case http.MethodPost:
  271. urlParams = mux.Vars(r)
  272. post, e = Database.GetPostById(urlParams["id"])
  273. if e != nil {
  274. log.Fatal("Cannot get Post by id")
  275. }
  276. title = r.FormValue("title")
  277. subject = r.FormValue("subject")
  278. intro = r.FormValue("intro")
  279. body = r.FormValue("body")
  280. if title != post.Title {
  281. defer Helper.DeleteOldPostFile(post.Title)
  282. }
  283. bodyPath, e = Helper.WriteBody(title, body)
  284. if e != nil {
  285. log.Fatal(e)
  286. }
  287. r.ParseMultipartForm(32 << 20) // 32MB is the default used by FormFile
  288. fileUpload = r.MultipartForm.File["img"]
  289. Helper.UploadFiles(fileUpload)
  290. if len(fileUpload) == 1 {
  291. post.MainImage = fileUpload[0].Filename
  292. }
  293. fileUpload = r.MultipartForm.File["files"]
  294. Helper.UploadFiles(fileUpload)
  295. post.Title = title
  296. post.Subject = subject
  297. post.Intro = intro
  298. post.HtmlPath = bodyPath
  299. Database.UpdatePost(
  300. post,
  301. )
  302. http.Redirect(w, r, fmt.Sprintf("/admin/post/%s/edit", post.ID), 302)
  303. return
  304. }
  305. }