def handle_openid_login_request(): openid_url = request.form['openid_identifier'] try: consumer = openid.Consumer(session, None) openid_req = consumer.begin(openid_url) except openid.DiscoveryFailure: logger.exception('Error in OpenID discovery') raise else: if openid_req is None: raise Exception('No OpenID services found for the given URL') else: ax_req = ax.FetchRequest() ax_req.add(ax.AttrInfo('http://schema.openid.net/contact/email', alias='email')) ax_req.add(ax.AttrInfo('http://axschema.org/namePerson/friendly', alias='nickname')) openid_req.addExtension(ax_req) url = openid_req.redirectURL(get_openid_realm(), url_for('.openid_login', return_url=request.values.get('return_url'), _external=True)) return redirect(url) raise Exception('OpenID login failed')
def init(self): if self.connector: return from openid.consumer import consumer from openid.extensions import ax # from openid.store import memstore self.cons = consumer.Consumer({}, None) # memstore.MemoryStore()) self.connector = self.cons.begin(self.provider) ax_request = ax.FetchRequest() # 'http://axschema.org/contact/email', ax_request.add( ax.AttrInfo('http://axschema.org/contact/email', required=True)) self.connector.addExtension(ax_request)
def attach_reg_info(self, auth_request, keys): """Attaches sreg and ax requests to the auth request. :internal: """ keys = set(keys) sreg_keys = list(SREG_KEYS & keys) auth_request.addExtension(SRegRequest(required=sreg_keys)) ax_req = ax.FetchRequest() for key in keys: for uri in AX_MAPPING.get(key, ()): ax_req.add(ax.AttrInfo(uri, required=key in REQUIRED_KEYS)) auth_request.addExtension(ax_req)
def test_getExtensionArgs_empty_request_some(self): uri = 'http://not.found/' alias = 'ext0' expected_args = { 'mode': 'fetch_response', 'type.%s' % (alias, ): uri, 'count.%s' % (alias, ): '0' } req = ax.FetchRequest() req.add(ax.AttrInfo(uri)) msg = ax.FetchResponse(request=req) self.assertEqual(msg.getExtensionArgs(), expected_args)
def POST(self): # unlike the usual scheme of things, the POST is actually called # first here i = web.input(return_to='/') if i.get('action') == 'logout': oid.logout() return web.redirect(i.return_to) if not i.has_key('openid') or len(i.openid) == 0: return web.redirect(i.return_to) session_data = {'webpy_return_to': i.return_to} session_hash = oid._new_session(session_data) ax_req = ax.FetchRequest() ax_req.add( ax.AttrInfo('http://axschema.org/namePerson/first', required=True)) ax_req.add( ax.AttrInfo('http://axschema.org/namePerson/last', required=True)) ax_req.add( ax.AttrInfo('http://axschema.org/contact/email', required=True)) c = openid.consumer.consumer.Consumer(session_data, oid._get_openid_store()) a = c.begin(i.openid) a.addExtension(ax_req) a.addExtension( sreg.SRegRequest(optional=['email', 'fullname'])) f = a.redirectURL(web.ctx.home, web.ctx.home + web.ctx.fullpath) oid._save_session(session_hash, session_data) web.setcookie('openid_session_id', session_hash) return web.redirect(f)
def setup_request(self, params=None): """Fetch email, firstname, lastname from openid""" request = self.openid_request(params) # TODO: use sreg instead ax request to fetch nickname as username fetch_request = ax.FetchRequest() fetch_request.add( ax.AttrInfo('http://axschema.org/contact/email', alias='email', required=True)) fetch_request.add( ax.AttrInfo('http://axschema.org/namePerson/first', alias='firstname', required=True)) fetch_request.add( ax.AttrInfo('http://axschema.org/namePerson/last', alias='lastname', required=True)) request.addExtension(fetch_request) return request
def _handle_openid_login(self, req, errors): openid_url = req.form.get('openid_identifier') if openid_url: try: consumer = openid.Consumer(self.session, None) openid_req = consumer.begin(openid_url) except openid.DiscoveryFailure: logger.traceback('Error in OpenID discovery') errors.append('Error while trying to verify the OpenID') else: if openid_req is None: errors.append('No OpenID services found for the given URL') else: ax_req = ax.FetchRequest() ax_req.add(ax.AttrInfo('http://schema.openid.net/contact/email', alias='email')) ax_req.add(ax.AttrInfo('http://axschema.org/namePerson/friendly', alias='nickname')) openid_req.addExtension(ax_req) url = openid_req.redirectURL(self.config.base_url, self.login_url) return redirect(url) else: errors.append('Missing OpenID')
def _update_authrequest(self, authrequest, request): # Add on the Attribute Exchange for those that support that request_attributes = request.POST.get('ax_attributes', ax_attributes.keys()) ax_request = ax.FetchRequest() for attr in request_attributes: ax_request.add(ax.AttrInfo(attributes[attr], required=False, count=1)) authrequest.addExtension(ax_request) # Add OAuth request? oauth_request = OAuthRequest(consumer=self.consumer_key) authrequest.addExtension(oauth_request) return None
def test_updateUrlInResponse(self): uri = 'http://not.found/' alias = 'ext0' expected_args = { 'mode': 'fetch_response', 'update_url': self.request_update_url, 'type.%s' % (alias, ): uri, 'count.%s' % (alias, ): '0' } req = ax.FetchRequest(update_url=self.request_update_url) req.add(ax.AttrInfo(uri)) msg = ax.FetchResponse(request=req) self.assertEqual(msg.getExtensionArgs(), expected_args)
def start_openid(session, openid_url, trust_root, return_to): """ Start the OpenID authentication process. * 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. """ # Start OpenID authentication. c = get_consumer(session) try: auth_request = c.begin(openid_url) except DiscoveryFailure as e: # Some other protocol-level failure occurred. raise Exception("error in openid: OpenID discovery error") from e # 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. sreg_request = sreg.SRegRequest(required=['email'], optional=[]) auth_request.addExtension(sreg_request) # Add Attribute Exchange request information. ax_request = ax.FetchRequest() # XXX - uses myOpenID-compatible schema values, which are # not those listed at axschema.org. for k, v in AX_REQUIRED_FIELDS.items(): ax_request.add(ax.AttrInfo(v, required=True)) auth_request.addExtension(ax_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. url = auth_request.redirectURL(trust_root, return_to) return url
def login(request, environ, start_response, ask_info=False): """Redirect the user to the openid provider. Arguments: - ask_info: bool, default False. If set to true, will use the sreg and ax extensions to ask info about the user (email, name...). """ user_url = request.GET['url'] session, oi_session = get_sessions(environ) trust_root = request.host_url return_to = "%s/socialauth/openid/process" % trust_root immediate = False # If set to true and the identity provider can not reply # immediatly (user has to approve), then authentication will fail. # If set to True, then we have to handle the SetupNeeded response case in # process function. consumer = Consumer(oi_session, OPENID_STORE) auth_req = consumer.begin(user_url) if ask_info: sreg_request = sreg.SRegRequest(required=['email' ]) #, optional=SREG_FIELDS) auth_req.addExtension(sreg_request) ax_request = ax.FetchRequest() for alias, url in AX_FIELDS.iteritems(): ax_request.add(ax.AttrInfo(url, alias=alias, required=True)) auth_req.addExtension(ax_request) # PAPE (Provider Authentication Policy Extension): # TODO (an treat pape.Response as well) #pape_request = pape.Request([pape.AUTH_PHISHING_RESISTANT]) #auth_req.addExtension(pape_request) session.save() if auth_req.shouldSendRedirect(): redirect_url = auth_req.redirectURL(trust_root, return_to, immediate=immediate) start_response('302 Redirect', [('Location', redirect_url)]) return [] else: form_html = auth_req.htmlMarkup( trust_root, return_to, form_tag_attrs={'id': 'openid_message'}, immediate=immediate) start_response('200 OK', [('Content-Type', 'text/html')]) return [form_html]
def test_getExtensionArgs_noAlias(self): attr = ax.AttrInfo(type_uri='type://of.transportation', ) self.msg.add(attr) ax_args = self.msg.getExtensionArgs() for k, v in ax_args.items(): if v == attr.type_uri and k.startswith('type.'): alias = k[5:] break else: self.fail("Didn't find the type definition") self.assertExtensionArgs({ 'type.' + alias: attr.type_uri, 'if_available': alias })
def setup_request(self): """Setup request""" openid_request = self.openid_request() # Request some user details. Use attribute exchange if provider # advertises support. if openid_request.endpoint.supportsType(ax.AXMessage.ns_uri): fetch_request = ax.FetchRequest() # Mark all attributes as required, Google ignores optional ones for attr, alias in (AX_SCHEMA_ATTRS + OLD_AX_ATTRS): fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True)) else: fetch_request = sreg.SRegRequest(optional=dict(SREG_ATTR).keys()) openid_request.addExtension(fetch_request) return openid_request
def get_redirect_url(self): auth_request = self.consumer.begin(self.endpoint_url) if self.ax_attrs: ax_request = ax.FetchRequest() for ax_attr in self.ax_attrs: ax_request.add(ax.AttrInfo(AX_ATTRS[ax_attr], required=True)) auth_request.addExtension(ax_request) if self.sreg_attrs: auth_request.addExtension( sreg.SRegRequest(required=self.sreg_attrs)) redirect_url = auth_request.redirectURL(self.get_realm(), self.get_callback_url()) return redirect_url
def get_redirect_url(self): auth_request = self.consumer.begin(self.endpoint_url) # Use the openid AX Extension to get the user's name, email, and country ax_request = ax.FetchRequest() requested_info = self.available_info.keys() for alias in requested_info: ax_request.add(ax.AttrInfo(self.available_info[alias], alias=alias, required=True)) auth_request.addExtension(ax_request) redirect_url = auth_request.redirectURL(self.get_realm(), self.get_callback_url()) return redirect_url
def _update_authrequest(self, request, authrequest): # Add on the Attribute Exchange for those that support that ax_request = ax.FetchRequest() for attrib in ['http://axschema.org/namePerson/friendly', 'http://axschema.org/namePerson', 'http://axschema.org/person/gender', 'http://axschema.org/pref/timezone', 'http://axschema.org/media/image/default', 'http://axschema.org/contact/email']: ax_request.add(ax.AttrInfo(attrib)) authrequest.addExtension(ax_request) # Add OAuth request? if 'oauth' in request.POST: oauth_request = OAuthRequest(consumer=self.oauth_key) authrequest.addExtension(oauth_request)
def get_redirect(self): auth_request = self.consumer.begin(self.endpoint) if self.sreg: auth_request.addExtension(oid_sreg.SRegRequest(**self.sreg)) ax_request = oid_ax.FetchRequest() for mode, attributes in self.sreg.items(): for attribute in attributes: if attribute in _ax_sreg_mapping: ax_request.add( oid_ax.AttrInfo(_ax_sreg_mapping[attribute], count=1, required=mode == 'required', alias=attribute)) auth_request.addExtension(ax_request) redirect_url = auth_request.redirectURL( 'http%s://%s/' % (_https(), Site.objects.get_current().domain), self.return_to) return HttpResponseRedirect(redirect_url)
def buildAttributeRequest(self): ax_request = ax.FetchRequest() attributes = [ EMAIL_ATTR, VERIFIED_EMAIL_ATTR, NAME_ATTR, FIRST_NAME_ATTR, LAST_NAME_ATTR, FRIENDLY_NAME_ATTR, GENDER_ATTR, BIRTH_DATE_ATTR, AVATAR_ATTR, ] for attr in attributes: ax_request.add(ax.AttrInfo(attr, required=True)) return ax_request
def _update_authrequest(self, authrequest): """Update the authrequest with the default extensions and attributes we ask for This method doesn't need to return anything, since the extensions should be added to the authrequest object itself. """ # Add on the Attribute Exchange for those that support that request_attributes = self.get_argument('ax_attributes', ax_attributes.keys()) ax_request = ax.FetchRequest() for attr in request_attributes: ax_request.add(ax.AttrInfo(attributes[attr], required=True)) authrequest.addExtension(ax_request) # Form the Simple Reg request sreg_request = sreg.SRegRequest(optional=[ 'nickname', 'email', 'fullname', 'dob', 'gender', 'postcode', 'country', 'language', 'timezone' ], ) authrequest.addExtension(sreg_request) # Add PAPE request information. Setting max_auth_age to zero will force a login. requested_policies = [] policy_prefix = 'policy_' #for k, v in request.POST.iteritems(): # if k.startswith(policy_prefix): # policy_attr = k[len(policy_prefix):] # requested_policies.append(getattr(pape, policy_attr)) pape_request = pape.Request(requested_policies, max_auth_age=self.get_argument( 'pape_max_auth_age', None)) authrequest.addExtension(pape_request) popup_mode = self.get_argument('popup_mode', None) if popup_mode: kw_args = {'mode': popup_mode} popup_icon = self.get_argument('popup_icon') if 'popup_icon': kw_args['icon'] = popup_icon ui_request = UIRequest(**kw_args) authrequest.addExtension(ui_request) return None
def post_pw(): logging.debug("login_openid post_pw") oid_consumer = consumer.Consumer(self.get_openid_session(request), self.store) try: oid_req = oid_consumer.begin(identity) # SReg speaks this protocol: http://openid.net/specs/openid-simple-registration-extension-1_1-01.html # and tries to request additional metadata about this OpenID identity sreg_req = sreg.SRegRequest(required=['fullname','nickname','email'], optional=[]) oid_req.addExtension(sreg_req) # AX speaks this protocol: http://openid.net/specs/openid-attribute-exchange-1_0.html # and tries to get more attributes (by URI), we request some of the more common ones ax_req = ax.FetchRequest() for uri in self.AX_URIS: ax_req.add(ax.AttrInfo(uri, required = True)) oid_req.addExtension(ax_req) except consumer.DiscoveryFailure as exc: #request.setResponseCode(200, message = "OK") #request.write("Error: {0}".format(exc)) #request.finish() logging.error("Error in login_openid: {0}".format(exc)) return self.return_unauthorized(request) else: if oid_req is None: #request.setResponseCode(200, message = "OK") #request.write("Error, no OpenID services found for: {0}".format(identity)) logging.error("Error in login_openid: no OpenID services found for: {0}".format(identity)) #request.finish() return self.return_unauthorized(request) else: trust_root = self.webserver.server_url return_to = appendArgs(trust_root + "/" + self.base_path + "/openid_process", {}) logging.debug("OpenID, had oid_req, trust_root: {0}, return_to: {1}, oid_req: {2}".format(trust_root, return_to, oid_req)) redirect_url = oid_req.redirectURL(trust_root, return_to) # FIXME check this is the best way to redirect here request.setHeader("Location", redirect_url) request.setResponseCode(302, "Found") request.finish() return
def _update_authrequest(self, request, authrequest): """Update the authrequest with the default extensions and attributes we ask for This method doesn't need to return anything, since the extensions should be added to the authrequest object itself. """ # Add on the Attribute Exchange for those that support that ax_request = ax.FetchRequest() for attrib in attributes.values(): ax_request.add(ax.AttrInfo(attrib)) authrequest.addExtension(ax_request) # Form the Simple Reg request sreg_request = sreg.SRegRequest(optional=[ 'nickname', 'email', 'fullname', 'dob', 'gender', 'postcode', 'country', 'language', 'timezone' ], ) authrequest.addExtension(sreg_request)
def _update_authrequest(self, authrequest, request): """Update the authrequest with Attribute Exchange and optionally OAuth To optionally request OAuth, the request POST must include an ``oauth_scope`` parameter that indicates what Google Apps should have access requested. """ request_attributes = request.POST.get('ax_attributes', ax_attributes.keys()) ax_request = ax.FetchRequest() for attr in request_attributes: ax_request.add(ax.AttrInfo(attributes[attr], required=True)) authrequest.addExtension(ax_request) # Add PAPE request information. # Setting max_auth_age to zero will force a login. requested_policies = [] policy_prefix = 'policy_' for k, v in request.POST.iteritems(): if k.startswith(policy_prefix): policy_attr = k[len(policy_prefix):] requested_policies.append(getattr(pape, policy_attr)) pape_request = pape.Request(requested_policies, max_auth_age=request.POST.get( 'pape_max_auth_age', None)) authrequest.addExtension(pape_request) oauth_request = OAuthRequest(consumer=self.consumer_key, scope=self.scope or 'http://www.google.com/m8/feeds/') authrequest.addExtension(oauth_request) if 'popup_mode' in request.POST: kw_args = {'mode': request.POST['popup_mode']} if 'popup_icon' in request.POST: kw_args['icon'] = request.POST['popup_icon'] ui_request = UIRequest(**kw_args) authrequest.addExtension(ui_request) return None
def redirect(self): """Return a custom auth request url.""" gconsumer = consumer.Consumer({}, memstore.MemoryStore()) # Create an auth request to the given endpoint authrequest = gconsumer.begin(self._config['endpoint']) # Create an Attribute Exchange extension request axrequest = ax.FetchRequest(self._config['callback']) for alias, url in self.required.iteritems(): axrequest.add(ax.AttrInfo(url, alias=alias, required=True)) authrequest.addExtension(axrequest) # Create and apply a custom User Interface extension request uirequest = UIFetchRequest(mode='popup', icon=True) authrequest.addExtension(uirequest) # Return the generated URL return authrequest.redirectURL(self._config['realm'], self._config['callback'])
def begin(request, openid_url, next): disc = manager.Discovery(request.session, openid_url) # Clean up any residual data from pevious attempts disc.cleanup(force=True) service = disc.getNextService(discover.discover) c = consumer.Consumer(request.session, models.DjangoOpenIDStore()) try: auth_request = c.beginWithoutDiscovery(service) except consumer.DiscoveryFailure as e: raise DiscoverError(openid_url, e[0]) fetch_request = ax.FetchRequest() attributes = [('http://axschema.org/contact/email', 'email'), ('http://axschema.org/namePerson', 'fullname'), ('http://axschema.org/namePerson/first', 'firstname'), ('http://axschema.org/namePerson/last', 'lastname'), ('http://axschema.org/namePerson/friendly', 'nickname'), ('http://schema.openid.net/contact/email', 'old_email'), ('http://schema.openid.net/namePerson', 'old_fullname'), ('http://schema.openid.net/namePerson/friendly', 'old_nickname')] for attr, alias in attributes: fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True)) auth_request.addExtension(fetch_request) return_to = settings.WPS_OPENID_RETURN_TO if next is not None: return_to = '{!s}?next={!s}'.format(return_to, next) url = auth_request.redirectURL(settings.WPS_OPENID_TRUST_ROOT, return_to) return url
class BeginLoginHandler(BaseHandler): def get(self): openid_url = self.request.get('openid_url') if not openid_url: self.render_template( 'login.html', { 'login_url': users.OPENID_LOGIN_PATH, 'continue': self.request.get('continue', '/') }) return consumer = self.get_consumer() # if consumer discovery or authentication fails, show error page try: request = consumer.begin(openid_url) except Exception, e: logging.error( "Unexpected error in OpenID discovery/authentication: %s", e) self.render_template('error.html') return # TODO: Support custom specification of extensions # TODO: Don't ask for data we already have, perhaps? # use Simple Registration if available request.addExtension(sreg.SRegRequest(required=OPENID_SREG_ATTRS)) # or Atribute Exchange if available ax_request = ax.FetchRequest() for attruri in OPENID_AX_ATTRS: ax_request.add( ax.AttrInfo(attruri, required=True, alias=OPENID_AX_ATTRS[attruri])) request.addExtension(ax_request) # assemble and send redirect continue_url = self.request.get('continue', '/') return_to = "%s%s?continue=%s" % ( self.request.host_url, users.OPENID_FINISH_PATH, continue_url) self.redirect(request.redirectURL(self.request.host_url, return_to)) self.session.save()
def setup_request(self, params=None): """Setup request""" request = self.openid_request(params) # Request some user details. Use attribute exchange if provider # advertises support. if request.endpoint.supportsType(ax.AXMessage.ns_uri): fetch_request = ax.FetchRequest() # Mark all attributes as required, Google ignores optional ones for attr, alias in self.get_ax_attributes(): fetch_request.add(ax.AttrInfo(attr, alias=alias, required=True)) else: fetch_request = sreg.SRegRequest( optional=list(dict(self.get_sreg_attributes()).keys()) ) request.addExtension(fetch_request) # Add PAPE Extension for if configured preferred_policies = self.setting( 'OPENID_PAPE_PREFERRED_AUTH_POLICIES' ) preferred_level_types = self.setting( 'OPENID_PAPE_PREFERRED_AUTH_LEVEL_TYPES' ) max_age = self.setting('OPENID_PAPE_MAX_AUTH_AGE') if max_age is not None: try: max_age = int(max_age) except (ValueError, TypeError): max_age = None if max_age is not None or preferred_policies or preferred_level_types: pape_request = pape.Request( max_auth_age=max_age, preferred_auth_policies=preferred_policies, preferred_auth_level_types=preferred_level_types ) request.addExtension(pape_request) return request
def init(self): self.consumer = create_consumer(self.openid_session) if not hasattr(self, 'form_result'): return self._failure('', _("Invalid input.")) openid = self.form_result.get("openid") try: if not openid: raise ValueError(_("No OpenID given!")) authrequest = self.consumer.begin(openid) if not c.user and not model.OpenID.find(openid): axreq = ax.FetchRequest( h.base_url('/openid/update', absolute=True)) axreq.add( ax.AttrInfo(get_ax_mail_schema(openid), alias="email", required=True)) authrequest.addExtension(axreq) sreq = sreg.SRegRequest(required=['nickname'], optional=['email']) authrequest.addExtension(sreq) redirecturl = authrequest.redirectURL(h.base_url('/', absolute=True), return_to=h.base_url( '/openid/verify', absolute=True), immediate=False) self.set_session(self.openid_session) session.save() return redirect(redirecturl) except HTTPFound: raise except Exception, e: log.exception(e) return self._failure(openid, str(e))
def _update_authrequest(self, req, authrequest): """Update the authrequest with Attribute Exchange and optionally OAuth To optionally request OAuth, the request POST must include an ``oauth_scope`` parameter that indicates what Google Apps should have access requested. """ ax_request = ax.FetchRequest() for attr in self.request_attributes: ax_request.add(ax.AttrInfo(attributes[attr], required=True)) authrequest.addExtension(ax_request) # Add OAuth request? if 'oauth_scope' in req.POST: oauth_request = OAuthRequest(consumer=self.consumer, scope=req.POST['oauth_scope']) authrequest.addExtension(oauth_request) if 'popup_mode' in req.POST: kw_args = {'mode': req.POST['popup_mode']} if 'popup_icon' in req.POST: kw_args['icon'] = req.POST['popup_icon'] ui_request = UIRequest(**kw_args) authrequest.addExtension(ui_request) return None
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. openid_url = request.POST['openid_identifier'] c = getConsumer(request) error = None try: auth_request = c.begin(openid_url) except DiscoveryFailure as 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. sreg_request = sreg.SRegRequest( optional=['email', 'nickname'], required=['dob']) auth_request.addExtension(sreg_request) # Add Attribute Exchange request information. ax_request = ax.FetchRequest() # XXX - uses myOpenID-compatible schema values, which are # not those listed at axschema.org. ax_request.add( ax.AttrInfo('http://schema.openid.net/namePerson', required=True)) ax_request.add( ax.AttrInfo( 'http://schema.openid.net/contact/web/default', required=False, count=ax.UNLIMITED_VALUES)) 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 list(request.POST.items()): if k.startswith(policy_prefix): policy_attr = k[len(policy_prefix):] if policy_attr in PAPE_POLICIES: requested_policies.append(getattr(pape, policy_attr)) 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 TemplateView(request, 'consumer/request_form.html', {'html': form_html}) return renderIndexPage(request)
def login(self): # Instantiate consumer self.store._log = self._log oi_consumer = consumer.Consumer(self.session, self.store) # handle realm and XRDS if there is only one query parameter if self.use_realm and len(self.params) == 1: realm_request = self.params.get(self.realm_param) xrds_request = self.params.get(self.xrds_param) else: realm_request = None xrds_request = None # determine type of request if realm_request: #=================================================================== # Realm HTML #=================================================================== self._log(logging.INFO, 'Writing OpenID realm HTML to the response.') xrds_location = '{u}?{x}={x}'.format(u=self.url, x=self.xrds_param) self.write(REALM_HTML.format(xrds_location=xrds_location, body=self.realm_body)) elif xrds_request: #=================================================================== # XRDS XML #=================================================================== self._log(logging.INFO, 'Writing XRDS XML document to the response.') self.set_header('Content-Type', 'application/xrds+xml') self.write(XRDS_XML.format(return_to=self.url)) elif self.params.get('openid.mode'): #=================================================================== # Phase 2 after redirect #=================================================================== self._log(logging.INFO, 'Continuing OpenID authentication procedure after redirect.') # complete the authentication process response = oi_consumer.complete(self.params, self.url) # on success if response.status == consumer.SUCCESS: data = {} # get user ID data['guid'] = response.getDisplayIdentifier() self._log(logging.INFO, 'Authentication successful.') # get user data from AX response ax_response = ax.FetchResponse.fromSuccessResponse(response) if ax_response and ax_response.data: self._log(logging.INFO, 'Got AX data.') ax_data = {} # convert iterable values to their first item for k, v in ax_response.data.iteritems(): if v and type(v) in (list, tuple): ax_data[k] = v[0] data['ax'] = ax_data # get user data from SREG response sreg_response = sreg.SRegResponse.fromSuccessResponse(response) if sreg_response and sreg_response.data: self._log(logging.INFO, 'Got SREG data.') data['sreg'] = sreg_response.data # get data from PAPE response pape_response = pape.Response.fromSuccessResponse(response) if pape_response and pape_response.auth_policies: self._log(logging.INFO, 'Got PAPE data.') data['pape'] = pape_response.auth_policies # create user self._update_or_create_user(data) #=============================================================== # We're done! #=============================================================== elif response.status == consumer.CANCEL: raise CancellationError('User cancelled the verification of ID "{}"!'.format(response.getDisplayIdentifier())) elif response.status == consumer.FAILURE: raise FailureError(response.message) elif self.params.get(self.identifier_param): #=================================================================== # Phase 1 before redirect #=================================================================== self._log(logging.INFO, 'Starting OpenID authentication procedure.') # get AuthRequest object try: auth_request = oi_consumer.begin(self.identifier) except consumer.DiscoveryFailure as e: raise FailureError('Discovery failed for identifier {}!'.format(self.identifier), url=self.identifier, original_message=e.message) self._log(logging.INFO, 'Service discovery for identifier {} successful.'.format(self.identifier)) # add SREG extension # we need to remove required fields from optional fields because addExtension then raises an error self.sreg = [i for i in self.sreg if i not in self.sreg_required] auth_request.addExtension(sreg.SRegRequest(optional=self.sreg, required=self.sreg_required)) # add AX extension ax_request = ax.FetchRequest() # set AX schemas for i in self.ax: required = i in self.ax_required ax_request.add(ax.AttrInfo(i, required=required)) auth_request.addExtension(ax_request) # add PAPE extension auth_request.addExtension(pape.Request(self.pape)) # prepare realm and return_to URLs if self.use_realm: realm = return_to = '{u}?{r}={r}'.format(u=self.url, r=self.realm_param) else: realm = return_to = self.url url = auth_request.redirectURL(realm, return_to) if auth_request.shouldSendRedirect(): # can be redirected url = auth_request.redirectURL(realm, return_to) self._log(logging.INFO, 'Redirecting user to {}.'.format(url)) self.redirect(url) else: # must be sent as POST # this writes a html post form with auto-submit self._log(logging.INFO, 'Writing an auto-submit HTML form to the response.') form = auth_request.htmlMarkup(realm, return_to, False, dict(id='openid_form')) self.write(form) else: raise OpenIDError('No identifier specified!')