login

<     >

2023-07-20 15:17:54 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

simpler access control without groups

repos can be either public or private
private repos can only be viewed by admin
repo is public iif repo.desc doesn't start with "Unnamed" or ":"

diff --git a/cogit/cogit.lua b/cogit/cogit.lua
index 2dcfe6f..49ec89b 100644
--- a/cogit/cogit.lua
+++ b/cogit/cogit.lua
@@ -46,8 +46,15 @@ local function diff_cb(line_type, line)
     return line .. "\n"
 end
 
-local function allowed(is_admin, gname)
-    return gname == "public" or is_admin
+local function starts_with(str, sub)
+    return str:sub(1, #sub) == sub
+end
+
+local function allowed(is_admin, repo)
+    if is_admin then return true end
+    if starts_with(repo.desc, "Unnamed") then return false end
+    if starts_with(repo.desc, ":") then return false end
+    return true
 end
 
 local LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG = 0, 1, 2, 3
@@ -80,7 +87,7 @@ end
 
 function Cogit:scan()
     self:log(LOG_INFO, "scanning repos in "..self.path)
-    self.groups = scan.scanrepos(self.path)
+    self.repos = scan.scanrepos(self.path)
 end
 
 function Cogit:log(level, msg)
@@ -103,14 +110,18 @@ function Cogit:routes()
     {"GET", "/?",
     function (req)
         local is_admin = self:is_admin(req.cookies)
-        local gnames = {}
         self:scan()
-        for gname in pairs(self.groups) do
-            if allowed(is_admin, gname) then
-                table.insert(gnames, gname)
+        local repos = {}
+        for rname, repo in pairs(self.repos) do
+            if allowed(is_admin, repo) then
+                local desc = repo.desc:gsub("^:", "")
+                if starts_with(desc, "Unnamed") then
+                    desc = "<em>no description</em>"
+                end
+                table.insert(repos, {name=rname, desc=desc})
             end
         end
-        local env = {title=self.title, is_admin=is_admin, gnames=gnames}
+        local env = {title=self.title, is_admin=is_admin, repos=repos}
         return lud.template.render_file("view/home.html", env)
     end},
     {"GET", "/login",
@@ -148,74 +159,61 @@ function Cogit:routes()
         end
         return "/", 303
     end},
-    {"GET", "/group/([%w_-]+)",
-    function (req, gname)
-        local is_admin = self:is_admin(req.cookies)
-        if not allowed(is_admin, gname) then
-            return "/login", 303
-        end
-        local rnames = {}
-        for rname in pairs(self.groups[gname]) do
-            table.insert(rnames, rname)
-        end
-        local env = {title=self.title, is_admin=is_admin, gname=gname, rnames=rnames}
-        return lud.template.render_file("view/group.html", env)
-    end},
-    {"GET", "/group/([%w_-]+)/repo/([%w_-]+)",
-    function (req, gname, rname)
+    {"GET", "/repo/([%w_-]+)",
+    function (req, rname)
         local is_admin = self:is_admin(req.cookies)
-        if not allowed(is_admin, gname) then
+        local repo = self.repos[rname]
+        if not allowed(is_admin, repo) then
             return "/login", 303
         end
-        local repo = self.groups[gname][rname]
         local bnames = repo:branches()
         local tnames = repo:tags()
         local env = {
-            title=self.title, is_admin=is_admin, repo=repo, gname=gname,
+            title=self.title, is_admin=is_admin, repo=repo,
             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)
+    {"GET", "/repo/([%w_-]+)/history/([%w_-]+)",
+    function (req, rname, first)
         local is_admin = self:is_admin(req.cookies)
-        if not allowed(is_admin, gname) then
+        local repo = self.repos[rname]
+        if not allowed(is_admin, repo) then
             return "/login", 303
         end
-        local repo = self.groups[gname][rname]
         local commit = repo:commit(first)
         local prev = repo:find_prev(commit:id(), self.limit)
         local env = {
-            title=self.title, is_admin=is_admin, gname=gname, rname=rname,
-            bname=bname, commit=commit, limit=self.limit, prev=prev, first=first,
+            title=self.title, is_admin=is_admin, rname=rname,
+            commit=commit, limit=self.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)
+    {"GET", "/repo/([%w_-]+)/commit/([%w_-]+)",
+    function (req, rname, cid)
         local is_admin = self:is_admin(req.cookies)
-        if not allowed(is_admin, gname) then
+        local repo = self.repos[rname]
+        if not allowed(is_admin, repo) 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=self.title, is_admin=is_admin, gname=gname, rname=rname, bname=bname,
-            commit=commit, time_str=time_str, sig=sig, cid=cid, prev=prev, diff=diff,
+            title=self.title, is_admin=is_admin, rname=rname, 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)
+    {"GET", "/repo/([%w_-]+)/commit/([%w_-]+)/tree/(.*)",
+    function (req, rname, cid, path)
         local is_admin = self:is_admin(req.cookies)
-        if not allowed(is_admin, gname) then
+        local repo = self.repos[rname]
+        if not allowed(is_admin, repo) 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
@@ -230,7 +228,7 @@ function Cogit:routes()
             base = base .. "/"
         end
         local env = {
-            title=self.title, is_admin=is_admin, gname=gname, rname=rname, cid=cid,
+            title=self.title, is_admin=is_admin, rname=rname, cid=cid,
             path=path, base=base, parts=parts, node=node,
         }
         if node.type_ == "dir" then

diff --git a/cogit/git.lua b/cogit/git.lua
index b16ff24..c4db1b7 100644
--- a/cogit/git.lua
+++ b/cogit/git.lua
@@ -359,6 +359,7 @@ local function open(path)
     local prepo = ffi.new("git_repository *[1]")
     assert(C.git_repository_open_bare(prepo, path) == 0)
     self.repo = prepo[0]
+    self.desc = io.open(path.."/description"):read()
     return self
 end
 

diff --git a/cogit/scan.lua b/cogit/scan.lua
index 7c7d603..4f18bc3 100644
--- a/cogit/scan.lua
+++ b/cogit/scan.lua
@@ -46,24 +46,16 @@ local function listdir(path, filter)
 end
 
 local function scanrepos(path)
-    local folders = listdir(path, function (e)
-        return e.d_type == C.DT_DIR and ffi.string(e.d_name):sub(1, 1) ~= "."
+    local git_folders = listdir(path, function (e)
+        return e.d_type == C.DT_DIR and (ffi.string(e.d_name):match(".*%.git$") ~= nil)
     end)
-    local groups = {}
-    for _, folder in ipairs(folders) do
-        local group_path = path.."/"..folder
-        local git_folders = listdir(group_path, function (e)
-            return e.d_type == C.DT_DIR and (ffi.string(e.d_name):match(".*%.git$") ~= nil)
-        end)
-        local group = {}
-        for _, git_folder in ipairs(git_folders) do
-            local repo_path = group_path.."/"..git_folder
-            local repo_name = git_folder:match("(.*)%.git$")
-            group[repo_name] = git.open(repo_path)
-        end
-        groups[folder] = group
+    local repos = {}
+    for _, git_folder in ipairs(git_folders) do
+        local repo_path = path.."/"..git_folder
+        local repo_name = git_folder:match("(.*)%.git$")
+        repos[repo_name] = git.open(repo_path)
     end
-    return groups
+    return repos
 end
 
 return {scanrepos=scanrepos}

diff --git a/view/commit.html b/view/commit.html
index 397d572..27244ab 100644
--- a/view/commit.html
+++ b/view/commit.html
@@ -18,15 +18,13 @@
   <div id="nav-bar">
     <a href="/">home</a>
     &gt;
-    <a href="/group/{{$gname}}">{{$gname}}</a>
+    <a href="/repo/{{$rname}}">{{$rname}}</a>
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}">{{$rname}}</a>
-    &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$cid}}">history</a>
+    <a href="/repo/{{$rname}}/history/{{$cid}}">history</a>
     &gt;
     {{$cid}}
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$cid}}/tree/">tree</a>
+    <a href="/repo/{{$rname}}/commit/{{$cid}}/tree/">tree</a>
   </div>
   <div id="auth-bar">
     % if $is_admin then
@@ -38,13 +36,13 @@
   </div>
   <br>
   % if $prev then
-  <a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$prev:id()}}">&lt</a>
+  <a href="/repo/{{$rname}}/commit/{{$prev:id()}}">&lt</a>
   % else
   &lt
   % end
   &nbsp;&nbsp;&nbsp;
   % if $commit:parent() then
