+ if request.user.is_authenticated():
+ auth_logout(request)
+ if url and auto_redirect:
+ return HttpResponseRedirect(url)
+ return render_to_response(template_name, {'url': url}, \
+ context_instance=RequestContext(request))
+
+
+def service_validate(request):
+ """Validate ticket via CAS v.2 protocol"""
+ service = request.GET.get('service', None)
+ ticket_string = request.GET.get('ticket', None)
+ if service is None or ticket_string is None:
+ return _cas2_error_response(INVALID_REQUEST)
+
+ try:
+ ticket = ServiceTicket.objects.get(ticket=ticket_string)
+ except ServiceTicket.DoesNotExist:
+ return _cas2_error_response(INVALID_TICKET)
+
+ if ticket.service != service:
+ ticket.delete()
+ return _cas2_error_response(INVALID_SERVICE)
+
+ user = ticket.user
+ ticket.delete()
+ return _cas2_sucess_response(user)
+
+
+def _cas2_error_response(code):
+ return HttpResponse(u''''<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
+ <cas:authenticationFailure code="%(code)s">
+ %(message)s
+ </cas:authenticationFailure>
+ </cas:serviceResponse>''' % {
+ 'code': code,
+ 'message': dict(ERROR_MESSAGES).get(code)
+ }, mimetype='text/xml')
+
+
+def _cas2_sucess_response(user):
+ return HttpResponse(auth_success_response(user), mimetype='text/xml')
+
+
+def auth_success_response(user):
+ from attribute_formatters import CAS, NSMAP, etree
+
+ response = etree.Element(CAS + 'serviceResponse', nsmap=NSMAP)
+ auth_success = etree.SubElement(response, CAS + 'authenticationSuccess')
+ username = etree.SubElement(auth_success, CAS + 'user')
+ username.text = user.username
+
+ if settings.CAS_CUSTOM_ATTRIBUTES_CALLBACK:
+ callback = get_callable(settings.CAS_CUSTOM_ATTRIBUTES_CALLBACK)
+ attrs = callback(user)
+ if len(attrs) > 0:
+ formater = get_callable(settings.CAS_CUSTOM_ATTRIBUTES_FORMATER)
+ formater(auth_success, attrs)
+ return unicode(etree.tostring(response, encoding='utf-8'), 'utf-8')