问题
I am looking to write a pre-receive
githook in Python. It is my understanding that no arguments are passed into pre-receive
scripts but rather each reference is passed in using standard input on separate lines. I have been able to read the reference changes via:
!/usr/bin/env python
import sys
import fileinput
for line in fileinput.input():
print "pre-receive: Trying to push ref: %s" % line
However, for this hook, I am mainly concerned with making sure that the user pushing code has the correct privileges to push to the branch of which they are trying to. Through my research, I have been unable to find a way to seek the committer's user credentials. It was my goal to compare their creds against a whitelist in order to grant access.
How can I change my pre-receive
code to authenticate the committing user and verify that they are whitelisted to push to their attempted branch? And what, if any, changes do I have to make on the git repository to make the code function?
回答1:
From the stdin, we can get <old-value> SP <new-value> SP <ref-name> LF
. Use git cat-file -p $new-value
or git cat-file -p $ref-name
in the hook, we can get info like this
tree d06734b17feff2faf22bcd7c0fac1587876e601d
parent 524bd5e2fa72e6358a22f28582e094de936c3768
author Xyz <mm@nn.com> 1466782764 +0800
committer Abc <ss@tt.com> 1466782764 +0800
Or in a more straightforward way, we can use git log -1 --pretty=%an $ref-name
to get the author, and git log -1 --pretty=%cn $ref-name
to get the committer.
So a part of the hook in bash could be like:
#!/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
The left part is to check if the author or committer has the right to do something.
My version to implement your hook in python would be
#!/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
回答2:
If you are using git over ssh (or git in the local file system) the committing user will be available to the hook in the environment variable USER, so in python you can check against os.environ['USER']
It is possible to set up an environment (using git-daemon; there are other ways as well) where your git server receives a pack and there is no authenticating information at all attached; in that case you are out of luck.
来源:https://stackoverflow.com/questions/38015205/how-to-authenticate-user-via-git-pre-receive-hook