From af6820a94b670f78acc6bf04405f025c26e7efff Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 22 Nov 2011 14:55:15 +0530 Subject: [PATCH] new functions (can_*, is_admin, in_group) for ADCs (can_* == can_read, can_write, and can_create) See top of contrib/adc/adc.common-functions for more on this. Note: the old style (calling get_rights_and_owner with $repo, then checking $perm_read, $perm_write, etc.), will still work fine. --- contrib/adc/able | 3 +- contrib/adc/adc.common-functions | 73 ++++++++++++++++++++++++++++++++ contrib/adc/fork | 10 ++--- contrib/adc/restrict-admin | 3 +- contrib/adc/su-expand | 3 +- contrib/adc/su-getperms | 3 +- contrib/adc/sudo | 3 +- contrib/adc/symbolic-ref | 6 ++- contrib/adc/watch | 5 +-- contrib/adc/who-pushed | 5 +-- doc/admin-defined-commands.mkd | 6 +-- src/gitolite.pm | 10 +++++ 12 files changed, 104 insertions(+), 26 deletions(-) diff --git a/contrib/adc/able b/contrib/adc/able index 65b1a16..209a477 100755 --- a/contrib/adc/able +++ b/contrib/adc/able @@ -2,8 +2,7 @@ . $(dirname $0)/adc.common-functions -get_rights_and_owner gitolite-admin -[ -z "$perm_write" ] && die "just *what* are you trying to pull, young man?" +is_admin || die "just *what* are you trying to pull, young man?" op=$1 shift diff --git a/contrib/adc/adc.common-functions b/contrib/adc/adc.common-functions index 89a3248..e9520ce 100644 --- a/contrib/adc/adc.common-functions +++ b/contrib/adc/adc.common-functions @@ -2,6 +2,24 @@ # please make sure this file is NOT chmod +x +# this file contains settings for all ADCs at the top, then functions that you +# can call from shell scripts. Other files in this directory have examples. + +# all uses require you to "source" this file, like so: + +# # at the top of your ADC +# . $(dirname $0)/adc.common-functions + +# then you use one of the following functions, like so: + +# can_create reponame || die "you can't create reponame" +# can_write reponame || die "you can't write reponame" +# can_read reponame || die "you can't read reponame" +# is_admin || die "you're not an admin" + +# IMPORTANT NOTE: all the can_* functions set $repo to the normalised reponame +# (i.e., with '.git' extension removed if it was supplied). + # ------------------------------------------------------------------------------ # settings for various ADCs, collected in one place for ease of keeping local @@ -24,6 +42,9 @@ GL_FORKED_FROM="gl-forked-from" # Change to 1 to make -list the default action for the 'help' command HELP_LIST_DEFAULT=0 +# name of "admin" group (see is_admin() below before uncommenting) +# ADMIN_GROUPNAME=admins + # ------------------------------------------------------------------------------ die() { echo "$@"; exit 1; } @@ -57,3 +78,55 @@ get_rights_and_owner() { echo $rights | grep R >/dev/null 2>&1 && perm_read=yes || perm_read= echo $rights | grep W >/dev/null 2>&1 && perm_write=yes || perm_write= } + +can_create() { + get_rights_and_owner ${1%.git} + [ -z "$perm_create" ] && return 1 + return 0 +} + +can_write() { + get_rights_and_owner ${1%.git} + [ -z "$perm_write" ] && return 1 + return 0 +} + +can_read() { + get_rights_and_owner ${1%.git} + [ -z "$perm_read" ] && return 1 + return 0 +} + +# ------------------------------------------------------------------------------ + +# check if current user is an admin +is_admin() { + # there are two ways to check if someone is an admin. The default (if + # ADMIN_GROUPNAME is not defined) is to check if they have write access to + # the admin repo + + if [ -z "$ADMIN_GROUPNAME" ] + then + can_write gitolite-admin || return 1 + return 0 + fi + + # the alternative way is to check membership in $ADMIN_GROUPNAME; please + # remember this method requires GL_BIG_CONFIG to be set + + # TODO, pending the code to allow an external query of a user's "group" + # affiliations + in_group $ADMIN_GROUPNAME +} + +# ------------------------------------------------------------------------------ + +grouplist() { + perl -I$GL_BINDIR -Mgitolite -e "cli_grouplist()" +} + +in_group() { + local g=$1 + grouplist | egrep "(^| )$g( |$)" >/dev/null && return 0 + return 1 +} diff --git a/contrib/adc/fork b/contrib/adc/fork index ff2a9cb..81a0f3e 100755 --- a/contrib/adc/fork +++ b/contrib/adc/fork @@ -5,12 +5,12 @@ [ -z "$GL_RC" ] && die "ENV GL_RC not set" [ -z "$2" ] && die "Usage: fork source_repo target_repo" -# get_rights_and_owner now also sets $repo; see comments in common functions -get_rights_and_owner $1; from=$repo -[ -z "$perm_read" ] && die "no read permissions on $from" +# all the can_* functions set $repo +can_read $1 || die "no read permissions on $repo" +from=$repo -get_rights_and_owner $2; to=$repo -[ -z "$perm_create" ] && die "no create permissions on $to" +can_create $2 || die "no create permissions on $repo" +to=$repo # clone $from to $to git clone --bare -l $GL_REPO_BASE_ABS/$from.git $GL_REPO_BASE_ABS/$to.git diff --git a/contrib/adc/restrict-admin b/contrib/adc/restrict-admin index 8d3d892..8e28924 100755 --- a/contrib/adc/restrict-admin +++ b/contrib/adc/restrict-admin @@ -2,8 +2,7 @@ . $(dirname $0)/adc.common-functions -get_rights_and_owner gitolite-admin -[ -z "$perm_write" ] && die "just *what* are you trying to pull, young man?" +is_admin || die "just *what* are you trying to pull, young man?" # and here you let them do the dangerous stuff echo "+rm -rf $GL_REPO_BASE_ABS" diff --git a/contrib/adc/su-expand b/contrib/adc/su-expand index 95234e9..f45416b 100755 --- a/contrib/adc/su-expand +++ b/contrib/adc/su-expand @@ -46,8 +46,7 @@ . $(dirname $0)/adc.common-functions -get_rights_and_owner gitolite-admin -[ -z "$perm_write" ] && die "just *what* are you trying to pull here, $GL_USER?" +is_admin || die "just *what* are you trying to pull here, $GL_USER?" pat="$1"; shift for user diff --git a/contrib/adc/su-getperms b/contrib/adc/su-getperms index bab7859..c5d58d1 100755 --- a/contrib/adc/su-getperms +++ b/contrib/adc/su-getperms @@ -16,8 +16,7 @@ . $(dirname $0)/adc.common-functions -get_rights_and_owner gitolite-admin -[ -z "$perm_write" ] && die "just *what* are you trying to pull here, $GL_USER?" +is_admin || die "just *what* are you trying to pull here, $GL_USER?" # find the command name; we don't do a lot of fancy checking -- we just go # "safe" and assume that anything but a name of "su-setperms" runs getperms diff --git a/contrib/adc/sudo b/contrib/adc/sudo index 47d9641..16781d4 100755 --- a/contrib/adc/sudo +++ b/contrib/adc/sudo @@ -13,8 +13,7 @@ . $(dirname $0)/adc.common-functions -get_rights_and_owner gitolite-admin -[ -z "$perm_write" ] && die "just *what* are you trying to pull, young man?" +is_admin || die "just *what* are you trying to pull, young man?" user="$1"; shift cmd="$1"; shift diff --git a/contrib/adc/symbolic-ref b/contrib/adc/symbolic-ref index 86e5b8b..6634961 100755 --- a/contrib/adc/symbolic-ref +++ b/contrib/adc/symbolic-ref @@ -23,8 +23,10 @@ # of git-symbolic-ref to also work [ -z "$2" ] && die "usage: symbolic-ref /path/to/repo.git " -get_rights_and_owner $1; to=$repo -[ -z "$perm_write" ] && die "no write permissions on $to" +# all the can_* functions set $repo +can_write $1 || die "no write permissions on $repo" +to=$repo + shift # change head diff --git a/contrib/adc/watch b/contrib/adc/watch index 1ca1556..386e40e 100755 --- a/contrib/adc/watch +++ b/contrib/adc/watch @@ -52,9 +52,8 @@ #[ -z "$perm_write" ] && die "just *what* are you trying to pull, young man?" #get_rights_and_owner $1; -# Comment this block if uncommenting the above block -get_rights_and_owner $1; -[ -z "$perm_read" ] && die "no read permissions on $repo" +# all the can_* functions set $repo +can_read $1 || die "no read permissions on $repo" cmd=$2 identifier=$3 diff --git a/contrib/adc/who-pushed b/contrib/adc/who-pushed index 413b417..db7f7d0 100755 --- a/contrib/adc/who-pushed +++ b/contrib/adc/who-pushed @@ -10,9 +10,8 @@ sha=$2 [ -n "$sha" ] || die Usage: ssh ... who-pushed reponame SHA \# at least first few hex digits -# get_rights_and_owner now also sets $repo; see comments in common functions -get_rights_and_owner $1 -[ -z "$perm_read" ] && die "no read permissions on $repo" +# all the can_* functions set $repo +can_read $1 || die "no read permissions on $repo" cd $GL_REPO_BASE_ABS/$repo.git diff --git a/doc/admin-defined-commands.mkd b/doc/admin-defined-commands.mkd index a9a484c..8e16407 100644 --- a/doc/admin-defined-commands.mkd +++ b/doc/admin-defined-commands.mkd @@ -128,9 +128,9 @@ like `_____R__W u1` or maybe `____@R_@W `. (The `u1` indicates the queried repo is a wildcard repo created by user `u1`; for meanings of the "@" see doc/report-output.mkd) -But that's cumbersome. There's a bash shell function called -`get_rights_and_owner` in `contrib/adc/adc.common-functions` that is much more -convenient. See any of the other samples for how to use it. +But that's cumbersome. It's much nicer to use the convenient functions +defined in `contrib/adc/adc.common-functions`; see the comments in that file +for details, and any of the other samples for how to use them. If you prefer perl, there is a nicely commented example in `contrib/adc/get-rights-and-owner.in-perl`. diff --git a/src/gitolite.pm b/src/gitolite.pm index fcbda13..4d5f9e2 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -8,6 +8,7 @@ use Exporter 'import'; check_ref check_repo_write_enabled cli_repo_rights + cli_grouplist dbg dos2unix list_phy_repos @@ -837,6 +838,15 @@ sub cli_repo_rights { print join(" ", check_access($_[0])), "\n"; } +# helper/convenience routine to get group membership info +sub cli_grouplist { + die "GL_BIG_CONFIG needs to be set\n" unless $GL_BIG_CONFIG; + # we may not have any data yet... + parse_acl() unless (%repos); + my @groups = grep { s/^@//; } get_memberships($ENV{GL_USER}, 0); + print join(" ", @groups), "\n"; +} + sub can_read { my $repo = shift; my $user = shift || $ENV{GL_USER};