diff --git a/apps/users.lua b/apps/users.lua index 3b9a72d..fde4af7 100644 --- a/apps/users.lua +++ b/apps/users.lua @@ -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 \ No newline at end of file diff --git a/migrations.lua b/migrations.lua index 010f861..29fd504 100644 --- a/migrations.lua +++ b/migrations.lua @@ -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 } diff --git a/models.lua b/models.lua index b36f72e..21b7927 100644 --- a/models.lua +++ b/models.lua @@ -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"), diff --git a/views/user/user.etlua b/views/user/user.etlua index 80ccc34..3aa315e 100644 --- a/views/user/user.etlua +++ b/views/user/user.etlua @@ -2,6 +2,19 @@

Logged in successfully.

<% end %>

<%= user.username %>

-<% if user:is_guest() then %> +<% if user:is_guest() and user_is_me then %>

You are a guest. An administrator needs to approve your account before you will be able to post.

<% end %> +<% if user_is_me then %> +
"> + +
+<% end %> +<% if me:is_admin() and user:is_guest() then %> +

This user is a guest. They signed up on <%= os.date("%c", user.created_at) %>.

+
"> + +
+<% elseif me:is_admin() then %> +

This user signed up on <%= os.date("%c", user.created_at) %> and was confirmed on <%= os.date("%c", user.confirmed_on) %>.

+<% end %>