login

<     >

2022-03-03 10:09:18 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

make app modular

diff --git a/app.lua b/app.lua
deleted file mode 100644
index 4ef6f96..0000000
--- a/app.lua
+++ /dev/null
@@ -1,241 +0,0 @@
-local git = require "git"
-local scan = require "scan"
-local hash = require "hash"
-
-local lud = require "ludweb"
-
-local function time_fmt(sig)
-    local s = os.date("%Y-%m-%d %H:%M:%S", sig.time_)
-    local offset = sig.offset
-    local sign
-    if offset < 0 then
-        offset = -offset
-        sign = "-"
-    else
-        sign = "+"
-    end
-    local hours = math.floor(offset / 60)
-    local mins = offset % 60
-    s = s .. (" (UTC%s%02d:%02d)"):format(sign, hours, mins)
-    return s
-end
-
-local function diff_cb(line_type, line)
-    line = lud.template.escape(line:sub(1, #line-1))
-    if line_type == " " then
-        line = ' <span class="diff_ctx">' .. line .. '</span>'
-    elseif line_type == "+" then
-        line = '+<span class="diff_add">' .. line .. '</span>'
-    elseif line_type == "-" then
-        line = '-<span class="diff_del">' .. line .. '</span>'
-    elseif line_type == "=" then
-        line = ' <span class="diff_nonl diff_ctx_nonl">' .. line .. '</span>'
-    elseif line_type == ">" then
-        line = ' <span class="diff_nonl diff_old_nonl">' .. line .. '</span>'
-    elseif line_type == "<" then
-        line = ' <span class="diff_nonl diff_new_nonl">' .. line .. '</span>'
-    elseif line_type == "F" then
-        line = '\n<span class="diff_file_hdr">' .. line .. '</span>'
-    elseif line_type == "H" then
-        line = '<span class="diff_hunk_hdr">' .. line .. '</span>'
-    elseif line_type == "B" then
-        line = '<span class="diff_bin">' .. line .. '</span>'
-    else
-        line = line_type .. line
-    end
-    return line .. "\n"
-end
-
-local function allowed(user, gname)
-    if gname == "public" then
-        return true
-    elseif user == nil then
-        return false
-    end
-    for _, ok in ipairs(user.groups) do
-        if gname == ok then
-            return true
-        end
-    end
-    return false
-end
-
-local LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG = 0, 1, 2, 3
-
-local path = arg[1]
-local conf = dofile(path.."/conf.lua")
-local title = conf.title
-
-git.init()
-local groups = scan.scanrepos(path)
-
-local sessions = {}
-
-local function get_user(cookies)
-    local session_id = cookies["sid"]
-    if session_id == nil then
-        return nil
-    end
-    local uname = sessions[session_id]
-    if uname == nil then
-        return nil
-    end
-    return conf.users[uname]
-end
-
-local routes = {
-    {"GET", "/?",
-    function (req)
-        local user = get_user(req.cookies)
-        local gnames = {}
-        groups = scan.scanrepos(path)
-        for gname in pairs(groups) do
-            if allowed(user, gname) then
-                table.insert(gnames, gname)
-            end
-        end
-        local env = {title=title, user=user, gnames=gnames}
-        return lud.template.render_file("view/home.html", env)
-    end},
-    {"GET", "/login",
-    function (req)
-        local user = get_user(req.cookies)
-        if user ~= nil then  -- already logged in
-            return "/", 303
-        else
-            return lud.template.render_file("view/login.html", {title=title})
-        end
-    end},
-    {"POST", "/login",
-    function (req)
-        local uname = req.form.username
-        local pass = req.form.password
-        local user = conf.users[uname]
-        local salt, h
-        if user == nil then
-            -- hash something as if we're trying to login anyway
-            salt = hash.get_salt()
-            h = hash.hash_pass(pass, salt)
-            conf.log(LOG_INFO, "invalid username")
-        else
-            salt = lud.crypt.b64_dec(user.salt)
-            h = hash.hash_pass(pass, salt)
-            if h == lud.crypt.b64_dec(user.hash) then
-                local session_id = lud.crypt.b64_enc(lud.crypt.uuid4())
-                sessions[session_id] = uname
-                conf.log(LOG_INFO, "logged in as "..uname)
-                local age = conf.session_age
-                local cookie = {key="sid", val=session_id, path="/", age=age}
-                return "/", 303, "See Other", {cookie}
-            else
-                conf.log(LOG_INFO, "invalid password")
-            end
-        end
-        return "/login", 303
-    end},
-    {"GET", "/logout",
-    function (req)
-        local session_id = req.cookies["sid"]
-        if session_id ~= nil then
-            conf.log(LOG_INFO, "logged out as "..sessions[session_id])
-            sessions[session_id] = nil
-        end
-        return "/", 303
-    end},
-    {"GET", "/group/([%w_-]+)",
-    function (req, gname)
-        local user = get_user(req.cookies)
-        if not allowed(user, gname) then
-            return "/login", 303
-        end
-        local rnames = {}
-        for rname in pairs(groups[gname]) do
-            table.insert(rnames, rname)
-        end
-        local env = {title=title, user=user, gname=gname, rnames=rnames}
-        return lud.template.render_file("view/group.html", env)
-    end},
-    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)",
-    function (req, gname, rname)
-        local user = get_user(req.cookies)
-        if not allowed(user, gname) then
-            return "/login", 303
-        end
-        local repo = groups[gname][rname]
-        local bnames = repo:branches()
-        local tnames = repo:tags()
-        local env = {
-            title=title, user=user, repo=repo, gname=gname,
-            rname=rname, bnames=bnames, tnames=tnames,
-        }
-        return lud.template.render_file("view/repo.html", env)
-    end},
-    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/history/([%w_-]+)",
-    function (req, gname, rname, first)
-        local user = get_user(req.cookies)
-        if not allowed(user, gname) then
-            return "/login", 303
-        end
-        local repo = groups[gname][rname]
-        local commit = repo:commit(first)
-        local prev = repo:find_prev(commit:id(), conf.limit)
-        local env = {
-            title=title, user=user, gname=gname, rname=rname, bname=bname,
-            commit=commit, limit=conf.limit, prev=prev, first=first,
-        }
-        return lud.template.render_file("view/history.html", env)
-    end},
-    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/commit/([%w_-]+)",
-    function (req, gname, rname, cid)
-        local user = get_user(req.cookies)
-        if not allowed(user, gname) then
-            return "/login", 303
-        end
-        local repo = groups[gname][rname]
-        local commit = repo:commit(cid)
-        local prev = repo:find_prev(commit:id(), 1)
-        local sig = commit:signature()
-        local time_str = time_fmt(sig)
-        local diff = repo:diff(commit, diff_cb)
-        local env = {
-            title=title, user=user, gname=gname, rname=rname, bname=bname,
-            commit=commit, time_str=time_str, sig=sig, cid=cid, prev=prev, diff=diff,
-        }
-        return lud.template.render_file("view/commit.html", env)
-    end},
-    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/commit/([%w_-]+)/tree/(.*)",
-    function (req, gname, rname, cid, path)
-        local user = get_user(req.cookies)
-        if not allowed(user, gname) then
-            return "/login", 303
-        end
-        local repo = groups[gname][rname]
-        local commit = repo:commit(cid)
-        local node = commit:tree_entry(path)
-        if node == nil then
-            return "File not found", 404, "Not found"
-        end
-        local parts = {}
-        for part in path:gmatch("[^/]+") do
-            table.insert(parts, part)
-        end
-        local base = req.path
-        if base:sub(#base) ~= "/" then
-            base = base .. "/"
-        end
-        local env = {
-            title=title, user=user, gname=gname, rname=rname, cid=cid,
-            path=path, base=base, parts=parts, node=node,
-        }
-        if node.type_ == "dir" then
-            return lud.template.render_file("view/dir.html", env)
-        elseif node.type_ == "file" then
-            return lud.template.render_file("view/file.html", env)
-        end
-    end},
-}
-
-conf.log(LOG_INFO, "server running on port "..conf.port)
-lud.app.new_app(routes):run(conf.port)
-
-git.shutdown()

