]> snippets.scripts.mit.edu Git - Scripts/git/.git/blame - __init__.py
Wrappers for safely calling commands in a new PAG
[Scripts/git/.git] / __init__.py
CommitLineData
20e2c5bc 1import os
aec307d9
AD
2import subprocess
3import ldap
4import ldap.filter
5
e2ce65b9
AD
6from django.contrib.auth.middleware import RemoteUserMiddleware
7from django.contrib.auth.backends import RemoteUserBackend
2e0bd8fa
AD
8from django.contrib.auth.views import login
9from django.contrib.auth import REDIRECT_FIELD_NAME
10from django.http import HttpResponseRedirect
e2ce65b9
AD
11from django.contrib import auth
12from django.core.exceptions import ObjectDoesNotExist
6650ee78
AD
13from django.core.validators import URLValidator, ValidationError
14
2e0bd8fa 15import settings
e2ce65b9 16
aec307d9
AD
17def zephyr(msg, clas='message', instance='log', rcpt='nobody',):
18 proc = subprocess.Popen(
19 ['zwrite', '-d', '-n', '-c', clas, '-i', instance, rcpt, ],
20 stdin=subprocess.PIPE, stdout=subprocess.PIPE
21 )
22 proc.communicate(msg)
e2ce65b9 23
6650ee78
AD
24def UrlOrAfsValidator(value):
25 if value.startswith('/mit/') or value.startswith('/afs/'):
26 return
27 else:
28 try:
29 URLValidator()(value)
30 except ValidationError:
31 raise ValidationError('Provide a valid URL or AFS path')
32
20e2c5bc
AD
33def pag_check_helper(fn, args, aklog=False, ccname=None, **kwargs):
34 if 'executable' in kwargs:
35 raise ValueError('"executable" not supported with pag_check_*')
36
37 env = None
38 if 'env' in kwargs:
39 env = kwargs['env']
40 del kwargs['env']
41 if ccname:
42 if env is not None:
43 env = dict(env)
44 else:
45 env = dict(os.environ)
46 env['KRB5CCNAME'] = ccname
47
48 pagsh_cmd = 'exec "$@"'
49 if aklog: pagsh_cmd = "aklog && " + pagsh_cmd
50 args = ['pagsh', '-c', pagsh_cmd, 'exec', ] + args
51
52 return fn(args, env=env, **kwargs)
53
54def pag_check_call(args, **kwargs):
55 return pag_check_helper(subprocess.check_call, args, **kwargs)
56def pag_check_output(args, **kwargs):
57 return pag_check_helper(subprocess.check_output, args, **kwargs)
58
e2ce65b9
AD
59class ScriptsRemoteUserMiddleware(RemoteUserMiddleware):
60 header = 'SSL_CLIENT_S_DN_Email'
61
62class ScriptsRemoteUserBackend(RemoteUserBackend):
63 def clean_username(self, username, ):
64 if '@' in username:
65 name, domain = username.split('@')
66 assert domain.upper() == 'MIT.EDU'
67 return name
68 else:
69 return username
70 def configure_user(self, user, ):
71 username = user.username
aec307d9 72 user.password = "ScriptsSSLAuth"
abab96a3 73 con = ldap.open('ldap-too.mit.edu')
e2ce65b9
AD
74 con.simple_bind_s("", "")
75 dn = "dc=mit,dc=edu"
76 fields = ['cn', 'sn', 'givenName', 'mail', ]
aec307d9
AD
77 userfilter = ldap.filter.filter_format('uid=%s', [username])
78 result = con.search_s('dc=mit,dc=edu', ldap.SCOPE_SUBTREE, userfilter, fields)
e2ce65b9
AD
79 if len(result) == 1:
80 user.first_name = result[0][1]['givenName'][0]
81 user.last_name = result[0][1]['sn'][0]
23bea0e4
GT
82 try:
83 user.email = result[0][1]['mail'][0]
84 except KeyError:
85 user.email = username + '@mit.edu'
e2ce65b9
AD
86 try:
87 user.groups.add(auth.models.Group.objects.get(name='mit'))
88 except ObjectDoesNotExist:
89 print "Failed to retrieve mit group"
aec307d9
AD
90 else:
91 raise ValueError, ("Could not find user with username '%s' (filter '%s')"%(username, userfilter))
e2ce65b9
AD
92 try:
93 user.groups.add(auth.models.Group.objects.get(name='autocreated'))
94 except ObjectDoesNotExist:
95 print "Failed to retrieve autocreated group"
aec307d9 96 user.save()
e2ce65b9 97 return user
2e0bd8fa 98
d4bd5af8
AD
99def get_or_create_mit_user(username, ):
100 """
101 Given an MIT username, return a Django user object for them.
102 If necessary, create (and save) the Django user for them.
103 If the MIT user doesn't exist, raises ValueError.
104 """
105 user, created = auth.models.User.objects.get_or_create(username=username, )
106 if created:
107 backend = ScriptsRemoteUserBackend()
108 # Raises ValueError if the user doesn't exist
109 try:
110 return backend.configure_user(user), created
111 except ValueError:
112 user.delete()
113 raise
114 else:
115 return user, created
116
2e0bd8fa 117def scripts_login(request, **kwargs):
4df1aef4
AD
118 host = request.META['HTTP_HOST'].split(':')[0]
119 if host == 'localhost':
2e0bd8fa
AD
120 return login(request, **kwargs)
121 elif request.META['SERVER_PORT'] == '444':
122 if request.user.is_authenticated():
123 # They're already authenticated --- go ahead and redirect
124 if 'redirect_field_name' in kwargs:
125 redirect_field_name = kwargs['redirect_field_names']
126 else:
127 from django.contrib.auth import REDIRECT_FIELD_NAME
128 redirect_field_name = REDIRECT_FIELD_NAME
129 redirect_to = request.REQUEST.get(redirect_field_name, '')
130 if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
131 redirect_to = settings.LOGIN_REDIRECT_URL
132 return HttpResponseRedirect(redirect_to)
133 else:
134 return login(request, **kwargs)
135 else:
136 # Move to port 444
2e0bd8fa
AD
137 redirect_to = "https://%s:444%s" % (host, request.META['REQUEST_URI'], )
138 return HttpResponseRedirect(redirect_to)