---
 filters/gitolite-authorization.lua | 74 ++++++++++++++++++++++++++++++++++++++
 scan-tree.c                        | 18 ++++++++++
 2 files changed, 92 insertions(+)
 create mode 100644 filters/gitolite-authorization.lua

diff --git a/filters/gitolite-authorization.lua 
b/filters/gitolite-authorization.lua
new file mode 100644
index 0000000..2f0e4f5
--- /dev/null
+++ b/filters/gitolite-authorization.lua
@@ -0,0 +1,74 @@
+-- This script can be used with project-filter option
+-- It uses REMOTE_USER environment variable to obtain the user who needs to be 
authorized
+-- This variable is normally set by HTTP Basic Authentication.
+-- In Apache something like this can be used:
+--
+--    AuthType Basic
+--    AuthName Protected area
+--    AuthUserFile users.htpasswd
+--    Require valid-user
+--
+-- For anonymous access a public username can be set in environment config.
+-- In Apache, using mod_env:
+--
+--    SetEnv REMOTE_USER gitweb
+--
+-- Gitolite requires HOME environment variable to work properly and point to 
valid Gitolite
+-- environment. Since the user, under which web server process runs, usually 
does not have
+-- this set, HOME should be explicitly configured and pointed to valid 
gitolite setup.
+-- In Apache, using mod_env:
+--
+--    SetEnv HOME /path/to/gitolite/home
+
+
+local git = {}
+local http = {}
+local repos = {}
+local action = nil
+
+function action_init()
+       -- Anonymous access, cancel repo list building
+       if git.user == nil or git.user == "" then return end
+       
+       local handle = io.popen("gitolite list-phy-repos | gitolite access % " 
.. git.user .. " R any")
+       
+       while true do
+               local repo = handle:read()
+               if repo == nil then break end
+               
+               -- Skip DENIED repos
+               if not string.find(repo, "DENIED") then
+                       -- Gitolite returns string: <repo>\t<user>\t<refs>
+                       -- We are interested only in the first field for now
+                       -- Append .git extension since Gitolite does not and 
cgit repo name has it
+                       local name = string.sub(repo, 0, string.find(repo, 
"\t") - 1) .. ".git"
+                       repos[name] = 1 -- Authorize flag is > 0
+               end
+       end
+       
+       handle:close()
+end
+
+function action_filter()
+       -- Return > 0 if access is authorized
+       return repos[git.repo]
+end
+
+local actions = {}
+actions["init"] = action_init;
+actions["filter"] = action_filter;
+
+function filter_open(...)
+       action = actions[select(1, ...)]
+       
+       git["repo"] = select(2, ...)
+       git["user"] = select(3, ...)
+       
+       http["server"] = select(4, ...)
+       http["path"] = select(5, ...)
+end
+
+function filter_close()
+       return action()
+end
+
diff --git a/scan-tree.c b/scan-tree.c
index e17bca9..7490e74 100644
--- a/scan-tree.c
+++ b/scan-tree.c
@@ -74,6 +74,14 @@ static char *xstrrchr(char *s, char *from, int c)
        return from < s ? NULL : from;
 }
 
+static int open_project_filter(const char *action, const char *repo) {
+       return cgit_open_filter(ctx.cfg.project_filter, action, repo,
+                       ctx.env.remote_user ? ctx.env.remote_user : "",
+                       ctx.env.server_name ? ctx.env.server_name : "",
+                       ctx.env.path_info ? ctx.env.path_info : ""
+       );
+}
+
 static void add_repo(const char *base, struct strbuf *path, repo_config_fn fn)
 {
        struct stat st;
@@ -115,6 +123,11 @@ static void add_repo(const char *base, struct strbuf 
*path, repo_config_fn fn)
        else if (rel.len && rel.buf[rel.len - 1] == '/')
                strbuf_setlen(&rel, rel.len - 1);
 
+       if(ctx.cfg.project_filter) {
+               if(open_project_filter("filter", rel.buf)) return;
+               if(cgit_close_filter(ctx.cfg.project_filter) < 1) return;
+       }
+
        repo = cgit_add_repo(rel.buf);
        config_fn = fn;
        if (ctx.cfg.enable_git_config) {
@@ -261,6 +274,11 @@ void scan_projects(const char *path, const char 
*projectsfile, repo_config_fn fn
 
 void scan_tree(const char *path, repo_config_fn fn)
 {
+       if (ctx.cfg.project_filter) {
+               open_project_filter("init", path);
+               cgit_close_filter(ctx.cfg.project_filter);
+       }
+
        if (ctx.cfg.project_list) {
                scan_projects(path, ctx.cfg.project_list, fn);
                return;
-- 
2.1.4

_______________________________________________
CGit mailing list
[email protected]
http://lists.zx2c4.com/mailman/listinfo/cgit

Reply via email to