-
Notifications
You must be signed in to change notification settings - Fork 1
/
glgl-http-auth
executable file
·92 lines (81 loc) · 3.66 KB
/
glgl-http-auth
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python
# glglHttpAuth - HTTP Basic Authentication wrapper for GitLab 2.0/2.1 + gitolite
# Copyright (c) 2012 Nobuo OKAZAKI
### --- Modify for your environment --- ###
AUTH_METHOD = "bcrypt" # set auth method 'bcrypt'(default) or 'http'
GITLAB_BASEURL = "http://gitlab.foo.com" # set GitLab base URL
GITLAB_DB = "/home/git/gitlabhq/db/production.sqlite3" # set GitLab database file
GITOLITE_ENV = {
"GIT_PROJECT_ROOT" : "/home/git/repositories", # repository path
"GITOLITE_HTTP_HOME" : "/home/git", # gitolite home contains gitolite's bin scripts
"GIT_HTTP_BACKEND" : "/usr/libexec/git-core/git-http-backend", # git smart http cgi
"GIT_HTTP_EXPORT_ALL" : "TRUE", # NEED NOT MODIFY
}
### ----------------------------------- ###
import os, sys
import urllib, urllib2, cookielib
import sqlite3
from xml.dom.minidom import parse
def check_password(environ, user, password):
"""handler for WSGIAuthUserScript"""
if AUTH_METHOD == "http": return auth_gitlab(GITLAB_BASEURL, user, password)
return auth_gitlab_with_bcrypt(user, password)
def auth_gitlab_with_bcrypt(email, password):
"""authentication with GitLab database
If you use bcrypt in devise (default), this way is so reasonable than latter.
"""
import bcrypt
conn = sqlite3.connect(GITLAB_DB)
cur = conn.cursor()
cur.execute("SELECT encrypted_password FROM users WHERE email = ?", [email])
enc_pw = cur.fetchone()[0]
return (bcrypt.hashpw(password, enc_pw) == enc_pw)
def auth_gitlab(baseurl, email, password):
"""authentication with GitLab Web Interface
There may be more efficient way, but I have any idea, so I have never used Rails.
"""
# create CookieJar
cookie_handler = urllib2.HTTPCookieProcessor(cookielib.CookieJar())
opener = urllib2.build_opener(cookie_handler)
# open the GitLab login web page and parse
res = opener.open("%s/users/sign_in" % baseurl)
dom = parse(res)
form = {
"commit": "Sign in",
"user[email]": email,
"user[password]": password,
"user[remember_me]": 0,
"utf8": "✓",
}
for el in dom.getElementsByTagName("input"):
if el.getAttribute("name") == "authenticity_token":
form["authenticity_token"] = el.getAttribute("value")
break
# send login information to GitLab and check result
res = opener.open("%s/users/sign_in" % baseurl, urllib.urlencode(form))
try: dom = parse(res)
except: return False
for el in dom.getElementsByTagName("input"):
if el.getAttribute("name") == "user[email]": return False
form = {"_method":"delete", "authenticity_token":form["authenticity_token"]}
# logout if login was success
f = opener.open("%s/users/sign_out" % baseurl, urllib.urlencode(form))
return True
# wrapper for gl-auth-command of gitolite
if __name__ == "__main__":
import subprocess
conn = sqlite3.connect(GITLAB_DB)
cur = conn.cursor()
cur.execute("SELECT identifier FROM users LEFT JOIN keys ON users.id = user_id WHERE email = ? ORDER BY keys.id LIMIT 1", (os.environ["REMOTE_USER"],));
# sys.stderr.write("email:%s, " % os.environ["REMOTE_USER"])
os.environ["REMOTE_USER"] = cur.fetchone()[0]
# sys.stderr.write("gitolite:%s\n" % os.environ["REMOTE_USER"])
for k in GITOLITE_ENV.keys(): os.environ[k] = GITOLITE_ENV[k]
subprocess.check_call("%s/bin/gl-auth-command" % GITOLITE_ENV["GITOLITE_HTTP_HOME"])
# History
# * Sat Feb 11 2012 Nobuo Okazaki
# - add auth_gitlab_with_bcrypt()
# authenticate with accessing GitLab DB
#
# * Sun Jan 15 2012 Nobuo Okazaki
# - initial script