-  <a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$commit:parent():id()}}">&gt</a>
+  <a href="/repo/{{$rname}}/commit/{{$commit:parent():id()}}">&gt</a>
   % else
   &gt
   % end

diff --git a/view/dir.html b/view/dir.html
index 4a9b8fc..5848078 100644
--- a/view/dir.html
+++ b/view/dir.html
@@ -12,13 +12,11 @@
   <div id="nav-bar">
     <a href="/">home</a>
     &gt;
-    <a href="/group/{{$gname}}">{{$gname}}</a>
+    <a href="/repo/{{$rname}}">{{$rname}}</a>
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}">{{$rname}}</a>
+    <a href="/repo/{{$rname}}/commit/{{$cid}}">{{$cid}}</a>
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$cid}}">{{$cid}}</a>
-    &gt;
-    % set partial = "/group/"..$gname.."/repo/"..$rname.."/commit/"..$cid.."/tree"
+    % set partial = "/repo/"..$rname.."/commit/"..$cid.."/tree"
     <a href="{{$partial}}/">tree</a>
     % for part in $parts do
     % set partial = $partial .. "/" .. $part

diff --git a/view/file.html b/view/file.html
index 7f8ad84..2b7a8de 100644
--- a/view/file.html
+++ b/view/file.html
@@ -12,13 +12,11 @@
   <div id="nav-bar">
     <a href="/">home</a>
     &gt;
