2023-08-05 12:48:49 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
db: add invited_by to User and hard-code states
diff --git a/data.lua b/data.lua index cfaa737..77a8faa 100644 --- a/data.lua +++ b/data.lua @@ -14,7 +14,8 @@ CREATE TABLE IF NOT EXISTS User ( nick TEXT NOT NULL UNIQUE, name TEXT NOT NULL, salt TEXT, - hash TEXT + hash TEXT, + invited_by INTEGER REFERENCES User(id) ); CREATE TABLE IF NOT EXISTS Invite ( uuid TEXT PRIMARY KEY, @@ -36,15 +37,11 @@ CREATE TABLE IF NOT EXISTS Membership ( user_id INTEGER REFERENCES User(id), PRIMARY KEY(proj_id, user_id) ); -CREATE TABLE IF NOT EXISTS State ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL UNIQUE -); CREATE TABLE IF NOT EXISTS Ticket ( id INTEGER PRIMARY KEY AUTOINCREMENT, proj_id INTEGER NOT NULL REFERENCES Project(id), user_id INTEGER NOT NULL REFERENCES User(id), - state_id INTEGER NOT NULL REFERENCES State(id), + state_id INTEGER NOT NULL, time INTEGER NOT NULL, code INTEGER NOT NULL, title TEXT NOT NULL, @@ -60,8 +57,8 @@ CREATE TABLE IF NOT EXISTS Block ( CREATE TABLE IF NOT EXISTS Shift ( id INTEGER PRIMARY KEY AUTOINCREMENT, ticket_id INTEGER NOT NULL REFERENCES Ticket(id), - old_stt_id INTEGER NOT NULL REFERENCES State(id), - new_stt_id INTEGER NOT NULL REFERENCES State(id), + old_stt_id INTEGER NOT NULL, + new_stt_id INTEGER NOT NULL, user_id INTEGER NOT NULL REFERENCES User(id), time INTEGER NOT NULL ); @@ -81,33 +78,22 @@ function Model:create_tables() self.db:execute_many(schema) end -function Model:create_states() - self.db:execute[[ - INSERT INTO State(name) VALUES - ("backlog"), ("design"), ("progress"), ("review"), ("done"); - ]] -end - -function Model:get_states() - return self.db:execute("SELECT * FROM State;") -end - -function Model:get_indexed_states() - local query = "SELECT id, name FROM State;" - local states = {} - for _, state in ipairs(self.db:execute(query)) do - states[state.id] = state.name - end - return states -end - -function Model:create_user(nick, name, password) +function Model:create_user(nick, name, password, uuid) + self:expire_invites() + local inv = self.db:execute("SELECT * FROM Invite WHERE uuid = ?;", uuid)[1] + if inv == nil then return false end local salt = auth.get_salt() local hash = auth.hash_pass(password, salt) salt = auth.b64_enc(salt) hash = auth.b64_enc(hash) - local query = "INSERT INTO User(nick, name, salt, hash) VALUES (?, ?, ?, ?);" - self.db:execute(query, nick, name, salt, hash) + local query = "INSERT INTO User(nick, name, salt, hash, invited_by) VALUES (?, ?, ?, ?, ?);" + self.db:execute(query, nick, name, salt, hash, inv.user_id) + self.db:execute("DELETE FROM Invite WHERE uuid = ?;", uuid) + return true +end + +function Model:get_user_count() + return self.db:execute("SELECT COUNT(*) as count FROM User;")[1].count end function Model:get_user(nick) @@ -139,15 +125,6 @@ function Model:expire_invites() self.db:execute("DELETE FROM Invite WHERE expire < unixepoch();") end -function Model:use_invite(uuid) - self:expire_invites() - local inv = self.db:execute("SELECT * FROM Invite WHERE uuid = ?;", uuid)[1] - if inv ~= nil then - self.db:execute("DELETE FROM Invite WHERE uuid = ?;", uuid) - end - return inv ~= nil -end - function Model:del_invite(user_id, uuid) self.db:execute("DELETE FROM Invite WHERE user_id = ? AND uuid = ?;", user_id, uuid) end @@ -224,7 +201,6 @@ function Model:get_ticket(proj_id, code) end function Model:get_tickets(proj_id, state_id) - -- TODO: limit "done" tickets by age local query = "SELECT * FROM Ticket WHERE proj_id = ? AND state_id = ?;" return self.db:execute(query, proj_id, state_id) end @@ -292,6 +268,7 @@ end local function open(path) local self = setmetatable({path=path}, Model) self.db = lud.sqlite.open(path) + self.states = {"backlog", "design", "progress", "review", "done"} return self end diff --git a/skopos.lua b/skopos.lua index a2893c7..343f33f 100644 --- a/skopos.lua +++ b/skopos.lua @@ -10,12 +10,13 @@ App.__index = App function App:init() self.model:create_tables() - if #self.model:get_states() == 0 then - self.model:create_states() + local user_count = self.model:get_user_count() + if user_count == 0 then local uuid = self.model:create_invite() self:log(LOG_INFO, "root invite: "..uuid) else self.model:expire_invites() + self:log(LOG_INFO, "user count: "..user_count) end end @@ -70,11 +71,10 @@ function App:routes() if self.model:get_user(nick) ~= nil then -- user already exists return fail_path, 303 end - if not self.model:use_invite(uuid) then -- invalid/expired invite + if not self.model:create_user(nick, name, pass, uuid) then self:log(LOG_WARN, "attempt to use invalid invite: "..uuid) return fail_path, 303 end - self.model:create_user(nick, name, pass) self:log(LOG_INFO, "new user joined: "..nick) return "/login", 303 end}, @@ -222,12 +222,11 @@ function App:routes() local tick = self.model:get_ticket(proj.id, tonumber(code)) if tick == nil then return "not found", 404 end local users = self.model:get_indexed_users() - local states = self.model:get_indexed_states() -- TODO: load comments local comments = {} local env = { title=self.title, user=user, proj=proj, tick=tick, - users=users, states=states, comments=comments + users=users, states=self.model.states, comments=comments } return lud.template.render_file("view/ticket.html", env) end},