7 from django.contrib.auth.backends import RemoteUserBackend
8 from django.contrib.auth.hashers import UNUSABLE_PASSWORD
9 from django.contrib.auth.middleware import RemoteUserMiddleware
10 from django.contrib.auth.views import login
11 from django.contrib.auth import REDIRECT_FIELD_NAME
12 from django.http import HttpResponseRedirect
13 from django.contrib import auth
14 from django.core.exceptions import ObjectDoesNotExist
15 from django.core.validators import URLValidator, ValidationError
17 from django.conf import settings
19 def 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
26 def UrlOrAfsValidator(value):
27 if value.startswith('/mit/') or value.startswith('/afs/'):
32 except ValidationError:
33 raise ValidationError('Provide a valid URL or AFS path')
35 def pag_check_helper(fn, args, aklog=False, ccname=None, **kwargs):
36 if 'executable' in kwargs:
37 raise ValueError('"executable" not supported with pag_check_*')
47 env = dict(os.environ)
48 env['KRB5CCNAME'] = ccname
50 pagsh_cmd = 'exec "$@"'
51 if aklog: pagsh_cmd = "aklog && " + pagsh_cmd
52 args = ['pagsh', '-c', pagsh_cmd, 'exec', ] + args
54 return fn(args, env=env, **kwargs)
56 def pag_check_call(args, **kwargs):
57 return pag_check_helper(subprocess.check_call, args, **kwargs)
58 def pag_check_output(args, **kwargs):
59 return pag_check_helper(subprocess.check_output, args, **kwargs)
61 def kinit(keytab=None, principal=None, autodelete=True, ):
63 keytab = settings.KRB_KEYTAB
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)
73 class ScriptsRemoteUserMiddleware(RemoteUserMiddleware):
74 header = 'SSL_CLIENT_S_DN_Email'
76 class ScriptsRemoteUserBackend(RemoteUserBackend):
77 def clean_username(self, username, ):
79 name, domain = username.split('@')
80 assert domain.upper() == 'MIT.EDU'
84 def configure_user(self, user, ):
85 username = user.username
86 user.password = UNUSABLE_PASSWORD
87 con = ldap.open('ldap-too.mit.edu')
88 con.simple_bind_s("", "")
90 fields = ['cn', 'sn', 'givenName', 'mail', ]
91 userfilter = ldap.filter.filter_format('uid=%s', [username])
92 result = con.search_s('dc=mit,dc=edu', ldap.SCOPE_SUBTREE, userfilter, fields)
94 user.first_name = result[0][1]['givenName'][0]
95 user.last_name = result[0][1]['sn'][0]
97 user.email = result[0][1]['mail'][0]
99 user.email = username + '@mit.edu'
101 user.groups.add(auth.models.Group.objects.get(name='mit'))
102 except ObjectDoesNotExist:
103 print "Failed to retrieve mit group"
105 raise ValueError, ("Could not find user with username '%s' (filter '%s')"%(username, userfilter))
107 user.groups.add(auth.models.Group.objects.get(name='autocreated'))
108 except ObjectDoesNotExist:
109 print "Failed to retrieve autocreated group"
113 def get_or_create_mit_user(username, ):
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.
119 user, created = auth.models.User.objects.get_or_create(username=username, )
121 backend = ScriptsRemoteUserBackend()
122 # Raises ValueError if the user doesn't exist
124 return backend.configure_user(user), created
131 def scripts_login(request, **kwargs):
132 host = request.META['HTTP_HOST'].split(':')[0]
133 if host == 'localhost':
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']
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)
148 return login(request, **kwargs)
151 redirect_to = "https://%s:444%s" % (host, request.META['REQUEST_URI'], )
152 return HttpResponseRedirect(redirect_to)