-    <a href="/group/{{$gname}}">{{$gname}}</a>
+    <a href="/repo/{{$rname}}">{{$rname}}</a>
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}">{{$rname}}</a>
+    <a href="/repo/{{$rname}}/commit/{{$cid}}">{{$cid}}</a>
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$cid}}">{{$cid}}</a>
-    &gt;
-    % set partial = "/group/"..$gname.."/repo/"..$rname.."/commit/"..$cid.."/tree"
+    % set partial = "/repo/"..$rname.."/commit/"..$cid.."/tree"
     <a href="{{$partial}}/">tree</a>
     % for part in $parts do
     % set partial = $partial .. "/" .. $part

diff --git a/view/group.html b/view/group.html
deleted file mode 100644
index 0d60be7..0000000
--- a/view/group.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>{{$title}} - {{$gname}} repos</title>
-  <style>
-    #nav-bar { float: left; }
-    #auth-bar { float: right; }
-  </style>
-</head>
-<body>
-  <div id="nav-bar">
-    <a href="/">home</a>
-    &gt;
-    {{$gname}}
-  </div>
-  <div id="auth-bar">
-    % if $is_admin then
-    <strong>Admin</strong>
-    <a href="/logout">(logout)</a>
-    % else
-    <a href="/login">login</a>
-    % end
-  </div>
-  <br>
-  <p>Repos:</p>
-  <ul>
-    % for rname in $rnames do
-    <li><a href="/group/{{$gname}}/repo/{{$rname}}">{{$rname}}</a></li>
-    % end
-  </ul>
-</body>
-</html>

diff --git a/view/history.html b/view/history.html
index 1a55cb7..df442ff 100644
--- a/view/history.html
+++ b/view/history.html
@@ -12,13 +12,11 @@
   <div id="nav-bar">
     <a href="/">home</a>
     &gt;
