通过钩子对每个分支进行Git用户授权

时间:2013-08-14 07:21:07

标签: git bash repository authorization githooks

5位开发人员可以通过相同的ssh-account访问git-repository。 我需要限制该repo的某些分支(生产,开发)的推送访问。 如何使用git hook实现简单的分支安全性?

3 个答案:

答案 0 :(得分:1)

首先,让我指出,在GIT中,可以使用一个push命令上传更多分支,在这种情况下,这可能是一个安全风险。为了避免这种情况,你应该使用类似下面的脚本(只是认为每个人都可以推送到第一个分支但是第二个......授权将在第一个分支 - 但是第二个分支?)

while read anotherOldrev anotherNewrev anotherRefname
    do
        newRefType="$(echo $anotherRefname | awk '{split($0,a,"/"); print a[2]}')"
        if test "$newRefType" = "heads"
        then
            #branch
            if test "$refname"
            then
                #branch, 2nd time, which means another branch
            else
                #branch, 1st time
                oldrev=$anotherOldrev
                newrev=$anotherNewrev
                refname=$anotherRefname
            fi
        else
            #tag
        fi
    done

另一方面,我不确定你是否可以在预接收挂钩中进行授权,因为你在那里获得的所有信息都是旧参考,新参考和它的名字...... ...但暂时更改名称只是一两个命令(http://git-scm.com/book/en/Customizing-Git

答案 1 :(得分:1)

您可以使用预接收或更新挂钩来执行此操作,是的。 (这里的区别在于预接收挂钩只能接受或拒绝整个推送,而更新挂钩可以接受或拒绝每个单独的ref-update。)请注意,gitolite支持这个“out”的方框“。有关高级概述,请参阅the git book

答案 2 :(得分:0)

预先接收挂钩的简单解决方案:

#!/bin/bash

while read old_rev new_rev ref_name; do
    for script in `find $PWD/hooks/pre-receive.d/ -perm -100 -type f`; do
        ${script} "$old_rev" "$new_rev" "$ref_name"
        if [ "$?" -ne 0 ]; then
            status=1
        fi
    done
done

exit ${status}

此文件必须位于 pre-receive.d 目录中:

#!/bin/bash

old_rev=$1
new_rev=$2
ref_name=$3

# Secure branches
sec_branches=(refs/heads/production refs/heads/development)

# Authorized users
authorized_users=('John Doe' 'Bob Smith')

# get rev type
zero="0000000000000000000000000000000000000000"
if [ "$new_rev" = "$zero" ]; then
    new_rev_type=delete
else
    new_rev_type=$(git cat-file -t ${new_rev})
fi

case "$ref_name","$new_rev_type" in
    refs/heads/*,commit)
        # new commit        
        case ${sec_branches[@]} in
            *${ref_name}*)
                # Save committer and author into variables
                commit_prefs=$(git log -1 --pretty=format:'%an:%cn' ${new_rev})
                IFS=":" read author committer <<< "$commit_prefs"

                # if committer and author not in allowed persons - exit
                case ${authorized_users[@]} in
                    *${author}*)
                    ;;
                    *)
                        branch_name=`echo ${ref_name:11}`
                        echo
                        echo "You're not allowed to push in $branch_name branch" >&2
                        echo
                        exit 1
                    ;;
                esac

                # if committer and author not equal - exit
                if [ "$author" != "$committer" ]; then
                    echo
                    echo "You're not author of pushed commits. This is prohibited" >&2
                    echo
                    exit 1
                fi
            ;;
        esac
    ;;
esac

<强>更新
正如评论torek中所述,这不是安全的解决方案,但它可以防止事故发生。