summaryrefslogtreecommitdiff
path: root/meetingtools/apps/auth
diff options
context:
space:
mode:
authorLeif Johansson <leifj@sunet.se>2012-10-04 15:39:08 +0200
committerLeif Johansson <leifj@sunet.se>2012-10-04 15:39:08 +0200
commit2bdad0ae7a3a6e4ec5116becd39910388b679ed2 (patch)
tree5afdfba0a93c1af50d53bdc245d57cc4053e109a /meetingtools/apps/auth
parent873e7823970352d591deee5f67f47c5436ee0e84 (diff)
restructure
Diffstat (limited to 'meetingtools/apps/auth')
-rw-r--r--meetingtools/apps/auth/__init__.py79
-rw-r--r--meetingtools/apps/auth/utils.py19
-rw-r--r--meetingtools/apps/auth/views.py169
3 files changed, 267 insertions, 0 deletions
diff --git a/meetingtools/apps/auth/__init__.py b/meetingtools/apps/auth/__init__.py
new file mode 100644
index 0000000..e69cc29
--- /dev/null
+++ b/meetingtools/apps/auth/__init__.py
@@ -0,0 +1,79 @@
+__author__ = 'leifj'
+
+from django.conf import settings
+from saml2.config import SPConfig
+import copy
+from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT
+
+import logging
+logging.basicConfig()
+logger = logging.getLogger("djangosaml2")
+logger.setLevel(logging.DEBUG)
+
+def asgard_sp_config(request=None):
+ host = "localhost"
+ if request is not None:
+ host = request.get_host().replace(":","-")
+ x= {
+ # your entity id, usually your subdomain plus the url to the metadata view
+ 'entityid': 'https://%s/saml2/sp/metadata' % host,
+ # directory with attribute mapping
+ "attribute_map_dir" : "%s/saml2/attributemaps" % settings.BASE_DIR,
+ # this block states what services we provide
+ 'service': {
+ # we are just a lonely SP
+ 'sp' : {
+ 'name': 'meetingtools',
+ 'endpoints': {
+ # url and binding to the assertion consumer service view
+ # do not change the binding osettingsr service name
+ 'assertion_consumer_service': [
+ ('https://%s/saml2/sp/acs/' % host,
+ BINDING_HTTP_POST),
+ ],
+ # url and binding to the single logout service view
+ # do not change the binding or service name
+ 'single_logout_service': [
+ ('https://%s/saml2/sp/ls/' % host,
+ BINDING_HTTP_REDIRECT),
+ ],
+ },
+ # attributes that this project need to identify a user
+ 'required_attributes': ['eduPersonPrincipalName','displayName','eduPersonScopedAffiliation'],
+ }
+ },
+
+ # where the remote metadata is stored
+ #'metadata': { 'remote': [{'url':'http://md.swamid.se/md/swamid-idp.xml',
+ # 'cert':'%s/saml2/credentials/md-signer.crt' % settings.BASE_DIR}] },
+ 'metadata': {'local': [settings.SAML_METADATA_FILE]},
+
+ # set to 1 to output debugging information
+ 'debug': 1,
+
+ # certificate
+ "key_file" : "%s/%s.key" % (settings.SSL_KEY_DIR,host),
+ "cert_file" : "%s/%s.crt" % (settings.SSL_CRT_DIR,host),
+ # own metadata settings
+ 'contact_person': [
+ {'given_name': 'Leif',
+ 'sur_name': 'Johansson',
+ 'company': 'NORDUnet',
+ 'email_address': 'leifj@nordu.net',
+ 'contact_type': 'technical'},
+ {'given_name': 'Johan',
+ 'sur_name': 'Berggren',
+ 'company': 'NORDUnet',
+ 'email_address': 'jbn@nordu.net',
+ 'contact_type': 'technical'},
+ ],
+ # you can set multilanguage information here
+ 'organization': {
+ 'name': [('NORDUNet', 'en')],
+ 'display_name': [('NORDUnet A/S', 'en')],
+ 'url': [('http://www.nordu.net', 'en')],
+ }
+ }
+ c = SPConfig()
+ c.load(copy.deepcopy(x))
+ return c
diff --git a/meetingtools/apps/auth/utils.py b/meetingtools/apps/auth/utils.py
new file mode 100644
index 0000000..1a0174c
--- /dev/null
+++ b/meetingtools/apps/auth/utils.py
@@ -0,0 +1,19 @@
+'''
+Created on Jul 7, 2010
+
+@author: leifj
+'''
+from uuid import uuid4
+
+def nonce():
+ return uuid4().hex
+
+def anonid():
+ return uuid4().urn
+
+def groups(request):
+ groups = []
+ if request.user.is_authenticated():
+ groups = request.user.groups
+
+ return groups \ No newline at end of file
diff --git a/meetingtools/apps/auth/views.py b/meetingtools/apps/auth/views.py
new file mode 100644
index 0000000..ee23df3
--- /dev/null
+++ b/meetingtools/apps/auth/views.py
@@ -0,0 +1,169 @@
+'''
+Created on Jul 5, 2010
+
+@author: leifj
+'''
+from django.http import HttpResponseRedirect
+from django.contrib.auth.models import User, Group
+import datetime
+from django.views.decorators.cache import never_cache
+import logging
+from meetingtools.apps.userprofile.models import UserProfile
+from meetingtools.multiresponse import redirect_to, make_response_dict
+from meetingtools.ac import ac_api_client
+from django.shortcuts import render_to_response
+from django.contrib import auth
+from django_co_connector.models import co_import_from_request, add_member,remove_member
+from meetingtools.apps.cluster.models import acc_for_user
+from django.conf import settings
+
+def meta(request,attr):
+ v = request.META.get(attr)
+ if not v:
+ return None
+ values = filter(lambda x: x != "(null)",v.split(";"))
+ return values;
+
+def meta1(request,attr):
+ v = meta(request,attr)
+ if v:
+ return str(v[0]).decode('utf-8')
+ else:
+ return None
+
+def _localpart(a):
+ if hasattr(a,'name'):
+ a = a.name
+ if '@' in a:
+ (lp,dp) = a.split('@')
+ a = lp
+ return a
+
+def _is_member_or_employee_old(affiliations):
+ lpa = map(_localpart,affiliations)
+ return 'student' in lpa or 'staff' in lpa or ('member' in lpa and not 'student' in lpa)
+
+def _is_member_or_employee(user):
+ lpa = map(_localpart,user.groups.all())
+ return 'student' in lpa or 'staff' in lpa or ('member' in lpa and not 'student' in lpa)
+
+@never_cache
+def logout(request):
+ auth.logout(request)
+ return HttpResponseRedirect('/Shibboleth.sso/Logout')
+
+@never_cache
+def login(request):
+ return render_to_response('apps/auth/login.html',make_response_dict(request,{'next': request.REQUEST.get("next")}));
+
+def join_group(group,**kwargs):
+ user = kwargs['user']
+ acc = acc_for_user(user)
+ with ac_api_client(acc) as api:
+ principal = api.find_principal("login", user.username, "user")
+ if principal:
+ gp = api.find_group(group.name)
+ if gp:
+ api.add_member(principal.get('principal-id'),gp.get('principal-id'))
+
+def leave_group(group,**kwargs):
+ user = kwargs['user']
+ acc = acc_for_user(user)
+ with ac_api_client(acc) as api:
+ principal = api.find_principal("login", user.username, "user")
+ if principal:
+ gp = api.find_group(group.name)
+ if gp:
+ api.remove_member(principal.get('principal-id'),gp.get('principal-id'))
+
+add_member.connect(join_group,sender=Group)
+remove_member.connect(leave_group,sender=Group)
+
+def accounts_login_federated(request):
+ if request.user.is_authenticated():
+ profile,created = UserProfile.objects.get_or_create(user=request.user)
+ if created:
+ profile.identifier = request.user.username
+ profile.user = request.user
+ profile.save()
+
+ update = False
+ fn = meta1(request,'givenName')
+ ln = meta1(request,'sn')
+ cn = meta1(request,'cn')
+ if not cn:
+ cn = meta1(request,'displayName')
+ logging.debug("cn=%s" % cn)
+ if not cn and fn and ln:
+ cn = "%s %s" % (fn,ln)
+ if not cn:
+ cn = profile.identifier
+
+ mail = meta1(request,'mail')
+
+ idp = meta1(request,'Shib-Identity-Provider')
+
+ for attrib_name, meta_value in (('display_name',cn),('email',mail),('idp',idp)):
+ attrib_value = getattr(profile, attrib_name)
+ if meta_value and not attrib_value:
+ setattr(profile,attrib_name,meta_value)
+ update = True
+
+ if request.user.password == "":
+ request.user.password = "(not used for federated logins)"
+ update = True
+
+ if update:
+ request.user.save()
+
+ # Allow auto_now to kick in for the lastupdated field
+ #profile.lastupdated = datetime.datetime.now()
+ profile.save()
+
+ next = request.session.get("after_login_redirect", None)
+ if not next and request.GET.has_key('next'):
+ next = request.GET['next']
+ else:
+ next = settings.DEFAULT_URL
+
+ acc = acc_for_user(request.user)
+ with ac_api_client(request) as api:
+ # make sure the principal is created before shooting off
+ principal = api.find_or_create_principal("login", request.user.username, "user",
+ {'type': "user",
+ 'has-children': "0",
+ 'first-name':fn,
+ 'last-name':ln,
+ 'email':mail,
+ 'send-email': 0,
+ 'login':request.user.username,
+ 'ext-login':request.user.username})
+
+
+
+ co_import_from_request(request)
+
+ member_or_employee = _is_member_or_employee(request.user)
+ for gn in ('live-admins','seminar-admins'):
+ group = api.find_builtin(gn)
+ if group:
+ api.add_remove_member(principal.get('principal-id'),group.get('principal-id'),member_or_employee)
+
+ #(lp,domain) = uid.split('@')
+ #for a in ('student','employee','member'):
+ # affiliation = "%s@%s" % (a,domain)
+ # group = connect_api.find_or_create_principal('name',affiliation,'group',{'type': 'group','has-children':'1','name': affiliation})
+ # member = affiliation in affiliations
+ # connect_api.add_remove_member(principal.get('principal-id'),group.get('principal-id'),member)
+
+ #for e in epe:
+ # group = connect_api.find_or_create_principal('name',e,'group',{'type': 'group','has-children':'1','name': e})
+ # if group:
+ # connect_api.add_remove_member(principal.get('principal-id'),group.get('principal-id'),True)
+
+ if next is not None:
+ return redirect_to(next)
+ else:
+ pass
+
+ return redirect_to(settings.LOGIN_URL)