aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Doan <andy.doan@linaro.org>2016-09-29 16:59:54 -0500
committerAndy Doan <andy.doan@linaro.org>2016-10-18 11:49:18 -0500
commitf85c40c4ed1c8bfca09acd1fccaf9bb77baa0c0f (patch)
tree77e37563fb382096f16a528a84adede229609068
parent8983f30d31595c6e2167543a0ce37ddab3405ca7 (diff)
downloadcgit-linaro-patches.tar.gz
ui-repolist: add ability to control what repos a user seelinaro-patches
The auth-filter works at the repository level but still shows repositories in ui-repolist. This change allows you to limit what a user sees based on the STDOUT of a command. The existing filter code doesn't handle the capture of stdout, so a new mechanism was created just for this. Signed-off-by: Andy Doan <andy.doan@linaro.org>
-rw-r--r--cgit.c2
-rw-r--r--cgit.h1
-rw-r--r--ui-repolist.c63
3 files changed, 60 insertions, 6 deletions
diff --git a/cgit.c b/cgit.c
index 1075753..8d47bb4 100644
--- a/cgit.c
+++ b/cgit.c
@@ -215,6 +215,8 @@ static void config_cb(const char *name, const char *value)
ctx.cfg.owner_filter = cgit_new_filter(value, OWNER);
else if (!strcmp(name, "auth-filter"))
ctx.cfg.auth_filter = cgit_new_filter(value, AUTH);
+ else if (!strcmp(name, "allowed-repos-cmd"))
+ ctx.cfg.allowed_repos_cmd = xstrdup(expand_macros(value));
else if (!strcmp(name, "embedded"))
ctx.cfg.embedded = atoi(value);
else if (!strcmp(name, "max-atom-items"))
diff --git a/cgit.h b/cgit.h
index fbc6c6a..05189d8 100644
--- a/cgit.h
+++ b/cgit.h
@@ -267,6 +267,7 @@ struct cgit_config {
struct cgit_filter *email_filter;
struct cgit_filter *owner_filter;
struct cgit_filter *auth_filter;
+ char *allowed_repos_cmd;
};
struct cgit_page {
diff --git a/ui-repolist.c b/ui-repolist.c
index 82e94c0..dfb6756 100644
--- a/ui-repolist.c
+++ b/ui-repolist.c
@@ -10,6 +10,14 @@
#include "ui-repolist.h"
#include "html.h"
#include "ui-shared.h"
+#include "run-command.h"
+
+
+struct allowed_repos {
+ const char *name;
+ struct allowed_repos *next;
+};
+
static time_t read_agefile(char *path)
{
@@ -97,6 +105,38 @@ static int is_match(struct cgit_repo *repo)
return 0;
}
+static struct allowed_repos* find_allowed_repos(void)
+{
+ struct strbuf buf = STRBUF_INIT;
+ struct child_process cp = CHILD_PROCESS_INIT;
+ const char *argv[] = {ctx.cfg.allowed_repos_cmd, NULL};
+ char *result, *token;
+ struct allowed_repos *allowed = NULL, *prev=NULL;
+
+ cp.argv = argv;
+ cp.no_stdin = 1;
+
+ if (!capture_command(&cp, &buf, 1024)) {
+ strbuf_trim(&buf);
+ result = strbuf_detach(&buf, NULL);
+
+ token = strtok(result, "\n");
+ while( token != NULL ) {
+ if (!prev) {
+ allowed = xmalloc(sizeof(*allowed));
+ prev = allowed;
+ } else {
+ prev->next = xmalloc(sizeof(*allowed));
+ prev = prev->next;
+ }
+ prev->name = token;
+ prev->next = NULL;
+ token = strtok(NULL, "\n");
+ }
+ }
+ return allowed;
+}
+
static int is_in_url(struct cgit_repo *repo)
{
if (!ctx.qry.url)
@@ -106,21 +146,28 @@ static int is_in_url(struct cgit_repo *repo)
return 0;
}
-static int is_visible(struct cgit_repo *repo)
+static int is_visible(struct allowed_repos *allowed, struct cgit_repo *repo)
{
if (repo->hide || repo->ignore)
return 0;
if (!(is_match(repo) && is_in_url(repo)))
return 0;
+ if (ctx.cfg.allowed_repos_cmd) {
+ while(allowed) {
+ if (!strcmp(repo->url, allowed->name))
+ return 1;
+ allowed = allowed->next;
+ }
+ return 0;
+ }
return 1;
}
-static int any_repos_visible(void)
+static int any_repos_visible(struct allowed_repos *allowed)
{
int i;
-
for (i = 0; i < cgit_repolist.count; i++) {
- if (is_visible(&cgit_repolist.repos[i]))
+ if (is_visible(allowed, &cgit_repolist.repos[i]))
return 1;
}
return 0;
@@ -277,8 +324,12 @@ void cgit_print_repolist(void)
char *section;
char *repourl;
int sorted = 0;
+ struct allowed_repos * allowed = NULL;
+
+ if (ctx.cfg.allowed_repos_cmd)
+ allowed = find_allowed_repos();
- if (!any_repos_visible()) {
+ if (!any_repos_visible(allowed)) {
cgit_print_error_page(404, "Not found", "No repositories found");
return;
}
@@ -304,7 +355,7 @@ void cgit_print_repolist(void)
html("<table summary='repository list' class='list nowrap'>");
for (i = 0; i < cgit_repolist.count; i++) {
ctx.repo = &cgit_repolist.repos[i];
- if (!is_visible(ctx.repo))
+ if (!is_visible(allowed, ctx.repo))
continue;
hits++;
if (hits <= ctx.qry.ofs)