5

I would like to stop users to delete remote git branch by using server side hooks(update hook).

I have written shell script in update hook to achieve that.
Now I am able to stop all users to delete remote git branch, but I want to give delete permission to specific user, to do this we need to get user information(username, useremail) of who is trying the delete operation in server side hook?

we have $USER, $GIT_AUTHOR_NAME, $GIT_AUTHOR_EMAIL etc variables to get user information in client side hooks, but they are not useful in server side hooks.

Do we have any other options to get user info in server-side hooks?

CodeWizard
  • 92,491
  • 19
  • 110
  • 133
Surendra Reddy
  • 169
  • 2
  • 9

3 Answers3

7

Sample hook code

Keep in mind that everyone can fake the email in the commit with:

git commit -c user.name ... -c user.email ...

To avoid it got to your central repo documentation and read bout user permissions (vary between each server) and extract from there the info how to fetch user details.

#!/bin/sh
#

# Extract the desired information from the log message
# You can also use the information passed out by the central repo if its available

# %ae = Extract the user email from the last commit (author email)
USER_EMAIL=$(git log -1 --format=format:%ae HEAD)

# %an = Extract the username from the last commit (author name)
USER_NAME=$(git log -1 --format=format:%an HEAD)

# or use those values if you have them:
# $USER, $GIT_AUTHOR_NAME, $GIT_AUTHOR_EMAIL

#
#... Check the branches and whatever you want to do ...
#

# personal touch :-)
echo "                                         "
echo "                   |ZZzzz                "
echo "                   |                     "
echo "                   |                     "
echo "      |ZZzzz      /^\            |ZZzzz  "
echo "      |          |~~~|           |       "
echo "      |        |-     -|        / \      "
echo "     /^\       |[]+    |       |^^^|     "
echo "  |^^^^^^^|    |    +[]|       |   |     "
echo "  |    +[]|/\/\/\/\^/\/\/\/\/|^^^^^^^|   "
echo "  |+[]+   |~~~~~~~~~~~~~~~~~~|    +[]|   "
echo "  |       |  []   /^\   []   |+[]+   |   "
echo "  |   +[]+|  []  || ||  []   |   +[]+|   "
echo "  |[]+    |      || ||       |[]+    |   "
echo "  |_______|------------------|_______|   "
echo "                                         "
echo "                                         "
Community
  • 1
  • 1
CodeWizard
  • 92,491
  • 19
  • 110
  • 133
  • people can fake email but while perform any action they need to send proper authentication information such as username. And when we delete branch i guess we don't have log information to get the details. – Surendra Reddy Mar 01 '16 at 10:01
  • $USER, $GIT_AUTHOR_NAME, $GIT_AUTHOR_EMAIL are useful to get details on client side hooks, can't be useful in server side hooks. – Surendra Reddy Mar 01 '16 at 10:02
  • You can control it by restrict the allowed protocol to ssh which means that the server must authenticate you regardless to the values passed to the server, the authentication is done via ssh keys. how to do it? depends on your centeral repo – CodeWizard Mar 01 '16 at 10:03
  • 1
    i wrote you an example on how to get it on server side via the log commands – CodeWizard Mar 01 '16 at 10:04
1

Here I got the solution.

https://github.com/jakubgarfield/Bonobo-Git-Server/issues/494

We are using bonobo git server as a version control.

Surendra Reddy
  • 169
  • 2
  • 9
0

On the server side you can get the commit that is trying to be pushed with git cat-file commit SHA

That said, it has a HEADER that gives you such information. That may be wrong or my be tampered, but that is available on the server side.

Something like this would do. In the following code, keep an eye on the three relevant variables: $CATAUTHOREMAIL, $CATAUTHOR and $CATEMAIL.

# --- Command line arguments
refname="$1"
oldrev="$2"
newrev="$3"

echo
echo '*** Checking your push update...'

MISSREVS=`git rev-list ${oldrev}..${newrev}`
CATAUTHOREMAIL=""
CMTMSG=""
for RV in ${MISSREVS} ; do
    if [ -z "$CATAUTHOREMAIL" ] ; then
        CATAUTHOREMAIL=`git cat-file commit ${RV} | grep author`
    fi  
    CMTMSG="$CMTMSG "`git cat-file commit ${RV} | sed '1,/^$/d'`
done

REMSG="author (.*) <"
[[ $CATAUTHOREMAIL =~ $REMSG ]]
CATAUTHOR="${BASH_REMATCH[1]}"
REMSG="author.*<(.*)>.*"
[[ $CATAUTHOREMAIL =~ $REMSG ]]
CATEMAIL="${BASH_REMATCH[1]}"
echo "*** Last commit author = $CATAUTHOR"
echo "*** Last commit email = $CATEMAIL"

That is very useful. I wrote this answer inspired in the answer from @codewizard, because there it is only available for client side, not server side. And I needed "something" from server side. It is not fool-proof, but it is very useful.

  • If you analyse the commit header, you can grab more information; for example, you have also the "commiter's name" that is not necessarily the author of the commit.

  • The loop on the code above will iterate on all commits. You may want to get only the last (most recent) commit's author, like the code do with that if [ -z "$CATAUTHOREMAIL ], or you may want to save all of them in an array or something. That is up to you to change this template to your needs.

  • I used grep author, but it would break if in the very commit message the word author appears... So, you may want to find a better filter, for example, separate the header from the body of the commit; that is, the first blank line.

DrBeco
  • 9,819
  • 7
  • 52
  • 70