A website for producing interactive charts without writing a single line of code. Built with Common Lisp and Python. https://charts.craigoates.net
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.
 
 
 
 

111 lines
4.3 KiB

(defpackage #:user-management
(:use #:cl
#:user
#:mito
#:local-time)
(:import-from #:hot-line.db
#:connection-settings
#:db
#:with-connection)
(:export #:add-user-to-db
#:user-in-db-p
#:validate-user
#:get-all-users
#:get-crud-redirect-url
#:update-user-display-name
#:update-user-password
#:delete-user-from-db
#:get-total-user-count
#:update-user-administration-role))
(in-package #:user-management)
(defun user-in-db-p (&key (id nil) username)
"Looks for the user with either the specified `ID' or `USERNAME'.
Make sure you specify which argument you want to use with either :id or
:username. The `USER' information will be returned if found. `NIL' will be
returned if no entry with either the specified `ID' or `USERNAME' is found."
(if (not id)
(with-connection (db)
(mito:find-dao 'user:user :username username))
(with-connection (db)
(mito:find-dao 'user:user :id id))))
(defun add-user-to-db (username display-name administrator password)
"Add a new user to the database.
Make sure you have validated the data before calling this function."
(with-connection (db)
(mito:create-dao 'user
:username username
:display-name display-name
:administrator administrator
:password password
;; :created_at (local-time:now)
;; :updated_at (local-time:now)
)))
(defun get-all-users ()
"Returns a list of all registered users in the database."
(with-connection (db)
(mito:select-dao 'user:user
(sxql:order-by (:asc :display-name)))))
(defun update-user-display-name (username display-name)
"Updates the specified user's display name.
`USERNAME' is used to specify which user to update in the
database. `DISPLAY-NAME' is used to replace the old one. The old 'display-name'
is not needed here as no validation check is done. This function simply
overwrites the old 'display-name' with the new `DISPLAY-NAME'."
(with-connection (db)
(mito:execute-sql
(format nil "UPDATE user SET display_name = ~S WHERE username = ~S;"
display-name username))))
(defun update-user-administration-role (username is-administrator)
"Adds or removes the specified user's administrator privileges.
You can specify the user via `USERNAME'. At the time of writing, the
website uses SQLite as it database so the `IS-ADMINISTRATOR' value is
determined via a '0' or '1'. You should use the 'APP-CONSTANTS'
package (E.G. 'app-constants:+true+') to specify (or help convert)
when specifying this 'make-shift' Boolean value."
(with-connection (db)
(mito:execute-sql
(format nil "UPDATE user SET administrator = ~D WHERE username = ~S;"
is-administrator username))))
(defun update-user-password (username new-password)
"Updates the password of the specified user.
Use `USERNAME' to specify which user your want from the database. `NEW-PASSWORD'
will overwrite the old password. Make sure you have validated the user and they
have entered the old password as a validation check before you call this
function."
(with-connection (db)
(let ((user-to-update
(mito:find-dao 'user:user :username username)))
(setf (user::password-of user-to-update) new-password)
(mito:save-dao user-to-update))))
(defun delete-user-from-db (&key (id nil) username)
"Deletes the user from the database with the specified `ID' or `USERNAME'.
Make sure your specify which argument you want to user when calling the function
with either :id or :username."
(if (not id)
(with-connection (db)
(mito:delete-by-values 'user:user :username username))
(with-connection (db)
(mito:delete-by-values 'user:user :id id))))
(defun get-crud-redirect-url ()
"Returns the URL the user is redirected to after a CRUD-based HTTP POST.
The `USERNAME' is the username of the currently logged in user. The URL is
formed based on the type of roles the user has asigned to him/her. If the user
is an administrator, the URL returns 'user/index.html' and 'user/dashboard.html'
otherwise."
(let ((user (authentication:get-current-user)))
(if (= (user::is-administrator-p user) app-constants:+true+)
"user/index.html" ; Admin.
"user/dashboard.html"))) ; Regular User
(defun get-total-user-count ()
"Returns the total number of registered users in the database."
(with-connection (db)
(mito:count-dao 'user:user)))