如何通过 git 预接收挂钩验证用户

How to authenticate user via git pre-receive hook

我想在 Python 中编写一个 pre-receive git 挂钩。据我了解,没有参数被传递到 pre-receive 脚本中,而是每个引用都使用标准输入在单独的行中传递。我已经能够通过以下方式阅读参考更改:

!/usr/bin/env python

import sys
import fileinput

for line in fileinput.input():
    print "pre-receive: Trying to push ref: %s" % line

然而,对于这个钩子,我主要关心的是确保推送代码的用户有正确的权限来推送到他们试图推送到的分支。通过我的研究,我一直无法找到一种方法来寻找提交者的用户凭证。我的目标是将他们的信誉与白名单进行比较以授予访问权限。

如何更改我的 pre-receive 代码以验证提交用户的身份并验证他们是否已列入白名单以推送到他们尝试的分支?如果有的话,我必须对 git 存储库进行哪些更改才能使代码正常运行?

如果您通过 ssh(或本地文件系统中的 git)使用 git,提交用户将可用于环境变量 USER 中的挂钩,因此在 python 你可以检查 os.environ['USER']

可以设置一个环境(使用 git-daemon;还有其他方法),您的 git 服务器收到一个包并且根本没有附加任何身份验证信息;那样的话你就不走运了。

从标准输入中,我们可以得到<old-value> SP <new-value> SP <ref-name> LF。在钩子中使用git cat-file -p $new-valuegit cat-file -p $ref-name,我们可以得到这样的信息

tree d06734b17feff2faf22bcd7c0fac1587876e601d
parent 524bd5e2fa72e6358a22f28582e094de936c3768
author Xyz <mm@nn.com> 1466782764 +0800
committer Abc <ss@tt.com> 1466782764 +0800

或者更直接的方式,我们可以使用 git log -1 --pretty=%an $ref-name 获取作者,并使用 git log -1 --pretty=%cn $ref-name 获取提交者。

所以 bash 中的一部分钩子可能是这样的:

#!/bin/bash

read old new ref
author=$(git log -1 $ref --pretty=%an)
committer=$(git log -1 $ref --pretty=%cn)
echo author:$author
echo committer:$committer

左边部分是检查作者或提交者是否有权做某事。

我在 python 中实现钩子的版本是

#!/usr/bin/env python

import sys
import fileinput
import commands

for line in fileinput.input():
    print "pre-receive: Trying to push ref: %s" % line
    values = line.split()
    old = values[0]
    new = values[1]
    ref = values[2]
    author = ''
    committer = ''
    status,output = commands.getstatusoutput('git log -1 --pretty=%an {0}'.format(ref))
    if status == 0:
        author = output
    status,output = commands.getstatusoutput('git log -1 --pretty=%cn {0}'.format(ref))
    if status == 0:
        committer = output