def index(request): consumer_url = util.getViewURL( request, 'consumer.views.startOpenID') server_url = util.getViewURL(request, 'server.views.server') return direct_to_template( request, 'index.html', {'consumer_url':consumer_url, 'server_url':server_url})
def renderIndexPage(request, **template_args): template_args['ns'] = SERVICE_NS template_args['sreg'] = SREG_ATTRIBUTES template_args['ax'] = AX_ATTRIBUTES template_args['consumer_url'] = util.getViewURL(request, startOpenID) template_args['pape_policies'] = POLICY_PAIRS response = direct_to_template( request, 'login.html', template_args) response[YADIS_HEADER_NAME] = util.getViewURL(request, rpXRDS) return response
def rpXRDS(request): """ Return a relying party verification XRDS document """ return util.renderXRDS( request, [RP_RETURN_TO_URL_TYPE], [util.getViewURL(request, finishOpenID)])
def server(request): """Respond to requests for the server's primary web page. """ return direct_to_template( request, 'server/index.html', {'user_url': reverse("idpage"), 'server_xrds_url': util.getViewURL(request, "idpXrds"), },context_instance=RequestContext(request))
def openid_chalange(request): if request.user.is_authenticated(): return HttpResponseRedirect("/") class OpenidForm(Form): openid = CharField(required=True, max_length=32) def clean_openid(self): openid = self.cleaned_data['openid'] import re p = re.compile('^[a-zA-Z._-]+$') if not p.match(openid): raise ValidationError(_("Invalid openid string.")) form = None if (request.POST): form = OpenidForm(request.POST) if form.is_valid(): store = getOpenIDStore("/tmp/taverna_openid", "c_") c = consumer.Consumer(request.session, store) openid_url = request.POST['openid'] # Google ... if openid_url == "google": openid_url = 'https://www.google.com/accounts/o8/id' try: auth_request = c.begin(openid_url) except consumer.DiscoveryFailure, exc: error = "OpenID discovery error: %s" % str(exc) return {'form': form, 'error': error} trust_root = getViewURL(request, openid_chalange) redirect_to = getViewURL(request, openid_finish) return HttpResponseRedirect( auth_request.redirectURL(trust_root, redirect_to) )
def processTrustResult(request): """ Handle the result of a trust decision and respond to the RP accordingly. """ # Get the request from the session so we can construct the # appropriate response. openid_request = util.getRequest(request) # Respond with correct identity id = openid_request.identity home_url = util.getViewURL(request, "home") # If the decision was to allow the verification, respond # accordingly. allowed = 'allow' in request.POST or 'alwaystrust' in request.POST # Choose identity to answer with # # If no identity given by user choose the first try : userid = request.POST['identity'] except KeyError: if openid_request.idSelect(): userid = Identity.objects.filter(userprofile__user=request.user, is_active=True)[0].userid else: # Does user have this identity? try : Identity.objects.get(userprofile__user=request.user, userid=userid, is_active=True) except Identity.DoesNotExist: # Hey ! User try to stolen other identity... allowed = False # Double check if user give right identity if not openid_request.idSelect(): # Id requested http://domain.tld/userid from urlparse import urlparse parsed_id = urlparse(id)[2].strip('/') if parsed_id != userid: # User want to answer with a non requested id allowed = False # Does we always trust this consumer for this identity? alwaystrust = 'alwaystrust' in request.POST and allowed openid_response = generate_response(request, allowed, openid_request, userid, alwaystrust) return displayResponse(request, openid_response)
def generate_response(request, allow, openid_request, userid, alwaystrust=False, send_sreg=True): """Generate openid response and history """ # Get identity url response_identity = util.getViewURL(request, 'ident', kwargs={'userid' : userid}) if not openid_request.identity.endswith("/") or openid_request.idSelect(): response_identity = response_identity.rstrip("/") # What is the identity? user_id = Identity.objects.get(userid=userid) # Generate a response with the appropriate answer. openid_response = openid_request.answer(allow, identity=response_identity) if allow: if send_sreg: # Send Simple Registration data in the response, if appropriate. sreg_data = user_id.getsreg() # Get requested fields sreg_req = sreg.SRegRequest.fromOpenIDRequest(openid_request) # fill fields sreg_resp = sreg.SRegResponse.extractResponse(sreg_req, sreg_data) openid_response.addExtension(sreg_resp) # Does we retain this consumer? if alwaystrust: trust = TrustedConsumers(host=openid_request.trust_root, user=request.user, identity=user_id, always=True) trust.save() # Save this response from account.models import RPHistory ip = request.META["REMOTE_ADDR"] rphist = RPHistory(identity=user_id, host=openid_request.trust_root, auth_result=allow, ip=ip) rphist.save() return openid_response
def openid_finish(request): if request.user.is_authenticated(): return HttpResponseRedirect("/") form = None error = None request_args = request.GET store = getOpenIDStore("/tmp/taverna_openid", "c_") c = consumer.Consumer(request.session, store) return_to = getViewURL(request, openid_finish) response = c.complete(request_args, return_to) if response.status == consumer.SUCCESS: openid_hash=sha512(response.getDisplayIdentifier()).hexdigest() sreg_response = sreg.SRegResponse.fromSuccessResponse(response) try: profile = Profile.objects.get(openid_hash=openid_hash) username = profile.user.username user = authenticate(username=username) if user is not None: login(request, user) return HttpResponseRedirect("/") except Profile.DoesNotExist: user = User( username=openid_hash[:30], is_staff=False, is_active=True, is_superuser=False ) user.save() profile = Profile( user=user, photo="", openid=response.getDisplayIdentifier(), openid_hash=openid_hash, karma=settings.START_RATING, force=settings.START_RATING ) profile.save() try: blog = Blog.objects.get(owner=user) except Blog.DoesNotExist: blog = Blog(owner=user, name=openid_hash[:30]) blog.save() auth = authenticate(username=user.username) if user is not None: login(request, auth) return HttpResponseRedirect( reverse("userauth.views.profile_edit") ) else: error = "Verification of %s failed: %s" % ( response.getDisplayIdentifier(), response.message ) return {'from': form, 'error': error}
def idpXrds(request): """Respond to requests for the IDP's XRDS document, which is used in IDP-driven identifier selection. """ return util.renderXRDS( request, [OPENID_IDP_2_0_TYPE], [util.getViewURL(request, "endpoint")])
def handleCheckIDRequest(request, openid_request): """Handle checkid_* requests. Checks : - Existing userid is requested by consumer - This userid is an user's userid - Does user allow direct auth? - Is it an direct-access auth? """ direct_auth = False userid = '' # Consumer can send an idselect request to let # user choose his identity in server. # But if it no do it, we use provided identity. if not openid_request.idSelect(): # Get homepage full uri home_url = util.getViewURL(request, 'home') # Parse IDP (http://domain.tld/ident <- ident) from urlparse import urlparse userid = urlparse(openid_request.identity)[2].strip('/') # If isn't user's identity, return error response !NOTEST! try: Identity.objects.get(userprofile__user=request.user, userid=userid, is_active=True) except Identity.DoesNotExist: # Return an error response error_response = ProtocolError( openid_request.message, "%s is not user's identity" % (openid_request.identity,)) return displayResponse(request, error_response) if len(userid) != 0: # Consumer give to us an userid id_url = util.getViewURL(request, 'ident', kwargs={'userid':userid}) if not openid_request.identity.endswith("/"): id_url = id_url.rstrip("/") else: id_url = '' # Confirm that this server can actually vouch for that # identifier # test : # - homepage for v2 like auth # - identity if not openid_request.identity in (home_url, id_url): # Return an error response error_response = ProtocolError( openid_request.message, "This server cannot verify the URL %r" % (openid_request.identity,)) return displayResponse(request, error_response) # Ok for a Direct auth ? # User can accept authentications for an host with an id without # confirmation if he trust it try : if userid: trust = TrustedConsumers.objects.get(host=openid_request.trust_root, user=request.user, identity__userid=userid, always=True) else: trust = TrustedConsumers.objects.get(host=openid_request.trust_root, user=request.user, always=True) except TrustedConsumers.DoesNotExist: direct_auth = False else: direct_auth = True # Now make a decision if direct_auth: # If we have direct address and trust association # lets allow auth ### userid = trust.identity.userid openid_response = generate_response(request, True, openid_request, userid, send_sreg=False) return displayResponse(request, openid_response) elif openid_request.immediate and not direct_auth: # If we have an direct address but no trust association, # cancel auth ### openid_response = openid_request.answer(False) return displayResponse(request, openid_response) else: # Store the incoming request object in the session so we can # get to it later. util.setRequest(request, openid_request) return showDecidePage(request, openid_request, userid)
def finishOpenID(request): """ Finish the OpenID authentication process. Invoke the OpenID library with the response from the OpenID server and render a page detailing the result. """ result = {} # Because the object containing the query parameters is a # MultiValueDict and the OpenID library doesn't allow that, we'll # convert it to a normal dict. # OpenID 2 can send arguments as either POST body or GET query # parameters. request_args = util.normalDict(request.GET) if request.method == 'POST': request_args.update(util.normalDict(request.POST)) if request_args: c = getConsumer(request) # Get a response object indicating the result of the OpenID # protocol. return_to = util.getViewURL(request, finishOpenID) response = c.complete(request_args, return_to) # Get a Simple Registration response object if response # information was included in the OpenID response. sreg_response = {} ax_items = {} if response.status == consumer.SUCCESS: sreg_response = sreg.SRegResponse.fromSuccessResponse(response) ax_response = ax.FetchResponse.fromSuccessResponse(response) if ax_response: ax_items = ax_response.data # Get a PAPE response object if response information was # included in the OpenID response. pape_response = None if response.status == consumer.SUCCESS: pape_response = pape.Response.fromSuccessResponse(response) if not pape_response.auth_policies: pape_response = None # Map different consumer status codes to template contexts. results = { consumer.CANCEL: {'message': 'OpenID authentication cancelled.'}, consumer.FAILURE: {'error': 'OpenID authentication failed.'}, consumer.SUCCESS: {'url': response.getDisplayIdentifier(), 'sreg_response': sreg_response and sreg_response.iteritems(), 'ax_response': ax_items.items(), 'pape': pape_response} } result = results[response.status] print result if not result.has_key("error"): data_array = [it[1][0] for it in result["ax_response"]] data = { "login": None, "openid": result["url"], "first_name": data_array[0], "last_name": data_array[1], "email": data_array[2], } return create_profil_from_ipenid(request, data) if isinstance(response, consumer.FailureResponse): # In a real application, this information should be # written to a log for debugging/tracking OpenID # authentication failures. In general, the messages are # not user-friendly, but intended for developers. result['failure_reason'] = response.message return renderIndexPage(request, **result)
def startOpenID(request): """ Start the OpenID authentication process. Renders an authentication form and accepts its POST. * Renders an error message if OpenID cannot be initiated * Requests some Simple Registration data using the OpenID library's Simple Registration machinery * Generates the appropriate trust root and return URL values for this application (tweak where appropriate) * Generates the appropriate redirect based on the OpenID protocol version. """ if request.POST: # Start OpenID authentication (mojeid url) openid_url = request.POST['openid_identifier'] c = getConsumer(request) error = None if request.session.has_key(Discovery.PREFIX + c.session_key_prefix): del request.session[Discovery.PREFIX + c.session_key_prefix] if not request.POST.has_key('ns'): OpenIDServiceEndpoint.openid_type_uris = SERVICE_NS else: OpenIDServiceEndpoint.openid_type_uris = request.POST.getlist('ns') try: auth_request = c.begin(openid_url) except DiscoveryFailure, e: # Some other protocol-level failure occurred. error = "OpenID discovery error: %s" % (str(e),) if error: # Render the page with an error. return renderIndexPage(request, error=error) # Add Simple Registration request information. Some fields # are optional, some are required. It's possible that the # server doesn't support sreg or won't return any of the # fields. if request.POST.has_key('sreg'): sreg_request = sreg.SRegRequest( optional=[], required=request.POST.getlist('sreg')) auth_request.addExtension(sreg_request) if True: # request.POST.has_key('ax'): # Add Attribute Exchange request information. ax_request = ax.FetchRequest() # XXX - uses myOpenID-compatible schema values, which are # not those listed at axschema.org. # for uri in request.POST.getlist('ax'): for uri in AX_ATTRIBUTES: ax_request.add( ax.AttrInfo(uri, required=True)) auth_request.addExtension(ax_request) # Add PAPE request information. We'll ask for # phishing-resistant auth and display any policies we get in # the response. requested_policies = [] policy_prefix = 'policy_' for k, v in request.POST.iteritems(): # print k,v if k.startswith(policy_prefix): policy_attr = k[len(policy_prefix):] if policy_attr in PAPE_POLICIES: requested_policies.append(getattr(pape, policy_attr)) print requested_policies if requested_policies: pape_request = pape.Request(requested_policies) auth_request.addExtension(pape_request) # Compute the trust root and return URL values to build the # redirect information. trust_root = util.getViewURL(request, startOpenID) return_to = util.getViewURL(request, finishOpenID) # Send the browser to the server either by sending a redirect # URL or by generating a POST form. if auth_request.shouldSendRedirect(): url = auth_request.redirectURL(trust_root, return_to) return HttpResponseRedirect(url) else: # Beware: this renders a template whose content is a form # and some javascript to submit it upon page load. Non-JS # users will have to click the form submit button to # initiate OpenID authentication. form_id = 'openid_message' form_html = auth_request.formMarkup(trust_root, return_to, False, {'id': form_id}) return direct_to_template( request, 'consumer/request_form.html', {'html': form_html})