diff --git a/cogit.lua b/cogit.lua
new file mode 100644
index 0000000..344cd5a
--- /dev/null
+++ b/cogit.lua
@@ -0,0 +1,275 @@
+local git = require "git"
+local scan = require "scan"
+local hash = require "hash"
+
+local lud = require "ludweb"
+
+local function time_fmt(sig)
+    local s = os.date("%Y-%m-%d %H:%M:%S", sig.time_)
+    local offset = sig.offset
+    local sign
+    if offset < 0 then
+        offset = -offset
+        sign = "-"
+    else
+        sign = "+"
+    end
+    local hours = math.floor(offset / 60)
+    local mins = offset % 60
+    s = s .. (" (UTC%s%02d:%02d)"):format(sign, hours, mins)
+    return s
+end
+
+local function diff_cb(line_type, line)
+    line = lud.template.escape(line:sub(1, #line-1))
+    if line_type == " " then
+        line = ' <span class="diff_ctx">' .. line .. '</span>'
+    elseif line_type == "+" then
+        line = '+<span class="diff_add">' .. line .. '</span>'
+    elseif line_type == "-" then
+        line = '-<span class="diff_del">' .. line .. '</span>'
+    elseif line_type == "=" then
+        line = ' <span class="diff_nonl diff_ctx_nonl">' .. line .. '</span>'
+    elseif line_type == ">" then
+        line = ' <span class="diff_nonl diff_old_nonl">' .. line .. '</span>'
+    elseif line_type == "<" then
+        line = ' <span class="diff_nonl diff_new_nonl">' .. line .. '</span>'
+    elseif line_type == "F" then
+        line = '\n<span class="diff_file_hdr">' .. line .. '</span>'
+    elseif line_type == "H" then
+        line = '<span class="diff_hunk_hdr">' .. line .. '</span>'
+    elseif line_type == "B" then
+        line = '<span class="diff_bin">' .. line .. '</span>'
+    else
+        line = line_type .. line
+    end
+    return line .. "\n"
+end
+
+local function allowed(user, gname)
+    if gname == "public" then
+        return true
+    elseif user == nil then
+        return false
+    end
+    for _, ok in ipairs(user.groups) do
+        if gname == ok then
+            return true
+        end
+    end
+    return false
+end
+
+local LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG = 0, 1, 2, 3
+
+local Cogit = {}
+Cogit.__index = Cogit
+
+function Cogit:init()
+    if not self.initialized then
+        git.init()
+        self.initialized = true
+    end
+end
+
+function Cogit:finish()
+    git.shutdown()
+    self.initialized = false
+end
+
+local function get_user(cookies)
+    local session_id = cookies["sid"]
+    if session_id == nil then
+        return nil
+    end
+    local uname = sessions[session_id]
+    if uname == nil then
+        return nil
+    end
+    return conf.users[uname]
+end
+
+function Cogit:run()
+    self:init()
+    self.conf.log(LOG_INFO, "server running on port "..self.conf.port)
+    self.app:run(self.conf.port)
+end
+
+function Cogit:scan()
+    self.conf.log(LOG_INFO, "scanning repos in "..self.path)
+    self.groups = scan.scanrepos(self.path)
+end
+
+function Cogit:log(level, msg)
+    self.conf.log(level, msg)
+end
+
+function Cogit:routes()
+    title = self.title
+    conf = self.conf
+    sessions = self.sessions
+    return {
+    {"GET", "/?",
+    function (req)
+        local user = get_user(req.cookies)
+        local gnames = {}
+        self:scan()
+        for gname in pairs(self.groups) do
+            if allowed(user, gname) then
+                table.insert(gnames, gname)
+            end
+        end
+        local env = {title=title, user=user, gnames=gnames}
+        return lud.template.render_file("view/home.html", env)
+    end},
+    {"GET", "/login",
+    function (req)
+        local user = get_user(req.cookies)
+        if user ~= nil then  -- already logged in
+            return "/", 303
+        else
+            return lud.template.render_file("view/login.html", {title=title})
+        end
+    end},
+    {"POST", "/login",
+    function (req)
+        local uname = req.form.username
+        local pass = req.form.password
+        local user = conf.users[uname]
+        local salt, h
+        if user == nil then
+            -- hash something as if we're trying to login anyway
+            salt = hash.get_salt()
+            h = hash.hash_pass(pass, salt)
+            conf.log(LOG_INFO, "invalid username")
+        else
+            salt = lud.crypt.b64_dec(user.salt)
+            h = hash.hash_pass(pass, salt)
+            if h == lud.crypt.b64_dec(user.hash) then
+                local session_id = lud.crypt.b64_enc(lud.crypt.uuid4())
+                sessions[session_id] = uname
+                conf.log(LOG_INFO, "logged in as "..uname)
+                local age = conf.session_age
+                local cookie = {key="sid", val=session_id, path="/", age=age}
+                return "/", 303, "See Other", {cookie}
+            else
+                conf.log(LOG_INFO, "invalid password")
+            end
+        end
+        return "/login", 303
+    end},
+    {"GET", "/logout",
+    function (req)
+        local session_id = req.cookies["sid"]
+        if session_id ~= nil then
+            conf.log(LOG_INFO, "logged out as "..sessions[session_id])
+            sessions[session_id] = nil
+        end
+        return "/", 303
+    end},
+    {"GET", "/group/([%w_-]+)",
+    function (req, gname)
+        local user = get_user(req.cookies)
+        if not allowed(user, gname) then
+            return "/login", 303
+        end
+        local rnames = {}
+        for rname in pairs(self.groups[gname]) do
+            table.insert(rnames, rname)
+        end
+        local env = {title=title, user=user, gname=gname, rnames=rnames}
+        return lud.template.render_file("view/group.html", env)
+    end},
+    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)",
+    function (req, gname, rname)
+        local user = get_user(req.cookies)
+        if not allowed(user, gname) then
+            return "/login", 303
+        end
+        local repo = self.groups[gname][rname]
+        local bnames = repo:branches()
+        local tnames = repo:tags()
+        local env = {
+            title=title, user=user, repo=repo, gname=gname,
+            rname=rname, bnames=bnames, tnames=tnames,
+        }
+        return lud.template.render_file("view/repo.html", env)
+    end},
+    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/history/([%w_-]+)",
+    function (req, gname, rname, first)
+        local user = get_user(req.cookies)
+        if not allowed(user, gname) then
+            return "/login", 303
+        end
+        local repo = self.groups[gname][rname]
+        local commit = repo:commit(first)
+        local prev = repo:find_prev(commit:id(), conf.limit)
+        local env = {
+            title=title, user=user, gname=gname, rname=rname, bname=bname,
+            commit=commit, limit=conf.limit, prev=prev, first=first,
+        }
+        return lud.template.render_file("view/history.html", env)
+    end},
+    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/commit/([%w_-]+)",
+    function (req, gname, rname, cid)
+        local user = get_user(req.cookies)
+        if not allowed(user, gname) then
+            return "/login", 303
+        end
+        local repo = self.groups[gname][rname]
+        local commit = repo:commit(cid)
+        local prev = repo:find_prev(commit:id(), 1)
+        local sig = commit:signature()
+        local time_str = time_fmt(sig)
+        local diff = repo:diff(commit, diff_cb)
+        local env = {
+            title=title, user=user, gname=gname, rname=rname, bname=bname,
+            commit=commit, time_str=time_str, sig=sig, cid=cid, prev=prev, diff=diff,
+        }
+        return lud.template.render_file("view/commit.html", env)
+    end},
+    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)/commit/([%w_-]+)/tree/(.*)",
+    function (req, gname, rname, cid, path)
+        local user = get_user(req.cookies)
+        if not allowed(user, gname) then
+            return "/login", 303
+        end
+        local repo = self.groups[gname][rname]
+        local commit = repo:commit(cid)
+        local node = commit:tree_entry(path)
+        if node == nil then
+            return "File not found", 404, "Not found"
+        end
+        local parts = {}
+        for part in path:gmatch("[^/]+") do
+            table.insert(parts, part)
+        end
+        local base = req.path
+        if base:sub(#base) ~= "/" then
+            base = base .. "/"
+        end
+        local env = {
+            title=title, user=user, gname=gname, rname=rname, cid=cid,
+            path=path, base=base, parts=parts, node=node,
+        }
+        if node.type_ == "dir" then
+            return lud.template.render_file("view/dir.html", env)
+        elseif node.type_ == "file" then
+            return lud.template.render_file("view/file.html", env)
+        end
+    end},
+} end
+
+local function new_cogit(path)
+    local self = setmetatable({}, Cogit)
+    self.path = path
+    self.sessions = {}
+    self.initialized = false
+    self.conf = dofile(path.."/conf.lua")
+    self:init()
+    self:scan()
+    self.app = lud.app.new_app(self:routes())
+    return self
+end
+
+return {new_cogit=new_cogit}

diff --git a/main.lua b/main.lua
new file mode 100644
index 0000000..28f1316
--- /dev/null
+++ b/main.lua
@@ -0,0 +1,3 @@
+local cogit = require "cogit"
+
+cogit.new_cogit(arg[1]):run()