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