7 from django.contrib.auth.backends import RemoteUserBackend
8 from django.contrib.auth.middleware import RemoteUserMiddleware
9 from django.contrib.auth.views import login
10 from django.contrib.auth import REDIRECT_FIELD_NAME
11 from django.http import HttpResponseRedirect
12 from django.contrib import auth
13 from django.core.exceptions import ObjectDoesNotExist
14 from django.core.validators import URLValidator, ValidationError
16 from django.conf import settings
18 def zephyr(msg, clas='message', instance='log', rcpt='nobody',):
19 proc = subprocess.Popen(
20 ['zwrite', '-d', '-n', '-c', clas, '-i', instance, rcpt, ],
21 stdin=subprocess.PIPE, stdout=subprocess.PIPE
25 def UrlOrAfsValidator(value):
26 if value.startswith('/mit/') or value.startswith('/afs/'):
31 except ValidationError:
32 raise ValidationError('Provide a valid URL or AFS path')
34 def pag_check_helper(fn, args, aklog=False, ccname=None, **kwargs):
35 if 'executable' in kwargs:
36 raise ValueError('"executable" not supported with pag_check_*')
46 env = dict(os.environ)
47 env['KRB5CCNAME'] = ccname
49 pagsh_cmd = 'exec "$@"'
50 if aklog: pagsh_cmd = "aklog && " + pagsh_cmd
51 args = ['pagsh', '-c', pagsh_cmd, 'exec', ] + args
53 return fn(args, env=env, **kwargs)
55 def pag_check_call(args, **kwargs):
56 return pag_check_helper(subprocess.check_call, args, **kwargs)
57 def pag_check_output(args, **kwargs):
58 return pag_check_helper(subprocess.check_output, args, **kwargs)
60 def kinit(keytab=None, principal=None, autodelete=True, ):
62 keytab = settings.KRB_KEYTAB
64 principal = settings.KRB_PRINCIPAL
65 assert keytab and principal
66 fd = tempfile.NamedTemporaryFile(mode='rb', prefix="krb5cc_djmit_", delete=autodelete, )
67 env = dict(KRB5CCNAME=fd.name)
68 kinit_cmd = ['kinit', '-k', '-t', keytab, principal, ]
69 subprocess.check_call(kinit_cmd, env=env)
72 class ScriptsRemoteUserMiddleware(RemoteUserMiddleware):
73 header = 'SSL_CLIENT_S_DN_Email'
75 class ScriptsRemoteUserBackend(RemoteUserBackend):
76 def clean_username(self, username, ):
78 name, domain = username.split('@')
79 assert domain.upper() == 'MIT.EDU'
83 def configure_user(self, user, ):
84 username = user.username
85 user.set_unusable_password()
86 con = ldap.open('ldap-too.mit.edu')
87 con.simple_bind_s("", "")
89 fields = ['cn', 'sn', 'givenName', 'mail', ]
90 userfilter = ldap.filter.filter_format('uid=%s', [username])
91 result = con.search_s('dc=mit,dc=edu', ldap.SCOPE_SUBTREE, userfilter, fields)
93 user.first_name = result[0][1]['givenName'][0]
94 user.last_name = result[0][1]['sn'][0]
96 user.email = result[0][1]['mail'][0]
98 user.email = username + '@mit.edu'
100 user.groups.add(auth.models.Group.objects.get(name='mit'))
101 except ObjectDoesNotExist:
102 print "Failed to retrieve mit group"
104 raise ValueError, ("Could not find user with username '%s' (filter '%s')"%(username, userfilter))
106 user.groups.add(auth.models.Group.objects.get(name='autocreated'))
107 except ObjectDoesNotExist:
108 print "Failed to retrieve autocreated group"
112 def get_or_create_mit_user(username, ):
114 Given an MIT username, return a Django user object for them.
115 If necessary, create (and save) the Django user for them.
116 If the MIT user doesn't exist, raises ValueError.
118 user, created = auth.models.User.objects.get_or_create(username=username, )
120 backend = ScriptsRemoteUserBackend()
121 # Raises ValueError if the user doesn't exist
123 return backend.configure_user(user), created
130 def scripts_login(request, **kwargs):
131 host = request.META['HTTP_HOST'].split(':')[0]
132 if host in ('localhost', '127.0.0.1'):
133 return login(request, **kwargs)
134 elif request.META['SERVER_PORT'] == '444':
135 if request.user.is_authenticated():
136 # They're already authenticated --- go ahead and redirect
137 if 'redirect_field_name' in kwargs:
138 redirect_field_name = kwargs['redirect_field_names']
140 from django.contrib.auth import REDIRECT_FIELD_NAME
141 redirect_field_name = REDIRECT_FIELD_NAME
142 redirect_to = request.REQUEST.get(redirect_field_name, '')
143 if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
144 redirect_to = settings.LOGIN_REDIRECT_URL
145 return HttpResponseRedirect(redirect_to)
147 return login(request, **kwargs)
150 redirect_to = "https://%s:444%s" % (host, request.META['REQUEST_URI'], )
151 return HttpResponseRedirect(redirect_to)