def login(request): if 'openid' in request.GET or request.method == 'POST': form = LoginForm(request.REQUEST) if form.is_valid(): client = _openid_consumer(request) try: auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() sreg.requestField(field_name=SRegField.EMAIL, required=True) auth_request.addExtension(sreg) ax = FetchRequest() ax.add(AttrInfo(AXAttribute.CONTACT_EMAIL, required=True)) auth_request.addExtension(ax) callback_url = reverse(callback) SocialLogin.stash_state(request) redirect_url = auth_request.redirectURL( request.build_absolute_uri('/'), request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) # UnicodeDecodeError: # see https://github.com/necaris/python3-openid/issues/1 except (UnicodeDecodeError, DiscoveryFailure) as e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error(request) else: form = LoginForm() d = dict(form=form) return render_to_response('openid/login.html', d, context_instance=RequestContext(request))
def login(request): if 'openid' in request.GET or request.method == 'POST': form = LoginForm(request.REQUEST) if form.is_valid(): client = _openid_consumer(request) try: auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() sreg.requestField(field_name=SRegField.EMAIL, required=True) auth_request.addExtension(sreg) ax = FetchRequest() ax.add(AttrInfo(AXAttribute.CONTACT_EMAIL, required=True)) auth_request.addExtension(ax) callback_url = reverse(callback) state = SocialLogin.marshall_state(request) callback_url = callback_url + '?' + urlencode(dict(state=state)) redirect_url = auth_request.redirectURL( request.build_absolute_uri('/'), request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) except DiscoveryFailure, e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error(request)
def __init__(self, status, identity_url): self.status = status self.identity_url = identity_url self.message = message.Message() sig_ext = SignatureVerification(consumer_key='CKEY', secret_key='SKEY', request_token='token', hmac=None, timestamp=None) sig_ext.toMessage(self.message) sreg_ext = SRegRequest( required=['nickname', 'email'], optional=['fullname'], policy_url=None, sreg_ns_uri='http://openid.net/extensions/sreg/1.1') sreg_ext.toMessage(self.message) self.signed_fields = [ 'openid.sreg.nickname', 'openid.sreg.email', 'openid.sreg.required', 'openid.sreg.optional', 'openid.sreg.fullname' ] self.endpoint = OpenIDServiceEndpoint() self.endpoint.claimed_id = identity_url
def post(self, request, *args, **kwargs): data = dict(list(request.GET.items()) + list(request.POST.items())) if self.provider.endpoint: data['openid'] = self.provider.endpoint form = LoginForm(data) if form.is_valid(): client = _openid_consumer(request) try: auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) auth_request.addExtension(ax) callback_url = reverse(self.callback_view) SocialLogin.stash_state(request) redirect_url = auth_request.redirectURL( request.build_absolute_uri('/'), request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) # UnicodeDecodeError: # see https://github.com/necaris/python3-openid/issues/1 except (UnicodeDecodeError, DiscoveryFailure) as e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error(request, self.provider.id, exception=e) return render(request, self.template_name, {'form': form})
def begin(request, openid_url): request.session['request_referer'] = urlparse.urljoin(request.META.get('HTTP_REFERER', ''), '/') consumer = Consumer(request.session, DjangoOpenIDStore()) try: auth_request = consumer.begin(openid_url) except DiscoveryFailure: return on_failure(request, _('The OpenID was invalid')) s = SRegRequest() for sarg in OPENID_SREG: if sarg.lower().lstrip() == "policy_url": s.policy_url = OPENID_SREG[sarg] else: for v in OPENID_SREG[sarg].split(','): s.requestField(field_name=v.lower().lstrip(), required=(sarg.lower().lstrip() == "required")) auth_request.addExtension(s) axr = AXFetchRequest() for i in OPENID_AX: axr.add(AttrInfo(i['type_uri'], i['count'], i['required'], i['alias'])) auth_request.addExtension(axr) redirect_url = auth_request.redirectURL(get_trusted_root(request), request.build_absolute_uri(reverse("openid_complete"))) return HttpResponseRedirect(redirect_url)
def __init__(self, status, identity_url): self.status = status self.identity_url = identity_url self.message = message.Message() sig_ext = SignatureVerification(consumer_key='CKEY', secret_key='SKEY', request_token='token', hmac=None, timestamp=None) sig_ext.toMessage(self.message) sreg_ext = SRegRequest(required = ['nickname','email'], optional = ['fullname'], policy_url = None, sreg_ns_uri = 'http://openid.net/extensions/sreg/1.1') sreg_ext.toMessage(self.message) self.signed_fields = ['openid.sreg.nickname', 'openid.sreg.email', 'openid.sreg.required', 'openid.sreg.optional', 'openid.sreg.fullname'] self.endpoint = OpenIDServiceEndpoint() self.endpoint.claimed_id=identity_url
def perform_openid_auth(self, form): if not form.is_valid(): return form request = self.request provider = self.provider(request) endpoint = form.cleaned_data["openid"] client = self.get_client(provider, endpoint) realm = self.get_realm(provider) auth_request = client.begin(endpoint) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) provider = OpenIDProvider(request) server_settings = provider.get_server_settings( request.GET.get("openid")) extra_attributes = server_settings.get("extra_attributes", []) for _, name, required in extra_attributes: ax.add(AttrInfo(name, required=required)) auth_request.addExtension(ax) SocialLogin.stash_state(request) # Fix for issues 1523 and 2072 (github django-allauth) if "next" in form.cleaned_data and form.cleaned_data["next"]: auth_request.return_to_args["next"] = form.cleaned_data["next"] redirect_url = auth_request.redirectURL( realm, request.build_absolute_uri(self.get_callback_url())) return HttpResponseRedirect(redirect_url)
def login(request): if 'openid' in request.GET or request.method == 'POST': form = LoginForm( dict(list(request.GET.items()) + list(request.POST.items())) ) if form.is_valid(): client = _openid_consumer(request) provider = OpenIDProvider(request) realm = provider.get_settings().get( 'REALM', request.build_absolute_uri('/')) try: auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) provider = OpenIDProvider(request) server_settings = \ provider.get_server_settings(request.GET.get('openid')) extra_attributes = \ server_settings.get('extra_attributes', []) for _, name, required in extra_attributes: ax.add(AttrInfo(name, required=required)) auth_request.addExtension(ax) callback_url = reverse(callback) SocialLogin.stash_state(request) # Fix for issues 1523 and 2072 (github django-allauth) if 'next' in form.cleaned_data and form.cleaned_data['next']: auth_request.return_to_args['next'] = \ form.cleaned_data['next'] redirect_url = auth_request.redirectURL( realm, request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) # UnicodeDecodeError: # see https://github.com/necaris/python3-openid/issues/1 except (UnicodeDecodeError, DiscoveryFailure) as e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error( request, OpenIDProvider.id, exception=e) else: form = LoginForm(initial={'next': request.GET.get('next'), 'process': request.GET.get('process')}) d = dict(form=form) return render(request, "openid/login.html", d)
def dispatch(self, request): if 'openid' in request.GET or request.method == 'POST': form = LoginForm( dict(list(request.GET.items()) + list(request.POST.items()))) if form.is_valid(): client = _openid_consumer(request) try: auth_request = client.begin(form.cleaned_data['openid']) provider = self.provider app = provider.get_app(request) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) server_settings = provider.get_server_settings( request.GET.get('openid')) extra_attributes = server_settings.get( 'extra_attributes', []) for _, name, required in extra_attributes: ax.add(AttrInfo(name, required=required)) auth_request.addExtension(ax) callback_url = provider.get_callback_url(request, app) SocialLogin.stash_state(request) # https://github.com/pennersr/django-allauth/issues/1523 auth_request.return_to_args['next'] = \ form.cleaned_data.get('next', '/') redirect_url = auth_request.redirectURL( request.build_absolute_uri('/'), request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) # UnicodeDecodeError: # see https://github.com/necaris/python3-openid/issues/1 except (UnicodeDecodeError, DiscoveryFailure) as e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error(request, self.provider.id, exception=e) else: form = LoginForm( initial={ 'next': request.GET.get('next'), 'process': request.GET.get('process') }) d = dict(form=form) return render(request, "openid/login.html", d)
def prepare_authentication_request(self, request, redirect_to): if not redirect_to.startswith('http://') or redirect_to.startswith( 'https://'): redirect_to = get_url_host(request) + redirect_to user_url = self.get_user_url(request) if xri.identifierScheme(user_url) == 'XRI' and getattr( settings, 'OPENID_DISALLOW_INAMES', False): raise InvalidAuthentication('i-names are not supported') consumer = Consumer(request.session, OsqaOpenIDStore()) try: auth_request = consumer.begin(user_url) except DiscoveryFailure: raise InvalidAuthentication( _('Sorry, but your input is not a valid OpenId')) sreg = getattr(self, 'sreg_attributes', False) if sreg: s = SRegRequest() for k, attr_dic in sreg.items(): if k == "policy_url": s.policy_url = attr_dic continue for attr_name in attr_dic.keys(): s.requestField(field_name=attr_name, required=(k == "required")) auth_request.addExtension(s) ax_schema = getattr(self, 'dataype2ax_schema', False) if ax_schema and request.session.get('force_email_request', True): axr = AXFetchRequest() for data_type, schema in ax_schema.items(): if isinstance(schema, tuple): axr.add(AttrInfo(schema[0], required=True, alias=schema[1])) else: axr.add(AttrInfo(schema, required=True, alias=data_type)) auth_request.addExtension(axr) trust_root = getattr(settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/') return auth_request.redirectURL(trust_root, redirect_to)
def prepare_authentication_request(self, request, redirect_to): if not redirect_to.startswith('http://') or redirect_to.startswith('https://'): redirect_to = get_url_host(request) + redirect_to user_url = self.get_user_url(request) if xri.identifierScheme(user_url) == 'XRI' and getattr( settings, 'OPENID_DISALLOW_INAMES', False ): raise InvalidAuthentication('i-names are not supported') consumer = Consumer(request.session, OsqaOpenIDStore()) try: auth_request = consumer.begin(user_url) except DiscoveryFailure: raise InvalidAuthentication(_('Sorry, but your input is not a valid OpenId')) sreg = getattr(self, 'sreg_attributes', False) if sreg: s = SRegRequest() for k, attr_dic in sreg.items(): if k == "policy_url": s.policy_url = attr_dic continue for attr_name in attr_dic.keys(): s.requestField(field_name=attr_name, required=(k == "required")) auth_request.addExtension(s) ax_schema = getattr(self, 'dataype2ax_schema', False) if ax_schema and request.session.get('force_email_request', True): axr = AXFetchRequest() for data_type, schema in ax_schema.items(): if isinstance(schema, tuple): axr.add(AttrInfo(schema[0], 1, True, schema[1])) else: axr.add(AttrInfo(schema, 1, True, data_type)) auth_request.addExtension(axr) trust_root = getattr( settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/' ) return auth_request.redirectURL(trust_root, redirect_to)
def test_login_create_users(self): settings.OPENID_CREATE_USERS = True # Create a user with the same name as we'll pass back via sreg. User.objects.create_user('someuser', '*****@*****.**') # Posting in an identity URL begins the authentication request: response = self.client.post('/openid/login/', {'openid_identifier': 'http://example.com/identity', 'next': '/getuser/'}) self.assertContains(response, 'OpenID transaction in progress') # Complete the request, passing back some simple registration # data. The user is redirected to the next URL. openid_request = self.provider.parseFormPost(response.content) sreg_request = SRegRequest.fromOpenIDRequest(openid_request) openid_response = openid_request.answer(True) sreg_response = SRegResponse.extractResponse( sreg_request, {'nickname': 'someuser', 'fullname': 'Some User', 'email': '*****@*****.**'}) openid_response.addExtension(sreg_response) response = self.complete(openid_response) self.assertRedirects(response, 'http://testserver/getuser/') # And they are now logged in as a new user (they haven't taken # over the existing "someuser" user). response = self.client.get('/getuser/') self.assertEquals(response.content, 'someuser2') # Check the details of the new user. user = User.objects.get(username='******') self.assertEquals(user.first_name, 'Some') self.assertEquals(user.last_name, 'User') self.assertEquals(user.email, '*****@*****.**')
class AccountController(BaseController): geoip = GeoIP(os.path.join(config['pylons.paths']['data'], 'geoip.dat')) openid_store = FileOpenIDStore('/var/tmp') @require('guest') def login(self): login = render('account/login.tpl', slacks=True) if request.environ['REQUEST_METHOD'] != 'POST': return login try: form = LoginForm().to_python(request.POST) except validators.Invalid, e: return h.htmlfill(e, form=login) try: cons = Consumer(session=session, store=self.openid_store) auth_request = cons.begin(form['openid_identifier']) auth_request.addExtension( SRegRequest(optional=['nickname', 'email'])) except DiscoveryFailure: h.flash(_('The specified URL is not a valid OpenID end-point.'), 'error') redirect(url(controller='account', action='login')) host = request.headers['host'] realm = '%s://%s' % (request_config().protocol, host) return_url = url(host=host, controller='account', action='login_complete') new_url = auth_request.redirectURL(return_to=return_url, realm=realm) redirect(new_url)
def _get_approved_data(request, orequest): """Given an HTTP request and an OpenID request, return a nested dict of values requested in the request and approved by the user. """ if not orequest: return None approved_data = {} rpconfig = utils.get_rpconfig(orequest.trust_root) sreg_request = SRegRequest.fromOpenIDRequest(orequest) ax_request = ax.FetchRequest.fromOpenIDRequest(orequest) user_attribs_form = UserAttribsRequestForm( request, sreg_request, ax_request, rpconfig) if user_attribs_form.has_data: approved_data['user_attribs'] = { 'requested': user_attribs_form.data.keys(), 'approved': user_attribs_form.data_approved_for_request.keys()} args = orequest.message.getArgs(LAUNCHPAD_TEAMS_NS) team_names = args.get('query_membership') if team_names: team_names = team_names.split(',') teams_form = TeamsRequestForm( request, TeamsRequest.fromOpenIDRequest(orequest), rpconfig, ) approved_data['teams'] = { 'requested': team_names, 'approved': teams_form.teams_approved_by_user} return approved_data
def login_begin(self): """Step one of logging in with OpenID; we redirect to the provider""" cons = Consumer(session=session, store=self.openid_store) try: openid_url = request.params['openid_identifier'] except KeyError: return self._bail("Gotta enter an OpenID to log in.") try: auth_request = cons.begin(openid_url) except DiscoveryFailure: return self._bail( "Can't connect to '{0}'. You sure it's an OpenID?".format( openid_url)) sreg_req = SRegRequest(optional=[ 'nickname', 'email', 'dob', 'gender', 'country', 'language', 'timezone' ]) auth_request.addExtension(sreg_req) host = request.headers['host'] protocol = request_config().protocol return_url = url(host=host, controller='accounts', action='login_finish') new_url = auth_request.redirectURL(return_to=return_url, realm=protocol + '://' + host) redirect(new_url)
def createPositiveResponse(self): """Create a positive assertion OpenIDResponse. This method should be called to create the response to successful checkid requests. If the trust root for the request is in openid_sreg_trustroots, then additional user information is included with the response. """ assert self.account is not None, ( 'Must be logged in for positive OpenID response') assert self.openid_request is not None, ( 'No OpenID request to respond to.') if not self.isIdentityOwner(): return self.createFailedResponse() if self.openid_request.idSelect(): response = self.openid_request.answer( True, identity=self.user_identity_url) else: response = self.openid_request.answer(True) person = IPerson(self.account) sreg_fields = dict(nickname=person.name, email=person.preferredemail.email, fullname=self.account.displayname) sreg_request = SRegRequest.fromOpenIDRequest(self.openid_request) sreg_response = SRegResponse.extractResponse(sreg_request, sreg_fields) response.addExtension(sreg_response) return response
def Respond(self, oidresponse): logging.warning('Respond: oidresponse.request.mode ' + oidresponse.request.mode) if oidresponse.request.mode in ['checkid_immediate', 'checkid_setup']: user = users.get_current_user() if user: from openid.extensions.sreg import SRegRequest, SRegResponse sreg_req = SRegRequest.fromOpenIDRequest(oidresponse.request) if sreg_req.wereFieldsRequested(): logging.info("sreg_req:%s", sreg_req.allRequestedFields()) user_data = {'nickname':user.nickname(), 'email':user.email()} sreg_resp = SRegResponse.extractResponse(sreg_req, user_data) sreg_resp.toMessage(oidresponse.fields) logging.info('Using response: %s' % oidresponse) encoded_response = oidserver.encodeResponse(oidresponse) for header, value in encoded_response.headers.items(): self.response.headers[header] = str(value) if encoded_response.code in (301, 302): self.redirect(self.response.headers['location']) else: self.response.set_status(encoded_response.code) if encoded_response.body: logging.debug('Sending response body: %s' % encoded_response.body) self.response.out.write(encoded_response.body) else: self.response.out.write('')
def begin(self, request, data): try: openid_url = data['openid_url'].strip() except KeyError: messages.error(request, lang.FILL_OPENID_URL) raise Redirect('publicauth-login') # allow user to type openid provider without http:// prefix if not openid_url.startswith("http"): openid_url = "http://%s" % openid_url return_url = request.build_absolute_uri( reverse('publicauth-complete', args=[self.provider])) request.session['openid_return_to'] = return_url client = consumer.Consumer(request.session, None) try: openid_request = client.begin(openid_url) sreg_extra = [i for i in self.PROFILE_MAPPING] sreg = SRegRequest(required=sreg_extra) openid_request.addExtension(sreg) ax_msg = FetchRequest() for detail in self.PROFILE_MAPPING: ax_msg.add(AttrInfo(settings.AX_URIS[detail], required=True)) openid_request.addExtension(ax_msg) redirect_url = openid_request.redirectURL(realm='http://' + request.get_host(), return_to=return_url) raise Redirect(redirect_url) except discover.DiscoveryFailure: messages.error(request, _('Could not find OpenID server')) raise Redirect('publicauth-login')
def Respond(self, oidresponse): logging.warning('Respond: oidresponse.request.mode ' + oidresponse.request.mode) if oidresponse.request.mode in ['checkid_immediate', 'checkid_setup']: user = users.get_current_user() if user: from openid.extensions.sreg import SRegRequest, SRegResponse sreg_req = SRegRequest.fromOpenIDRequest(oidresponse.request) if sreg_req.wereFieldsRequested(): logging.info("sreg_req:%s", sreg_req.allRequestedFields()) user_data = { 'nickname': user.nickname(), 'email': user.email() } sreg_resp = SRegResponse.extractResponse( sreg_req, user_data) sreg_resp.toMessage(oidresponse.fields) logging.info('Using response: %s' % oidresponse) encoded_response = oidserver.encodeResponse(oidresponse) for header, value in encoded_response.headers.items(): self.response.headers[header] = str(value) if encoded_response.code in (301, 302): self.redirect(self.response.headers['location']) else: self.response.set_status(encoded_response.code) if encoded_response.body: logging.debug('Sending response body: %s' % encoded_response.body) self.response.out.write(encoded_response.body) else: self.response.out.write('')
def createPositiveResponse(self): """Create a positive assertion OpenIDResponse. This method should be called to create the response to successful checkid requests. If the trust root for the request is in openid_sreg_trustroots, then additional user information is included with the response. """ assert self.account is not None, ( 'Must be logged in for positive OpenID response') assert self.openid_request is not None, ( 'No OpenID request to respond to.') if not self.isIdentityOwner(): return self.createFailedResponse() if self.openid_request.idSelect(): response = self.openid_request.answer( True, identity=self.user_identity_url) else: response = self.openid_request.answer(True) person = IPerson(self.account) sreg_fields = dict( nickname=person.name, email=person.preferredemail.email, fullname=self.account.displayname) sreg_request = SRegRequest.fromOpenIDRequest(self.openid_request) sreg_response = SRegResponse.extractResponse( sreg_request, sreg_fields) response.addExtension(sreg_response) return response
def decide(request, token): try: orequest = _get_orequest(request, token) rpconfig = utils.get_rpconfig(orequest.trust_root) except: return HttpResponse("Invalid OpenID transaction") if not request.user.is_authenticated(): # XXX: need to remove this circular dep to the webui app from webui.views import ui return ui.LoginView.as_view()(request, token, rpconfig=rpconfig) if not _user_is_verified_for_rp(request.user, rpconfig): name = rpconfig.displayname if rpconfig else orequest.trust_root messages.warning( request, SITE_REQUIRES_VERIFIED.format(rp_name=name) ) return HttpResponseRedirect(reverse('account-emails')) site_requires_twofactor = twofactor.site_requires_twofactor_auth( request, token, rpconfig) if (not twofactor.is_authenticated(request) or (site_requires_twofactor and not twofactor.is_upgraded(request))): if is_twofactor_enabled(request): return HttpResponseRedirect(reverse('twofactor', args=[token])) else: return _process_decide(request, orequest, decision=False) if ('ok' in request.POST or (rpconfig is not None and rpconfig.auto_authorize)): return _process_decide(request, orequest, decision=True) sreg_request = SRegRequest.fromOpenIDRequest(orequest) ax_request = ax.FetchRequest.fromOpenIDRequest(orequest) teams_request = TeamsRequest.fromOpenIDRequest(orequest) try: summary = OpenIDRPSummary.objects.get( account=request.user, trust_root=orequest.trust_root, openid_identifier=request.user.openid_identity_url) approved_data = summary.get_approved_data() except OpenIDRPSummary.DoesNotExist: approved_data = {} user_attribs_form = UserAttribsRequestForm( request, sreg_request, ax_request, rpconfig, approved_data=approved_data.get('user_attribs')) teams_form = TeamsRequestForm(request, teams_request, rpconfig, approved_data=approved_data.get('teams')) context = RequestContext(request, { 'account': request.user, 'trust_root': orequest.trust_root, 'rpconfig': rpconfig, 'user_attribs_form': user_attribs_form, 'teams_form': teams_form, 'token': token, 'sane_trust_root': _request_has_sane_trust_root(orequest) }) return render_to_response('server/decide.html', context)
def openid_decide(request): """ The page that asks the user if they really want to sign in to the site, and lets them add the consumer to their trusted whitelist. # If user is logged in, ask if they want to trust this trust_root # If they are NOT logged in, show the landing page """ orequest = request.session.get('OPENID_REQUEST') # No request ? Failure.. if not orequest: logger.warning('OpenID decide view failed, \ because no OpenID request is saved') return HttpResponseRedirect('/') sreg_request = SRegRequest.fromOpenIDRequest(orequest) logger.debug('SREG request: %s' % sreg_request.__dict__) if not request.user.is_authenticated(): # Not authenticated ? Authenticate and go back to the server endpoint return redirect_to_login(request, next=reverse(openid_server), nonce='1') if request.method == 'POST': if 'cancel' in request.POST: # User refused logger.info('OpenID decide canceled') return HttpResponseRedirect('%s?cancel' % reverse(openid_server)) else: form = DecideForm(sreg_request=sreg_request, data=request.POST) if form.is_valid(): data = form.cleaned_data # Remember the choice t, created = models.TrustedRoot.objects.get_or_create( user=request.user.id, trust_root=orequest.trust_root) t.choices = sreg_request.required \ + [ field for field in data if data[field] ] t.save() logger.debug('OpenID decide, user choice:%s' % data) return HttpResponseRedirect(reverse('openid-provider-root')) else: form = DecideForm(sreg_request=sreg_request) logger.info('OpenID device view, orequest:%s' % orequest) # verify return_to of trust_root try: trust_root_valid = verifyReturnTo(orequest.trust_root, orequest.return_to) and "Valid" or "Invalid" except HTTPFetchingError: trust_root_valid = "Unreachable" except DiscoveryFailure: trust_root_valid = "DISCOVERY_FAILED" return render_to_response('idp/openid/decide.html', { 'title': _('Trust this site?'), 'required': sreg_request.required, 'optional': sreg_request.optional, 'trust_root_valid': trust_root_valid, 'form': form, }, context_instance=RequestContext(request))
def post(self): parsed = urlparse.urlparse(self.request.uri) request_url_without_path = parsed[0] + '://' + parsed[1] request_url_without_params = request_url_without_path + parsed[2] token = self.request.get('token') or urlparse.urlparse(self.request.uri)[2].rsplit('/',2)[2] oid_args = False query = datastore.Query('Verification') query['token ='] = token v = query.Get(1) if v: v = v[0] if v['expires'] > time.time(): self.user = v['email'] self.oid_args = pickle.loads(str(v['oidrequest'])) else: error = 'That token has expired. Please try again.' datastore.Delete(v) else: error = 'No such token found.' if not self.CheckUser(): self.ShowFrontPage(error) return args = self.ArgsToDict() try: oidrequest = OpenIDServer.CheckIDRequest.fromMessage(OpenIDMessage.fromPostArgs(args), '') except: trace = ''.join(traceback.format_exception(*sys.exc_info())) self.ReportError('Error decoding login request:\n%s' % trace) return if True: #args.has_key('yes'): logging.debug('Confirming identity to %s' % oidrequest.trust_root) if args.get('remember', '') == 'yes': logging.info('Setting cookie to remember openid login for two weeks') expires = datetime.datetime.now() + datetime.timedelta(weeks=2) expires_rfc822 = expires.strftime('%a, %d %b %Y %H:%M:%S +0000') self.response.headers.add_header( 'Set-Cookie', 'openid_remembered=yes; expires=%s' % expires_rfc822) self.store_login(oidrequest, 'confirmed') sreg_req = SRegRequest.fromOpenIDRequest(oidrequest) self.Respond(oidrequest.answer(True, request_url_without_path + '/id/' + urllib.quote(self.user)), sreg_req) elif args.has_key('no'): logging.debug('Login denied, sending cancel to %s' % oidrequest.trust_root) self.store_login(oidrequest, 'declined') return self.Respond(oidrequest.answer(False)) else: self.ReportError('Bad login request.')
def _start_verification(request, form, return_to, sreg=True): """ Start OpenID Verification. Returns False if verification fails, otherwise, will return either a redirect or render_to_response object """ openid_url = form.openid.data c = consumer.Consumer(request.session, SQLAlchemyOpenIDStore()) # Try to discover provider try: auth_request = c.begin(openid_url) except DiscoveryFailure: # Discovery failed, return to login page form.openid.errors.append( _('Sorry, the OpenID server could not be found')) return False host = 'http://' + request.host if sreg: # Ask provider for email and nickname auth_request.addExtension(SRegRequest(required=['email', 'nickname'])) # Do we even need this? if auth_request is None: form.openid.errors.append( _('No OpenID service was found for %s' % openid_url)) elif auth_request.shouldSendRedirect(): # Begin the authentication process as a HTTP redirect redirect_url = auth_request.redirectURL( host, return_to) return redirect( request, location=redirect_url) else: # Send request as POST form_html = auth_request.htmlMarkup( host, host + return_to, # Is this necessary? form_tag_attrs={'id': 'openid_message'}) # 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. return render_to_response( request, 'mediagoblin/plugins/openid/request_form.html', {'html': form_html}) return False
def begin(self, oid, realm, return_to_url): """ Begin the OpenID authentication """ w2popenid = self.session.w2popenid w2popenid.oid = oid auth_req = self.consumer.begin(oid) auth_req.addExtension(SRegRequest(required=['email', 'nickname'])) url = auth_req.redirectURL(return_to=return_to_url, realm=realm) return url
def handle_sreg(request, response): """Handle any sreg data requests""" sreg_req = SRegRequest.fromOpenIDRequest(request) # Extract information if required if sreg_req.wereFieldsRequested(): fields = config.sreg_fields() if not fields: return sreg_resp = SRegResponse.extractResponse(sreg_req, config.sreg_fields()) sreg_resp.toMessage(response.fields)
def perform_openid_auth(self, form): if not form.is_valid(): return form request = self.request client = self.get_client() provider = self.provider(request) realm = self.get_realm(provider) auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField( field_name=name, required=True ) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) provider = OpenIDProvider(request) server_settings = \ provider.get_server_settings(request.GET.get('openid')) extra_attributes = \ server_settings.get('extra_attributes', []) for _, name, required in extra_attributes: ax.add(AttrInfo(name, required=required)) auth_request.addExtension(ax) SocialLogin.stash_state(request) # Fix for issues 1523 and 2072 (github django-allauth) if "next" in form.cleaned_data and form.cleaned_data["next"]: auth_request.return_to_args['next'] = \ form.cleaned_data['next'] redirect_url = auth_request.redirectURL( realm, request.build_absolute_uri(self.get_callback_url())) return HttpResponseRedirect(redirect_url)
def login(request): if 'openid' in request.GET or request.method == 'POST': form = LoginForm( dict(list(request.GET.items()) + list(request.POST.items()))) if form.is_valid(): client = _openid_consumer(request) try: auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) auth_request.addExtension(ax) callback_url = reverse(callback) SocialLogin.stash_state(request) redirect_url = auth_request.redirectURL( request.build_absolute_uri('/'), request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) # UnicodeDecodeError: # see https://github.com/necaris/python3-openid/issues/1 except (UnicodeDecodeError, DiscoveryFailure) as e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error(request, OpenIDProvider.id, exception=e) else: form = LoginForm(initial={ 'next': request.GET.get('next'), 'process': request.GET.get('process') }) d = dict(form=form) return render_to_response('openid/login.html', d, context_instance=RequestContext(request))
def Respond(self, oidresponse): """Send an OpenID response. Args: oidresponse: OpenIDResponse The response to send, usually created by OpenIDRequest.answer(). """ logging.warning('Respond: oidresponse.request.mode ' + oidresponse.request.mode) if oidresponse.request.mode in ['checkid_immediate', 'checkid_setup']: # user = users.get_current_user() user = self.get_current_user() if user: from openid.extensions.sreg import SRegRequest,SRegResponse sreg_req = SRegRequest.fromOpenIDRequest(oidresponse.request) logging.info("sreg_req:%s",sreg_req.allRequestedFields()) if sreg_req.wereFieldsRequested(): user_data = {'nickname':user.nickname, 'email':user.email} sreg_resp = SRegResponse.extractResponse(sreg_req, user_data) sreg_resp.toMessage(oidresponse.fields) # add nickname, using the Simple Registration Extension: # http://www.openidenabled.com/openid/simple-registration-extension/ #oidresponse.fields.setArg('http://openid.net/sreg/1.0', 'nickname', user.nickname) #oidresponse.fields.setArg('http://openid.net/sreg/1.0', 'email', user.email) #oidresponse.fields.setArg('http://openid.net/srv/ax/1.0', 'nickname', user.nickname) #oidresponse.fields.setArg('http://openid.net/srv/ax/1.0', 'email', user.email) from openid.extensions.ax import FetchRequest, FetchResponse res ={'nickname':user.nickname,'email':user.email,'attr0':user.email,'attr1':user.nickname} ax_req = FetchRequest.fromOpenIDRequest(oidresponse.request) logging.info("ax_req:%s",ax_req.getRequiredAttrs()) ax_res = FetchResponse() for x in ax_req.iterAttrs(): ax_res.addValue(x.type_uri,res[x.alias] ) ax_res.toMessage(oidresponse.fields) pass logging.info('Using response: %s' % oidresponse) encoded_response = oidserver.encodeResponse(oidresponse) # update() would be nice, but wsgiref.headers.Headers doesn't implement it for header, value in encoded_response.headers.items(): self.response.headers[header] = str(value) if encoded_response.code in (301, 302): self.redirect(self.response.headers['location']) else: self.response.set_status(encoded_response.code) if encoded_response.body: logging.debug('Sending response body: %s' % encoded_response.body) self.response.out.write(encoded_response.body) else: self.response.out.write('')
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 openid_begin(identifier, return_url, request, max_auth_age=False, sreg=False): """Step one of logging in with OpenID; we resolve a webfinger, if present, then redirect to the provider. Set sreg to True to attempt to retrieve Simple Registration information. Set max_auth_age to a number of seconds to request the OP to ensure that the user authenticated within that many seconds prior to the request, or else force immediate re-authentication.""" session = request.session openid_url = identifier # Does it look like an email address? # If so, try finding an OpenID URL via Webfinger. webfinger_openid = resolve_webfinger(identifier) if webfinger_openid: openid_url = webfinger_openid session['pending_identity_webfinger'] = identifier session.save() cons = Consumer(session=session, store=openid_store) print 1 try: auth_request = cons.begin(openid_url) except DiscoveryFailure: # XXX this error blows raise OpenIDError( "Can't connect to '{0}'. It might not support OpenID.".format(openid_url)) print 2 if sreg: sreg_req = SRegRequest(optional=['nickname', 'email', 'timezone']) auth_request.addExtension(sreg_req) if max_auth_age is not False and max_auth_age >= 0: auth_age_req = PAPERequest(max_auth_age=max_auth_age) auth_request.addExtension(auth_age_req) print 3 # XXX is this realm stuff correct # ^^^ AFAICT, yes, as long as we don't need the assertion to be valid for # sub-domains new_url = auth_request.redirectURL( return_to=return_url, realm=request.host_url, ) print new_url return new_url
def create_request(openid_url, session): errors = [] try: consumer = get_consumer(session) request = consumer.begin(openid_url) if request is None: errors.append(_('OpenID service is not found')) except Exception as e: errors.append(str(e)) if errors: raise OpenIdError(errors) sreg_request = SRegRequest(optional=['nickname', 'fullname']) request.addExtension(sreg_request) return request
def begin_openid_login(request): request.session["openid_login"] = True consumer = get_consumer(request) auth_request = consumer.begin('https://openid.intuit.com/openid/xrds') auth_request.addExtension(SRegRequest( required=['fullname', 'email'] )) trust_root = get_base_url(request) return_to = urljoin(get_base_url(request), request.path) url = auth_request.redirectURL(trust_root, return_to) return HttpResponseRedirect(url)
def add_sreg_fields(self, oidresponse, user): """ Add requested Simple Registration Extension fields to oidresponse and return it. """ sreg_req = SRegRequest.fromOpenIDRequest(oidresponse.request) if sreg_req.wereFieldsRequested(): logging.debug("respond: sreg_req:%s", sreg_req.allRequestedFields()) sreg_map = dict( ((key, val) for (key, val) in {'nickname':user.nickname(), 'email':user.email()}.items() if key in sreg_req.allRequestedFields())) oidresponse.addExtension( SRegResponse.extractResponse(sreg_req, sreg_map)) return oidresponse
def add_sreg_fields(self, oidresponse, user): """ Add requested Simple Registration Extension fields to oidresponse and return it. """ sreg_req = SRegRequest.fromOpenIDRequest(oidresponse.request) if sreg_req.wereFieldsRequested(): logging.debug("respond: sreg_req:%s", sreg_req.allRequestedFields()) sreg_map = dict(((key, val) for (key, val) in { 'nickname': user.nickname(), 'email': user.email() }.items() if key in sreg_req.allRequestedFields())) oidresponse.addExtension( SRegResponse.extractResponse(sreg_req, sreg_map)) return oidresponse
def _add_user_attribs(request, openid_request, openid_response): # Add ax and sreg result data sreg_request = SRegRequest.fromOpenIDRequest(openid_request) ax_request = ax.FetchRequest.fromOpenIDRequest(openid_request) rpconfig = utils.get_rpconfig(openid_request.trust_root) form = UserAttribsRequestForm( request, sreg_request, ax_request, rpconfig) if form.data_approved_for_request: sreg_response = SRegResponse.extractResponse( sreg_request, form.data_approved_for_request) openid_response.addExtension(sreg_response) if ax_request is not None: ax_response = ax.FetchResponse(ax_request) for k, v in form.data_approved_for_request.iteritems(): if AX_DATA_FIELDS.getNamespaceURI(k) in ax_request: ax_response.addValue(AX_DATA_FIELDS.getNamespaceURI(k), v) openid_response.addExtension(ax_response)
def _begin_login(self, environ, start_response): """Start the process of authenticating with OpenID. We redirect the user to Launchpad to identify themselves, asking to be sent their nickname. Launchpad will then redirect them to our +login page with enough information that we can then redirect them again to the page they were looking at, with a cookie that gives us the username. """ openid_request = self._make_consumer(environ).begin( config.launchpad.openid_provider_root) openid_request.addExtension(SRegRequest(required=['nickname'])) back_to = construct_url(environ) raise HTTPMovedPermanently( openid_request.redirectURL( config.codehosting.secure_codebrowse_root, config.codehosting.secure_codebrowse_root + '+login/?' + urllib.urlencode({'back_to': back_to})))
def Respond(self, oidresponse): """Send an OpenID response. Args: oidresponse: OpenIDResponse The response to send, usually created by OpenIDRequest.answer(). """ logging.info('Respond: oidresponse.request.mode ' + oidresponse.request.mode) if oidresponse.request.mode in ['checkid_immediate', 'checkid_setup']: user = Auth.AuthenticatedUser(self.request) if user: from openid.extensions.sreg import SRegRequest,SRegResponse sreg_req = SRegRequest.fromOpenIDRequest(oidresponse.request) if sreg_req.wereFieldsRequested(): logging.info("sreg_req:%s",sreg_req.allRequestedFields()) user_data = {'nickname':user.nickname(), 'email':user.email} sreg_resp = SRegResponse.extractResponse(sreg_req, user_data) sreg_resp.toMessage(oidresponse.fields) # add nickname, using the Simple Registration Extension: # http://www.openidenabled.com/openid/simple-registration-extension/ #mrk # oidresponse.fields.setArg('http://openid.net/sreg/1.0', 'nickname', user.nickname()) # oidresponse.fields.setArg('http://openid.net/sreg/1.0', 'email', user.email()) pass logging.info('Using response: %s' % oidresponse) encoded_response = oidserver.encodeResponse(oidresponse) # update() would be nice, but wsgiref.headers.Headers doesn't implement it for header, value in encoded_response.headers.items(): self.response.headers[header] = str(value) if encoded_response.code in (301, 302): self.redirect(self.response.headers['location']) else: self.response.set_status(encoded_response.code) if encoded_response.body: logging.debug('Sending response body: %s' % encoded_response.body) self.response.out.write(encoded_response.body) else: self.response.out.write('')
def test_login_update_details(self): settings.OPENID_UPDATE_DETAILS_FROM_SREG = True user = User.objects.create_user('testuser', '*****@*****.**') useropenid = UserOpenID( user=user, claimed_id='http://example.com/identity', display_id='http://example.com/identity') useropenid.save() # Posting in an identity URL begins the authentication request: response = self.client.post('/openid/login/', {'openid_identifier': 'http://example.com/identity', 'next': '/getuser/'}) self.assertContains(response, 'OpenID transaction in progress') # Complete the request, passing back some simple registration # data. The user is redirected to the next URL. openid_request = self.provider.parseFormPost(response.content) sreg_request = SRegRequest.fromOpenIDRequest(openid_request) openid_response = openid_request.answer(True) sreg_response = SRegResponse.extractResponse( sreg_request, {'nickname': 'someuser', 'fullname': 'Some User', 'email': '*****@*****.**'}) openid_response.addExtension(sreg_response) response = self.complete(openid_response) self.assertRedirects(response, 'http://testserver/getuser/') # And they are now logged in as testuser (the passed in # nickname has not caused the username to change). response = self.client.get('/getuser/') self.assertEquals(response.content, 'testuser') # The user's full name and email have been updated. user = User.objects.get(username='******') self.assertEquals(user.first_name, 'Some') self.assertEquals(user.last_name, 'User') self.assertEquals(user.email, '*****@*****.**')
def get(self): """Handles GET requests.""" parsed = urlparse.urlparse(self.request.uri) request_url_without_path = parsed[0] + '://' + parsed[1] request_url_without_params = request_url_without_path + parsed[2] oidrequest = self.GetOpenIdRequest() if oidrequest is False: # there was an error, and GetOpenIdRequest displayed it. bail out. return elif oidrequest is None: # this is a request from a browser unverified_email = urllib.unquote(urlparse.urlparse(self.request.uri)[2][4:]) email_md5 = hashlib.md5(unverified_email).hexdigest() nickname = unverified_email.rsplit('@',1)[0] self.Render('index', vars()) elif oidrequest.mode in ['checkid_immediate', 'checkid_setup']: if self.HasCookie() and self.CheckUser(): logging.debug('Has cookie, confirming identity to ' + oidrequest.trust_root) self.store_login(oidrequest, 'remembered') sreg_req = SRegRequest.fromOpenIDRequest(oidrequest) self.Respond(oidrequest.answer(True, request_url_without_params), sreg_req) elif oidrequest.immediate: self.store_login(oidrequest, 'declined') oidresponse = oidrequest.answer(False, request_url_without_path) self.Respond(oidresponse) else: if self.CheckUser(): self.Render('prompt', vars()) else: email = urllib.unquote(urlparse.urlparse(self.request.uri)[2][4:]) if not email: self.ReportError('Error, no email address specified.') else: if not '@' in email or not '.' in email: self.ReportError('Error, invalid email address specified.') else: v = datastore.Entity('Verification') v['token'] = hashlib.md5(email+str(random.random())+str(time.time())).hexdigest() v['email'] = email v['expires'] = int(time.time())+1800 v['oidrequest'] = Text(pickle.dumps(self.ArgsToDict())) datastore.Put(v) mail.send_mail(sender="Email Verification <*****@*****.**>", to=email, subject="Please verify your email address", body="""You need to verify your email address to continue with your request to <%s>. To continue, follow this link: <%s/login/%s> or cut and paste the following verification code into the textbox back in your browser: %s""" % (oidrequest.trust_root, request_url_without_path, v['token'], v['token'])) self.Render('prompt', vars()) elif oidrequest.mode in ['associate', 'check_authentication']: self.Respond(oidserver.handleRequest(oidrequest)) else: self.ReportError('Unknown mode: %s' % oidrequest.mode)
def openid_auth_site(request): try: oreq = request.session['openid_request'] except KeyError: return render(request, 'openid-auth-site.html', { 'error': 'No OpenID request associated. The request may have \ expired.', }, status=400) sreg = SRegRequest.fromOpenIDRequest(oreq) ax = FetchRequest.fromOpenIDRequest(oreq) sreg_fields = set(sreg.allRequestedFields()) if ax: for uri in ax.requested_attributes: k = openid_ax_attribute_mapping.get(uri) if k: sreg_fields.add(k) ldap_user = LDAPUser.objects.get(username=request.user.username) if sreg_fields: sreg_data = { 'nickname': ldap_user.username, 'email': ldap_user.email, 'fullname': ldap_user.full_name, 'dob': ldap_user.birthday, } for k in list(sreg_data): if not sreg_data[k]: del sreg_data[k] else: sreg_data = {} sreg_fields = sreg_data.keys() # Read preferences from the db. try: saved_pref = OpenID_Attributes.objects.get( uid=ldap_user.uid, trust_root=oreq.trust_root, ) except OpenID_Attributes.DoesNotExist: saved_pref = None auto_auth = False else: auto_auth = saved_pref.always_auth if auto_auth or request.POST: if auto_auth: # TODO: can we do this nicer? form_inp = model_to_dict(saved_pref) else: form_inp = request.POST form = SiteAuthForm(form_inp, instance=saved_pref) # can it be invalid somehow? assert (form.is_valid()) attrs = form.save(commit=False) # nullify fields that were not requested for fn in form.cleaned_data: if fn in ('always_auth', ): pass elif hasattr(attrs, fn) and fn not in sreg_fields: setattr(attrs, fn, None) if auto_auth or 'accept' in request.POST: # prepare sreg response for fn, send in form.cleaned_data.items(): if fn not in sreg_data: pass elif not send: del sreg_data[fn] elif isinstance(sreg_data[fn], list): form_key = 'which_%s' % fn val = form.cleaned_data[form_key] if val not in sreg_data[fn]: raise NotImplementedError( 'Changing choices not implemented yet') sreg_data[fn] = val if not auto_auth: setattr(attrs, form_key, val) if not auto_auth: # save prefs in the db # (if auto_auth, then nothing changed) attrs.uid = ldap_user.uid attrs.trust_root = oreq.trust_root attrs.save() oresp = oreq.answer(True, identity=request.build_absolute_uri( reverse(user_page, args=(request.user.username, )))) sreg_resp = SRegResponse.extractResponse(sreg, sreg_data) oresp.addExtension(sreg_resp) if ax: ax_resp = FetchResponse(ax) for uri in ax.requested_attributes: k = openid_ax_attribute_mapping.get(uri) if k and k in sreg_data: ax_resp.addValue(uri, sreg_data[k]) oresp.addExtension(ax_resp) elif 'reject' in request.POST: oresp = oreq.answer(False) else: return render(request, 'openid-auth-site.html', { 'error': 'Invalid request submitted.', }, status=400) if request.session.get('auto_logout', False): # _logout clears request.session _logout(request) else: del request.session['openid_request'] return render_openid_response(request, oresp) form = SiteAuthForm(instance=saved_pref) sreg_form = {} # Fill in lists for choices for f in sreg_fields: if f not in sreg_data: pass elif isinstance(sreg_data[f], list): form.fields['which_%s' % f].widget.choices = [ (x, x) for x in sreg_data[f] ] sreg_form[f] = form['which_%s' % f] else: sreg_form[f] = format_html( "<input type='text'" + " readonly='readonly'" + " value='{0}' />", sreg_data[f]) try: # TODO: cache it if oreq.returnToVerified(): tr_valid = 'Return-To valid and trusted' else: tr_valid = 'Return-To untrusted' except openid.yadis.discover.DiscoveryFailure: tr_valid = 'Unable to verify trust (Yadis unsupported)' except openid.fetchers.HTTPFetchingError: tr_valid = 'Unable to verify trust (HTTP error)' return render( request, 'openid-auth-site.html', { 'openid_request': oreq, 'return_to_valid': tr_valid, 'form': form, 'sreg': sreg_fields, 'sreg_form': sreg_form, 'policy_url': sreg.policy_url, })
except ProtocolError, why: logger.error('Invalid OpenID message %s' % querydict) return oresponse_to_response(server, why) if not orequest: orequest = request.session.get('OPENID_REQUEST', None) if orequest: logger.info('Restarting saved request by %s' % orequest.trust_root) # remove session stored data: pass # del request.session['OPENID_REQUEST'] else: logger.info('No OpenID request redirecting to homepage') return HttpResponseRedirect('/') else: logger.info('Received OpenID request: %s' % querydict) sreg_request = SRegRequest.fromOpenIDRequest(orequest) logger.debug('SREG request: %s' % sreg_request.__dict__) if orequest.mode in ("checkid_immediate", "checkid_setup"): # User is not logged if not request.user.is_authenticated(): # Site does not want interaction if orequest.immediate: logger.debug('User not logged and checkid immediate request, \ returning OpenID failure') return oresponse_to_response(server, orequest.answer(False)) else: # Try to login request.session['OPENID_REQUEST'] = orequest logger.debug('User not logged and checkid request, \ redirecting to login page')
try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None class OpenIdSetupError(Exception): pass class OpenIdError(Exception): pass def get_consumer(session): if not settings.SCIPIO_STORE_ROOT: raise OpenIdSetupError('SCIPIO_STORE_ROOT is not set') return Consumer(session, FileOpenIDStore(settings.SCIPIO_STORE_ROOT)) def create_request(openid_url, session): errors = [] try: consumer = get_consumer(session) request = consumer.begin(openid_url) if request is None: errors.append(_('OpenID service is not found')) except (DiscoveryFailure, OpenIdSetupError, ValueError), e: errors.append(str(e[0])) if errors: raise OpenIdError(errors) sreg_request = SRegRequest(optional=['nickname', 'fullname']) request.addExtension(sreg_request) return request
def openid_decide(request): """ The page that asks the user if they really want to sign in to the site, and lets them add the consumer to their trusted whitelist. # If user is logged in, ask if they want to trust this trust_root # If they are NOT logged in, show the landing page """ orequest = request.session.get("OPENID_REQUEST") # No request ? Failure.. if not orequest: logger.warning( "OpenID decide view failed, \ because no OpenID request is saved" ) return redirect("auth_homepage") sreg_request = SRegRequest.fromOpenIDRequest(orequest) logger.debug("SREG request: %s" % sreg_request.__dict__) if not request.user.is_authenticated(): # Not authenticated ? Authenticate and go back to the server endpoint return login_require(request, params={NONCE_FIELD_NAME: "1"}) if request.method == "POST": if "cancel" in request.POST: # User refused logger.info("OpenID decide canceled") return redirect(openid_server, params={"cancel": ""}) else: form = DecideForm(sreg_request=sreg_request, data=request.POST) if form.is_valid(): data = form.cleaned_data # Remember the choice t, created = models.TrustedRoot.objects.get_or_create( user=request.user.id, trust_root=orequest.trust_root ) t.choices = sreg_request.required + [field for field in data if data[field]] t.save() logger.debug("OpenID decide, user choice:%s" % data) return redirect("openid-provider-root") else: form = DecideForm(sreg_request=sreg_request) logger.info("OpenID device view, orequest:%s" % orequest) # verify return_to of trust_root try: trust_root_valid = verifyReturnTo(orequest.trust_root, orequest.return_to) and "Valid" or "Invalid" except HTTPFetchingError: trust_root_valid = "Unreachable" except DiscoveryFailure: trust_root_valid = "DISCOVERY_FAILED" return render_to_response( "idp/openid/decide.html", { "title": _("Trust this site?"), "required": sreg_request.required, "optional": sreg_request.optional, "trust_root_valid": trust_root_valid, "form": form, }, context_instance=RequestContext(request), )
def openid_auth_site(request): try: oreq = request.session['openid_request'] except KeyError: return render(request, 'openid-auth-site.html', { 'error': 'No OpenID request associated. The request may have \ expired.', }, status=400) sreg = SRegRequest.fromOpenIDRequest(oreq) ax = FetchRequest.fromOpenIDRequest(oreq) sreg_fields = set(sreg.allRequestedFields()) if ax: for uri in ax.requested_attributes: k = openid_ax_attribute_mapping.get(uri) if k: sreg_fields.add(k) ldap_user = LDAPUser.objects.get(username=request.user.username) if sreg_fields: sreg_data = { 'nickname': ldap_user.username, 'email': ldap_user.email, 'fullname': ldap_user.full_name, 'dob': ldap_user.birthday, } for k in list(sreg_data): if not sreg_data[k]: del sreg_data[k] else: sreg_data = {} sreg_fields = sreg_data.keys() # Read preferences from the db. try: saved_pref = OpenID_Attributes.objects.get( uid=ldap_user.uid, trust_root=oreq.trust_root, ) except OpenID_Attributes.DoesNotExist: saved_pref = None auto_auth = False else: auto_auth = saved_pref.always_auth if auto_auth or request.POST: if auto_auth: # TODO: can we do this nicer? form_inp = model_to_dict(saved_pref) else: form_inp = request.POST form = SiteAuthForm(form_inp, instance=saved_pref) # can it be invalid somehow? assert(form.is_valid()) attrs = form.save(commit=False) # nullify fields that were not requested for fn in form.cleaned_data: if fn in ('always_auth',): pass elif hasattr(attrs, fn) and fn not in sreg_fields: setattr(attrs, fn, None) if auto_auth or 'accept' in request.POST: # prepare sreg response for fn, send in form.cleaned_data.items(): if fn not in sreg_data: pass elif not send: del sreg_data[fn] elif isinstance(sreg_data[fn], list): form_key = 'which_%s' % fn val = form.cleaned_data[form_key] if val not in sreg_data[fn]: raise NotImplementedError( 'Changing choices not implemented yet') sreg_data[fn] = val if not auto_auth: setattr(attrs, form_key, val) if not auto_auth: # save prefs in the db # (if auto_auth, then nothing changed) attrs.uid = ldap_user.uid attrs.trust_root = oreq.trust_root attrs.save() oresp = oreq.answer(True, identity=request.build_absolute_uri( reverse(user_page, args=(request.user.username,)))) sreg_resp = SRegResponse.extractResponse(sreg, sreg_data) oresp.addExtension(sreg_resp) if ax: ax_resp = FetchResponse(ax) for uri in ax.requested_attributes: k = openid_ax_attribute_mapping.get(uri) if k and k in sreg_data: ax_resp.addValue(uri, sreg_data[k]) oresp.addExtension(ax_resp) elif 'reject' in request.POST: oresp = oreq.answer(False) else: return render(request, 'openid-auth-site.html', { 'error': 'Invalid request submitted.', }, status=400) if request.session.get('auto_logout', False): # _logout clears request.session _logout(request) else: del request.session['openid_request'] return render_openid_response(request, oresp) form = SiteAuthForm(instance=saved_pref) sreg_form = {} # Fill in lists for choices for f in sreg_fields: if f not in sreg_data: pass elif isinstance(sreg_data[f], list): form.fields['which_%s' % f].widget.choices = [ (x, x) for x in sreg_data[f] ] sreg_form[f] = form['which_%s' % f] else: sreg_form[f] = format_html("<input type='text'" + " readonly='readonly'" + " value='{0}' />", sreg_data[f]) try: # TODO: cache it if oreq.returnToVerified(): tr_valid = 'Return-To valid and trusted' else: tr_valid = 'Return-To untrusted' except openid.yadis.discover.DiscoveryFailure: tr_valid = 'Unable to verify trust (Yadis unsupported)' except openid.fetchers.HTTPFetchingError: tr_valid = 'Unable to verify trust (HTTP error)' return render(request, 'openid-auth-site.html', { 'openid_request': oreq, 'return_to_valid': tr_valid, 'form': form, 'sreg': sreg_fields, 'sreg_form': sreg_form, 'policy_url': sreg.policy_url, })