-    <a href="/group/{{$gname}}">{{$gname}}</a>
-    &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}">{{$rname}}</a>
+    <a href="/repo/{{$rname}}">{{$rname}}</a>
     &gt;
     history
     &gt;
-    <a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$first}}/tree/">tree</a>
+    <a href="/repo/{{$rname}}/commit/{{$first}}/tree/">tree</a>
   </div>
   <div id="auth-bar">
     % if $is_admin then
@@ -30,7 +28,7 @@
   </div>
   <br>
   % if $prev then
-  <a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$prev:id()}}">&lt</a>
+  <a href="/repo/{{$rname}}/history/{{$prev:id()}}">&lt</a>
   % else
   &lt
   % end
@@ -42,7 +40,7 @@
     % set i = $i + 1
   % end
   % if $next then
-  <a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$next:id()}}">&gt</a>
+  <a href="/repo/{{$rname}}/history/{{$next:id()}}">&gt</a>
   % else
   &gt
   % end
@@ -50,7 +48,7 @@
   <ul>
     % set i = 0
     % while $commit and $i < $limit do
-    <li><a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$commit:id()}}">{{$commit:summary()}}</a></li>
+    <li><a href="/repo/{{$rname}}/commit/{{$commit:id()}}">{{$commit:summary()}}</a></li>
       % set commit = $commit:parent()
       % set i = $i + 1
     % end

diff --git a/view/home.html b/view/home.html
index d1ee0ab..6b627de 100644
--- a/view/home.html
+++ b/view/home.html
@@ -6,6 +6,17 @@
   <style>
     #nav-bar { float: left; }
     #auth-bar { float: right; }
+    table {
+      border-collapse: collapse;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    th { background-color: #EEEEEE; }
+    th, td {
+      padding: 3px 12px;
+      border: 1px solid #006;
+    }
   </style>
 </head>
 <body>
@@ -19,11 +30,22 @@
     % end
   </div>
   <br>
-  <p>Groups:</p>
-  <ul>
-    % for gname in $gnames do
-    <li><a href="/group/{{$gname}}">{{$gname}}</a></li>
+  % if #$repos == 0 then
+  <p><em>no repos found</em></p>
+  % else
+  <br>
+  <table>
+    <tr>
+      <th>repo</th>
+      <th>description</th>
+    </tr>
+    % for repo in $repos do
+    <tr>
+      <td><a href="/repo/{{$repo.name}}">{{$repo.name}}</a></td>
+      <td>{{$repo.desc}}</td>
+    </tr>
     % end
-  </ul>
+  </table>
+  % end
 </body>
 </html>

diff --git a/view/repo.html b/view/repo.html
index a6475f5..6e12213 100644
--- a/view/repo.html
+++ b/view/repo.html
@@ -12,8 +12,6 @@
   <div id="nav-bar">
     <a href="/">home</a>
     &gt;
-    <a href="/group/{{$gname}}">{{$gname}}</a>
-    &gt;
     {{$rname}}
   </div>
   <div id="auth-bar">
@@ -28,7 +26,7 @@
   <p>Branches:</p>
   <ul>
     % for bname in $bnames do
-    <li><a href="/group/{{$gname}}/repo/{{$rname}}/history/{{$bname}}">{{$bname}}</a></li>
+    <li><a href="/repo/{{$rname}}/history/{{$bname}}">{{$bname}}</a></li>
     % end
   </ul>
   % if #$tnames > 0 then
@@ -36,7 +34,7 @@
   <ul>
     % for tname in $tnames do
       % set cid = $repo:commit($tname.."^{}"):id()
-    <li><a href="/group/{{$gname}}/repo/{{$rname}}/commit/{{$cid}}">{{$tname}}</a></li>
+    <li><a href="/repo/{{$rname}}/commit/{{$cid}}">{{$tname}}</a></li>
     % end
   </ul>
   % end