add user confirmation by admins

This commit is contained in:
Lera Elvoé 2025-05-18 06:55:21 +03:00
parent ac51e5c0e8
commit 9c327957d9
Signed by: yagich
SSH Key Fingerprint: SHA256:6xjGb6uA7lAVcULa7byPEN//rQ0wPoG+UzYVMfZnbvc
4 changed files with 78 additions and 6 deletions

View File

@ -10,6 +10,15 @@ local models = require("models")
local Users = models.Users
local Sessions = models.Sessions
local TransientUser = {
is_admin = function (self)
return false
end,
is_guest = function (self)
return true
end
}
local function authenticate_user(user, password)
return bcrypt.verify(password, user.password_hash)
end
@ -30,6 +39,10 @@ local function create_session(user_id)
end
local function validate_session(session_key)
if session_key == nil then
return nil
end
local session = db.select('* FROM "sessions" WHERE "key" = ? AND "expires_at" > "?" LIMIT 1', session_key, os.time())
print(#session)
if #session > 0 then
@ -69,15 +82,22 @@ app:get("user", "/:username", function(self)
return {status = 404}
end
if self.session.flash.just_logged_in then
if self.session.flash ~= nil and self.session.flash.just_logged_in then
self.just_logged_in = true
self.session.flash = {}
end
local me = validate_session(self.session.session_key)
if not me and user.permission == constants.PermissionLevel.GUEST then
return {status = 404}
end
local me = validate_session(self.session.session_key) or TransientUser
self.user = user
self.me = me
self.user_is_me = me.id == user.id
if user.permission == constants.PermissionLevel.GUEST then
if not (self.user_is_me or me:is_admin()) then
return {status = 404}
end
end
return {render = "user.user"}
end)
@ -178,4 +198,35 @@ app:post("user_signup", "/signup", function(self)
return {redirect_to = self:url_for("user", {username = username})}
end)
app:post("user_logout", "/logout", function (self)
local user = validate_session(self.session.session_key)
if not user then
return {redirect_to = self:url_for("user_login")}
end
local session = Sessions:find({key = self.session.session_key})
session:delete()
return {redirect_to = self:url_for("user_login")}
end)
app:post("confirm_user", "/confirm_user/:user_id", function (self)
local user = validate_session(self.session.session_key)
if not user then
return {status = 403}
end
if not user:is_admin() then
return {status = 403}
end
local target_user = Users:find(self.params.user_id)
if not target_user then
return {status = 404}
end
if target_user.permission > constants.PermissionLevel.GUEST then
return {status = 404}
end
target_user:update({permission = constants.PermissionLevel.USER, confirmed_on = os.time()})
return {redirect_to = self:url_for("user", {username = target_user.username})}
end)
return app

View File

@ -14,5 +14,9 @@ return {
db.query("CREATE INDEX sessions_user_id ON sessions(user_id)")
db.query("CREATE INDEX session_keys ON sessions(key)")
end,
[2] = function ()
schema.add_column("users", "confirmed_on", types.integer{null = true})
end
}

View File

@ -8,6 +8,10 @@ function Users_mt:is_guest()
return self.permission == constants.PermissionLevel.GUEST
end
function Users_mt:is_admin()
return self.permission == constants.PermissionLevel.ADMIN
end
local ret = {
Users = Users,
Topics = Model:extend("topics"),

View File

@ -2,6 +2,19 @@
<h1>Logged in successfully.</h1>
<% end %>
<h1><%= user.username %></h1>
<% if user:is_guest() then %>
<% if user:is_guest() and user_is_me then %>
<h2>You are a guest. An administrator needs to approve your account before you will be able to post.</h2>
<% end %>
<% if user_is_me then %>
<form method="post" action="<%= url_for("user_logout", {user_id = me.id}) %>">
<input type="submit" value="Log out">
</form>
<% end %>
<% if me:is_admin() and user:is_guest() then %>
<p>This user is a guest. They signed up on <%= os.date("%c", user.created_at) %>.</p>
<form method="post" action="<%= url_for("confirm_user", {user_id = user.id}) %>">
<input type="submit" value="Confirm user">
</form>
<% elseif me:is_admin() then %>
<p>This user signed up on <%= os.date("%c", user.created_at) %> and was confirmed on <%= os.date("%c", user.confirmed_on) %>.</p>
<% end %>