Browse Source

update web.lisp, mostly around site settings and first-run set-up.

stable
Craig Oates 2 years ago
parent
commit
bb5f8fb482
  1. 299
      src/web.lisp

299
src/web.lisp

@ -13,6 +13,7 @@
#:hermetic
#:auth
#:utils
#:validation
#:user
#:nera-db)
(:export #:*web*))
@ -32,14 +33,17 @@
;; Routing rules
(defroute "/" ()
(render #P"index.html"
(append (if (hermetic:logged-in-p)
(auth:auth-user-data))
`(:alert ,(utils:get-and-reset-alert)
:content ,(storage:open-text-file
"" "pages"
(site-settings::home-page-of
(nera:get-site-settings)))))))
(if (not (uiop:file-exists-p (ritherdon-archive.config:database-name)))
(redirect "/setup")
(render #P"index.html"
(append (if (hermetic:logged-in-p)
(auth:auth-user-data))
`(:alert ,(utils:get-and-reset-alert)
:nav-menu ,(nera:nav-menu-slugs)
:content ,(storage:open-text-file
"" "pages"
(site-settings::home-page-of
(nera:get-site-settings))))))))
(defroute "/setup" ()
;; If there is no database, there is no user, hence no more checks.
@ -57,6 +61,7 @@
`(,+service-unavailable+ (:location "/")))
(t (nera-db:init-db
(lack.request:request-body-parameters ningle:*request*))
(storage:init-storage)
;; Redirect to /setup-complete?
(utils:set-alert "All set-up. Log-in to continue.")
(redirect "/login")))))
@ -67,16 +72,16 @@
(utils:set-alert "This feature has been disabled.")
(redirect "/"))
(hermetic:auth (:logged-in)
;; Hermetic Authorised (Logged in users can't sign-up).
(progn
(utils:set-alert
"You need to be signed out to create a new account.")
(redirect "/dashboard"))
;; Hermetic Not Authorised
(let ((alert (utils:get-and-reset-alert)))
(render "sign-up.html"
`(:token ,(auth:csrf-token)
:alert ,alert))))))
;; Hermetic Authorised (Logged in users can't sign-up).
(progn
(utils:set-alert
"You need to be signed out to create a new account.")
(redirect "/dashboard"))
;; Hermetic Not Authorised
(let ((alert (utils:get-and-reset-alert)))
(render "sign-up.html"
`(:token ,(auth:csrf-token)
:alert ,alert))))))
(defroute ("/sign-up" :method :POST) ()
(destructuring-bind
@ -108,7 +113,6 @@
(utils:set-alert "Account created.")
(redirect "/login")))))))
(defroute ("/login" :method :GET) ()
(hermetic:auth (:logged-in)
;; Authorised
@ -136,7 +140,7 @@
(gethash :id ningle:*session*) (nera:get-user-id username)
;; Set the users password (for session)
(gethash :password ningle:*session*) password)
(redirect "/dashboard"))
(redirect "/dashboard"))
;; Failed log-in attempt.
(progn (utils:set-alert "Incorrect details provided.")
(redirect "/login"))
@ -172,39 +176,59 @@
(redirect "/login"))))
(defroute ("/site-settings" :method :GET) ()
(hermetic:auth (:administrator)
;; Authorised
(render #P"user/site-settings.html"
(append (auth:auth-user-data)
`(:alert ,(utils:get-and-reset-alert)
:pages ,(storage:get-file-names
(storage:get-files-in-directory
"" "pages"))
:settings ,(nera:get-site-settings))))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))
(defroute ("/site-settings/sign-up" :method :POST) ()
(hermetic:auth
(:administrator)
;; Authorised
(render #P"user/site-settings.html"
(append (auth:auth-user-data)
`(:alert ,(utils:get-and-reset-alert)
:pages ,(nera:get-all-pages)
:site-wide-snippet ,(storage:open-text-file-with-raw-path
"static/site-wide-snippet")
:settings ,(nera:get-site-settings))))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))
(defroute ("/site-settings/update-sign-up" :method :POST) ()
(destructuring-bind
(&key enable-sign-up authenticity-token &allow-other-keys)
(utils:request-params
(lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth (:administrator)
;; Authorised
(progn
(nera:update-enable-sign-on-settings enable-sign-up)
(utils:set-alert "Enable Sign-Up setting saved.")
(redirect "/site-settings"))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/update-nav-menu" :method :POST) (&key _parsed)
(destructuring-bind
(&key authenticity-token &allow-other-keys)
(utils:request-params
(lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth (:administrator)
;; Authorised
(progn
(nera:update-enable-sign-on-settings enable-sign-up)
(utils:set-alert "Enable Sign-Up setting saved.")
(format t "~a" (cdr (assoc "page" _parsed :test #'string=)))
(nera:update-nav-menu _parsed)
(utils:set-alert "Nav. menu updated.")
(redirect "/site-settings"))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/home-page" :method :POST) ()
(defroute ("/site-settings/update-home-page" :method :POST) ()
(destructuring-bind
(&key set-home-page authenticity-token &allow-other-keys)
(utils:request-params
@ -226,6 +250,122 @@
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/update-site-name" :method :POST) ()
(destructuring-bind
(&key site-name authenticity-token &allow-other-keys)
(utils:request-params
(lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth (:administrator)
;; Authorised
(cond ((utils:string-is-nil-or-empty? site-name)
(utils:set-alert "No value provided. Site name not changed.")
(redirect "/site-settings"))
(t
(nera:update-site-name site-name)
(utils:set-alert "Site name updated.")
(redirect "/site-settings")))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/update-code-snippet" :method :POST) ()
(destructuring-bind
(&key code-snippet authenticity-token &allow-other-keys)
(utils:request-params
(lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth (:administrator)
;; Authorised
(progn
(storage:store-text-with-raw-path
"static/site-wide-snippet" code-snippet)
(utils:set-alert "Site-Wide snippet updated.")
(redirect "/site-settings"))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/update-favicon" :method :POST) ()
(destructuring-bind
(&key favicon-file authenticity-token &allow-other-keys)
(utils:request-params (lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth
(:administrator)
;; Authorised
(cond ((utils:string-is-nil-or-empty? (cadr favicon-file))
(utils:set-alert "No file provided. Favicon not uploaded.")
(redirect "/site-settings"))
(t (storage:store-with-raw-path
"static/images/favicon.png" favicon-file)
(utils:set-alert "Favicon saved.")
(utils:run-bash-command
(format nil "convert ~a -resize 192x192\\> ~a"
(merge-pathnames
#P"static/images/favicon.png"
ritherdon-archive.config:*application-root*)
(merge-pathnames
#P"static/images/favicon.png"
ritherdon-archive.config:*application-root*)))
(redirect "/site-settings")))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/update-enable-site-logo" :method :POST) ()
(destructuring-bind
(&key enable-site-logo authenticity-token &allow-other-keys)
(utils:request-params
(lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth (:administrator)
;; Authorised
(progn
(nera:update-enable-site-logo-setting enable-site-logo)
(utils:set-alert "Enable Site Logo setting saved.")
(redirect "/site-settings"))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/site-settings/update-site-logo" :method :POST) ()
(destructuring-bind
(&key site-logo authenticity-token &allow-other-keys)
(utils:request-params (lack.request:request-body-parameters ningle:*request*))
(if (not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied"))
(hermetic:auth
(:administrator)
;; Authorised
(cond ((utils:string-is-nil-or-empty? (cadr site-logo))
(utils:set-alert "No file provided. Site logo not uploaded.")
(redirect "/site-settings"))
(t (storage:store-with-raw-path
"static/images/site-logo.png" site-logo)
(utils:set-alert "Site logo saved.")
(utils:run-bash-command
(format nil "convert ~a -resize 500x500\\> ~a"
(merge-pathnames
#P"static/images/site-logo.png"
ritherdon-archive.config:*application-root*)
(merge-pathnames
#P"static/images/site-logo.png"
ritherdon-archive.config:*application-root*)))
(redirect "/site-settings")))
;; Not Authorised
(progn
(utils:set-alert "You are not authorised to view this page.")
(redirect "/login"))))))
(defroute ("/users" :method :GET) ()
(hermetic:auth (:administrator)
;; Authorised
@ -423,6 +563,7 @@
"pages"
(utils:slugify title)
page-content)
(nera:create-page title (utils:slugify title) +false+ +false+)
(utils:set-alert "Page created.")
(redirect "/dashboard")))
;; Not Authorised
@ -454,6 +595,26 @@
(storage:get-files-in-directory
"" "pages")))))))
(defroute ("/view/pages" :method :GET) ()
(let ((alert (utils:get-and-reset-alert)))
(render #P"pages.html"
(append (if (hermetic:logged-in-p)
(auth:auth-user-data))
`(:alert ,alert
:pages ,(storage:get-file-names
(storage:get-files-in-directory
"" "pages")))))))
(defroute ("/view/archive" :method :GET) ()
(let ((alert (utils:get-and-reset-alert)))
(render #P"pages.html"
(append (if (hermetic:logged-in-p)
(auth:auth-user-data))
`(:alert ,alert
:pages ,(storage:get-file-names
(storage:get-files-in-directory
"" "pages")))))))
(defroute ("/view/page/:slug" :method :GET) (&key slug)
(let ((alert (utils:get-and-reset-alert)))
(if (storage:file-exists-p "" "pages" slug)
@ -461,6 +622,7 @@
(append (if (hermetic:logged-in-p)
(auth:auth-user-data))
`(:alert ,alert
:db-data ,(nera:get-page slug)
:data ,(storage:open-text-file
"" "pages" slug))))
(on-exception *web* 404))))
@ -472,7 +634,7 @@
(render "/user/edit-page.html"
(append (auth:auth-user-data)
`(:alert ,alert
:title ,slug
:db-data ,(nera:get-page slug)
:data ,(storage:open-text-file
"" "pages" slug)))))
;; Not Authorised
@ -482,7 +644,7 @@
(defroute ("/edit/page" :method :POST) ()
(destructuring-bind
(&key title page-content authenticity-token &allow-other-keys)
(&key slug page-content authenticity-token &allow-other-keys)
(utils:request-params (lack.request:request-body-parameters ningle:*request*))
(format t "~a" page-content)
(cond ((not (string= authenticity-token (auth:csrf-token)))
@ -490,15 +652,13 @@
(t (hermetic:auth
(:logged-in)
;; Authorised
(cond ((utils:string-is-nil-or-empty? title)
(utils:set-alert "Cannot find file. Unable to save page.")
(cond ((utils:string-is-nil-or-empty? slug)
(utils:set-alert "Page cannot be found.")
(redirect "/user/pages"))
(t (storage:store-text
"" ; `USERNAME' blank because it's not used/needed.
"pages"
(utils:slugify title)
page-content)
"pages" slug page-content)
(utils:set-alert "Page updated.")
(redirect "/user/pages")))
;; Not Authorised
@ -507,24 +667,29 @@
(defroute ("/rename/page" :method :POST) ()
(destructuring-bind
(&key title new-title authenticity-token &allow-other-keys)
(&key id slug new-title authenticity-token &allow-other-keys)
(utils:request-params (lack.request:request-body-parameters ningle:*request*))
(cond ((not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied")))
(t (hermetic:auth
(:logged-in)
;; Authorised
(cond ((utils:string-is-nil-or-empty? title)
(cond ((utils:string-is-nil-or-empty? slug)
(utils:set-alert "Cannot find file. Unable to save changes.")
(redirect "/user/pages"))
((utils:string-is-nil-or-empty? new-title)
(utils:set-alert "No title provided. Unable to save changes.")
(redirect (format nil "/edit/page/~a" title)))
(redirect (format nil "/edit/page/~a" slug)))
((utils:string-is-nil-or-empty? id)
(utils:set-alert "No Id. found. Cannot find page in database.")
(redirect "/user/pages"))
(t (storage:rename-content-file
"" ; `USERNAME' blank because it's not used/needed.
"pages" title (utils:slugify new-title))
"pages" slug (utils:slugify new-title))
(nera:update-page id new-title (utils:slugify new-title))
(utils:set-alert "File name changed.")
(redirect (format nil "/edit/page/~a"
(utils:slugify new-title)))))
@ -532,26 +697,52 @@
(progn (utils:set-alert "You are not logged in.")
(redirect "/login")))))))
(defroute ("/page/set-nav-menu" :method :POST) ()
(destructuring-bind
(&key slug show-in-nav authenticity-token &allow-other-keys)
(utils:request-params (lack.request:request-body-parameters ningle:*request*))
(cond ((not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied")))
(t (hermetic:auth
(:logged-in)
;; Authorised
(cond ((utils:string-is-nil-or-empty? slug)
(utils:set-alert "Cannot find page in database.")
(redirect "/user/pages"))
(t (nera:update-nav-menu
slug (if (null show-in-nav) +false+ +true+))
(utils:set-alert "Updated name changed.")
(redirect (format nil "/edit/page/~a" slug))))
;; Not Authorised
(progn (utils:set-alert "You are not logged in.")
(redirect "/login")))))))
(defroute ("/page/delete" :method :POST) ()
(destructuring-bind
(&key title authenticity-token &allow-other-keys)
(&key slug authenticity-token &allow-other-keys)
(utils:request-params (lack.request:request-body-parameters ningle:*request*))
(cond ((not (string= authenticity-token (auth:csrf-token)))
`(,+forbidden+ (:content-type "text/plain") ("Denied")))
(t (hermetic:auth
(:administrator)
;; Authorised
(cond ((utils:string-is-nil-or-empty? title)
(utils:set-alert "No file name provided. Nothing deleted.")
(cond ((utils:string-is-nil-or-empty? slug)
(utils:set-alert "Cannot find page in database. Nothing deleted.")
(redirect "/user/pages"))
((null (storage:file-exists-p "" "pages" title))
((null (storage:file-exists-p "" "pages" slug))
(utils:set-alert "Unable to find page. Nothing deleted.")
(redirect "/user/pages"))
((eql (pages::can-delete-p (nera:get-page slug)) +false+)
(utils:set-alert "File not allowed to be deleted.")
(redirect "/user/pages"))
(t (storage:remove-file
"" ; `USERNAME' blank because it's not used/needed.
"pages" title)
"pages" slug)
(nera:delete-page :slug slug)
(utils:set-alert "Page deleted.")
(redirect "/user/pages")))
;; Not Authorised

Loading…
Cancel
Save