-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscigit-shell
executable file
·67 lines (56 loc) · 1.88 KB
/
scigit-shell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/python2.7
import os, sys
import re
import subprocess
import MySQLdb
import scigitconfig as cfg
def error(msg):
sys.stderr.write("scigit: %s\n" % msg)
sys.exit(1)
dbc = MySQLdb.connect(user=cfg.user, passwd=cfg.passwd, db=cfg.db)
if len(sys.argv) != 3:
error('invalid arguments')
user = sys.argv[1]
match = re.search('^u([0-9]+)$', user)
if match == None:
error('invalid user')
userid = int(match.group(1))
if userid != 0:
pkeyid = int(sys.argv[2])
cursor = dbc.cursor()
cursor.execute("""SELECT id FROM user_public_keys
WHERE id = %s AND user_id = %s AND enabled = 1""", (pkeyid, userid))
if cursor.fetchone() == None:
error('Permission denied (publickey)')
soc = os.getenv('SSH_ORIGINAL_COMMAND')
if soc == None:
error("Shell access is not supported")
git_commands = 'git-upload-pack|git-receive-pack|git-upload-archive'
match = re.search("^(%s) '(.*?)(\.git)?'$" % git_commands, soc)
if match == None:
error("Invalid git command")
verb = match.group(1)
repo = match.group(2)
match = re.search('^r([0-9]+)$', repo)
if match == None:
error("Invalid repository")
repoid = match.group(1)
if userid != 0:
cursor = dbc.cursor()
cursor.execute("SELECT public FROM projects WHERE id = %s", (repoid))
project = cursor.fetchone()
if project == None:
error('repository does not exist')
public = project[0] != 0
cursor = dbc.cursor()
cursor.execute("""SELECT permission FROM project_permissions
WHERE project_id = %s AND user_id = %s""", (repoid, userid))
result = cursor.fetchone()
write = verb.find('upload') == -1
# 1 = subscriber, 2 = coauthor, 3 = owner
can_write = (result != None and result >= 2)
if write and not can_write or \
(result == None and not public):
error('not authorized (or wrong repository)')
os.environ['SCIGIT_USER_ID'] = str(userid)
subprocess.call(["/usr/bin/git", "shell", "-c", "%s 'repositories/%s'" % (verb, repo)])