def test_client_credentials_400_for_get_request(self): client_id = "test" client_secret = "secret" client_user = self.setup_user(authenticate=False) application = Application.objects.create( client_id=client_id, client_secret=client_secret, user=client_user, authorization_grant_type=Application.GRANT_CLIENT_CREDENTIALS, name='test client app') ApplicationInfo.objects.create(application=application, allowed_scopes='rw:issuer') request_data = dict(grant_type='client_credentials', client_id=application.client_id, client_secret=client_secret, scope='rw:issuer') # Including query parameters is just wrong for the token claim process. response = self.client.post(set_url_query_params( reverse('oauth2_provider_token'), **request_data), data=request_data) self.assertEqual(response.status_code, 400) # It is not ok to include all the data in query params response = self.client.post( set_url_query_params(reverse('oauth2_provider_token'), **request_data)) self.assertEqual(response.status_code, 400)
def get_email_confirmation_url(self, request, emailconfirmation, signup=False): url_name = "v1_api_user_email_confirm" temp_key = default_token_generator.make_token( emailconfirmation.email_address.user) token = "{uidb36}-{key}".format(uidb36=user_pk_to_url_str( emailconfirmation.email_address.user), key=temp_key) activate_url = OriginSetting.HTTP + reverse( url_name, kwargs={'confirm_id': emailconfirmation.key}) badgrapp = BadgrApp.objects.get_current(request=request) tokenized_activate_url = "{url}?token={token}&a={badgrapp}".format( url=activate_url, token=token, badgrapp=badgrapp.id) # Add source and signup query params to the confimation url if request: source = None if hasattr(request, 'data'): source = request.data.get('source', None) elif hasattr(request, 'session'): source = request.session.get('source', None) if source: tokenized_activate_url = set_url_query_params( tokenized_activate_url, source=source) if signup: tokenized_activate_url = set_url_query_params( tokenized_activate_url, signup="true") return tokenized_activate_url
def auto_provision(request, email, first_name, last_name, config): # Get/Create account and redirect with token or with error message saml2_account = Saml2Account.objects.filter(uuid=email, config=config).first() if saml2_account: return redirect(redirect_user_to_login(saml2_account.user)) try: existing_email = CachedEmailAddress.cached.get(email=email) if not existing_email.verified: # Email exists but is not verified, auto-provision account and log in new_account = saml2_new_account(email, config, first_name, last_name, request) return redirect(redirect_user_to_login(new_account)) elif existing_email.verified: # Email exists and is already verified return redirect( set_url_query_params( reverse('saml2_emailexists'), email=base64.urlsafe_b64encode( email.encode('utf-8')).decode('utf-8'))) except CachedEmailAddress.DoesNotExist: provision_data = json.dumps({ 'first_name': first_name, 'last_name': last_name, 'email': email, 'idp_name': config.slug # TODO: actual property }) return redirect( set_url_query_params( reverse('saml2_provision'), request_id=encrypt_authcode(provision_data), ))
def auto_provision(request, emails, first_name, last_name, config): # Get/Create account and redirect with token or with error message try: saml2_account = Saml2Account.objects.filter(uuid__in=emails, config=config).first() except Saml2Account.MultipleObjectsReturned: return redirect( reverse('saml2_failure', kwargs=dict(authError="Multiple SAML accounts found."))) if saml2_account: if CachedEmailAddress.objects.exclude(user=saml2_account.user).filter( email__in=emails).count() > 0: return redirect( reverse( 'saml2_failure', kwargs=dict( authError="Multiple accounts using provided emails."))) existing_emails = CachedEmailAddress.objects.filter( user=saml2_account.user).values_list('email', flat=True) processed_emails = [ee.lower() for ee in existing_emails] unused = [e for e in emails if e.lower() not in processed_emails] for e in unused: CachedEmailAddress.objects.create(email=e, user=saml2_account.user, verified=True) return redirect(redirect_user_to_login(saml2_account.user)) # Check if any/all of the claimed emails already exist as verified claimed_emails = CachedEmailAddress.cached.filter(email__in=emails, verified=True) if claimed_emails.count() > 0: # If at least one is already verified, grab the first one and redirect with error email = claimed_emails.first().email return redirect( set_url_query_params(reverse('saml2_emailexists'), email=base64.urlsafe_b64encode( email.encode('utf-8')).decode('utf-8'))) existing_email = CachedEmailAddress.cached.filter(email__in=emails).first() if existing_email: # An email exists but is not verified, auto-provision account and log in new_account = saml2_new_account(emails, config, first_name, last_name, request) return redirect(redirect_user_to_login(new_account)) else: provision_data = json.dumps({ 'first_name': first_name, 'last_name': last_name, 'emails': emails, 'idp_name': config.slug # TODO: actual property }) return redirect( set_url_query_params( reverse('saml2_provision'), request_id=encrypt_authcode(provision_data), ))
def test_put_issuer_detail_with_the_option_to_exclude_staff(self): test_user = self.setup_user(authenticate=True) test_issuer = self.setup_issuer(owner=test_user, name='1') issuer_data = { 'name': 'Testy MctestAlot', 'description': test_issuer.description, 'email': test_user.email, 'url': 'http://example.com' } staff_get_url = '/v1/issuer/issuers/{slug}/staff'.format( slug=test_issuer.entity_id) url_and_include_staff_false = set_url_query_params( '/v2/issuers/{}'.format(test_issuer.entity_id), include_staff='false') url_and_include_staff_true = set_url_query_params( '/v2/issuers/{}'.format(test_issuer.entity_id), include_staff='true') url_no_query_param = '/v2/issuers/{}'.format(test_issuer.entity_id) staff_response = self.client.get(staff_get_url) intial_staff = staff_response.data[0]['user'] # put response1 = self.client.put(url_and_include_staff_false, data=issuer_data) self.assertEqual(response1.status_code, 200) self.assertFalse(response1.data['result'][0].get('staff')) response2 = self.client.put(url_no_query_param, data=issuer_data) self.assertEqual(response2.status_code, 200) self.assertTrue(response2.data['result'][0].get('staff')) response3 = self.client.put(url_and_include_staff_true, data=issuer_data) self.assertEqual(response3.status_code, 200) self.assertTrue(response3.data['result'][0].get('staff')) # get get_response1 = self.client.get(url_and_include_staff_false) self.assertEqual(get_response1.status_code, 200) self.assertFalse(get_response1.data['result'][0].get('staff')) get_response2 = self.client.get(url_no_query_param) self.assertEqual(get_response2.status_code, 200) self.assertTrue(get_response2.data['result'][0].get('staff')) get_response3 = self.client.get(url_and_include_staff_true) self.assertEqual(get_response3.status_code, 200) self.assertTrue(get_response3.data['result'][0].get('staff')) # test that staff hasn't been modified staff_response2 = self.client.get(staff_get_url) final_staff = staff_response2.data[0]['user'] self.assertTrue(intial_staff == final_staff)
def get_authorization_redirect_url(self, scopes, credentials, allow=True): uri, headers, body, status = self.create_authorization_response( request=self.request, scopes=scopes, credentials=credentials, allow=allow) return set_url_query_params(uri, **{'scope': scopes})
def send_account_confirmation(**kwargs): if not kwargs.get('email'): return email = kwargs['email'] source = kwargs['source'] expires_seconds = getattr(settings, 'AUTH_TIMEOUT_SECONDS', 7 * 86400) payload = kwargs.copy() payload['nonce'] = ''.join( random.choice(string.ascii_uppercase) for _ in range(random.randint(20, 30))) payload = json.dumps(payload) authcode = encrypt_authcode(payload, expires_seconds=expires_seconds) confirmation_url = "{origin}{path}".format( origin=OriginSetting.HTTP, path=reverse('v2_api_account_confirm', kwargs=dict(authcode=authcode)), ) if source: confirmation_url = set_url_query_params(confirmation_url, source=source) get_adapter().send_mail( 'account/email/email_confirmation_signup', email, { 'HTTP_ORIGIN': settings.HTTP_ORIGIN, 'STATIC_URL': settings.STATIC_URL, 'MEDIA_URL': settings.MEDIA_URL, 'activate_url': confirmation_url, 'email': email, })
def error_redirect_url(self): if self.badgrapp is None: self.badgrapp = BadgrApp.objects.get_by_id_or_default() return set_url_query_params( self.badgrapp.ui_login_redirect.rstrip('/'), authError='Error validating request.')
def get_redirect_url(self): provider_name = self.request.GET.get('provider', None) if provider_name is None: raise ValidationError('No provider specified') badgr_app = BadgrApp.objects.get_current(request=self.request) if badgr_app is not None: set_session_badgr_app(self.request, badgr_app) else: raise ValidationError('Unable to save BadgrApp in session') self.request.session['source'] = self.request.GET.get('source', None) try: if 'saml2' in provider_name: redirect_url = reverse('saml2login', args=[provider_name]) else: redirect_url = reverse('{}_login'.format(provider_name)) except ( NoReverseMatch, TypeError, ): raise ValidationError('No {} provider found'.format(provider_name)) authcode = self.request.GET.get('authCode', None) if authcode is not None: set_session_authcode(self.request, authcode) return set_url_query_params(redirect_url, process=AuthProcess.CONNECT) else: return redirect_url
def redirect_user_to_login(user, token=None): if token is not None and not token.is_expired(): accesstoken = token else: accesstoken = AccessTokenProxy.objects.generate_new_token_for_user( user, scope='rw:backpack rw:profile rw:issuer') authcode = authcode_for_accesstoken(accesstoken) return set_url_query_params(reverse('saml2_success'), authcode=authcode)
def get_redirect_url(self, *args, **kwargs): badgr_app = BadgrApp.objects.get_current(self.request) if badgr_app is not None: params = { k: self.request.GET.get(k) for k in self.request.GET.keys() } return set_url_query_params(badgr_app.ui_signup_failure_redirect, **params)
def get_email_confirmation_redirect_url(self, request, badgr_app=None): """ The URL to return to after successful e-mail confirmation. """ if badgr_app is None: badgr_app = BadgrApp.objects.get_current(request) if not badgr_app: logger = logging.getLogger(self.__class__.__name__) logger.warning("Could not determine authorized badgr app") return super(BadgrAccountAdapter, self).get_email_confirmation_redirect_url(request) try: resolver_match = resolve(request.path) confirmation = EmailConfirmationHMAC.from_key( resolver_match.kwargs.get('confirm_id')) # publish changes to cache email_address = CachedEmailAddress.objects.get( pk=confirmation.email_address.pk) email_address.publish() query_params = {'email': email_address.email.encode('utf8')} # Pass source and signup along to UI source = request.query_params.get('source', None) if source: query_params['source'] = source signup = request.query_params.get('signup', None) if signup: query_params['signup'] = 'true' return set_url_query_params( badgr_app.get_path('/auth/welcome'), **query_params) else: return set_url_query_params( urllib.parse.urljoin( badgr_app.email_confirmation_redirect.rstrip('/') + '/', urllib.parse.quote( email_address.user.first_name.encode('utf8'))), **query_params) except Resolver404 as xxx_todo_changeme: EmailConfirmation.DoesNotExist = xxx_todo_changeme return badgr_app.email_confirmation_redirect
def launch(self, request, obj): if obj.authorization_grant_type != Application.GRANT_AUTHORIZATION_CODE: messages.add_message(request, messages.INFO, "This is not a Auth Code Application. Cannot Launch.") return launch_url = BadgrApp.objects.get_current().get_path('/auth/oauth2/authorize') launch_url = set_url_query_params( launch_url, client_id=obj.client_id, redirect_uri=obj.default_redirect_uri, scope=obj.applicationinfo.allowed_scopes ) return HttpResponseRedirect(launch_url)
def redirect_to_login_with_token(request, accesstoken): badgr_app = BadgrApp.objects.get_current(request) if badgr_app.use_auth_code_exchange: authcode = authcode_for_accesstoken(accesstoken) params = dict(authCode=authcode) else: params = dict(authToken=accesstoken.token) if badgr_app is not None: return set_url_query_params(badgr_app.ui_login_redirect, **params)
def get_redirect_url(self): badgr_app = BadgrApp.objects.get_current(self.request) if badgr_app is not None: verification_email = self.request.session.get('verification_email', '') provider = self.request.session.get('socialaccount_sociallogin', {}).get('account', {}).get('provider', '') return set_url_query_params( badgr_app.ui_signup_failure_redirect, authError='An account already exists with provided email address', email=base64.urlsafe_b64encode(verification_email), socialAuthSlug=provider )
def default_launch_url(self): application = self.application if application.authorization_grant_type != Application.GRANT_AUTHORIZATION_CODE: # This is not a Auth Code Application. Cannot Launch. return '' launch_url = BadgrApp.objects.get_current().get_path('/auth/oauth2/authorize') launch_url = set_url_query_params( launch_url, client_id=application.client_id, redirect_uri=application.default_redirect_uri, scope=self.allowed_scopes ) return launch_url
def login(user): accesstoken = AccessTokenProxy.objects.generate_new_token_for_user( user, scope='rw:backpack rw:profile rw:issuer') if badgr_app.use_auth_code_exchange: authcode = authcode_for_accesstoken(accesstoken) params = dict(authCode=authcode) else: params = dict(authToken=accesstoken.token) return redirect(set_url_query_params(badgr_app.ui_login_redirect, **params))
def auto_provision(request, email, first_name, last_name, badgr_app, config, idp_name): def login(user): accesstoken = AccessTokenProxy.objects.generate_new_token_for_user( user, scope='rw:backpack rw:profile rw:issuer') if badgr_app.use_auth_code_exchange: authcode = authcode_for_accesstoken(accesstoken) params = dict(authCode=authcode) else: params = dict(authToken=accesstoken.token) return redirect(set_url_query_params(badgr_app.ui_login_redirect, **params)) def new_account(email): new_user = BadgeUser.objects.create( email=email, first_name=first_name, last_name=last_name, request=request, send_confirmation=False ) # Auto verify emails cached_email = CachedEmailAddress.objects.get(email=email) cached_email.verified = True cached_email.save() Saml2Account.objects.create(config=config, user=new_user, uuid=email) return new_user # Get/Create account and redirect with token or with error message saml2_account = Saml2Account.objects.filter(uuid=email).first() if saml2_account: return login(saml2_account.user) try: existing_email = CachedEmailAddress.cached.get(email=email) if not existing_email.verified: # Email exists but is not verified, auto-provision account and log in return login(new_account(email)) Saml2Account.objects.create(config=config, user=existing_email.user, uuid=email) # Email exists and is already verified url = set_url_query_params( badgr_app.ui_signup_failure_redirect, authError='An account already exists with provided email address', email=base64.urlsafe_b64encode(email), socialAuthSlug=idp_name ) return redirect(url) except CachedEmailAddress.DoesNotExist: # Email does not exist, auto-provision account and log in return login(new_account(email))
def _initiate_login(self, idp_name, badgr_app, user=None): # Sets a BadgrApp in the session for later redirect, allows setting of a session authcode url = set_url_query_params(reverse('socialaccount_login'), provider=idp_name) if user is not None: self.client.force_authenticate(user=user) preflight_response = self.client.get( reverse('v2_api_user_socialaccount_connect') + '?provider={}'.format(idp_name)) location = urlparse(preflight_response.data['result']['url']) url = '?'.join([location.path, location.query]) # strip server info from location return self.client.get(url, HTTP_REFERER=badgr_app.ui_login_redirect)
def get_badgrapp_redirect(self, entity): badgrapp = entity.cached_badgrapp if not badgrapp or not badgrapp.public_pages_redirect: badgrapp = BadgrApp.objects.get_current(request=None) # use the default badgrapp redirect_url = badgrapp.public_pages_redirect if not redirect_url: redirect_url = 'https://{}/public/'.format(badgrapp.cors) else: if not redirect_url.endswith('/'): redirect_url += '/' path = entity.get_absolute_url() stripped_path = re.sub(r'^/public/', '', path) ret = '{redirect}{path}'.format( redirect=redirect_url, path=stripped_path) ret = set_url_query_params(ret, embedVersion=2) return ret
def get_redirect_url(self, *args, **kwargs): authcode = kwargs.get('authcode', None) if not authcode: return self.error_redirect_url() user_info = decrypt_authcode(authcode) try: user_info = json.loads(user_info) except ( TypeError, ValueError, ): user_info = None if not user_info: return self.error_redirect_url() badgrapp_id = user_info.get('badgrapp_id', None) self.badgrapp = BadgrApp.objects.get_by_id_or_default(badgrapp_id) try: email_address = CachedEmailAddress.cached.get( email=user_info.get('email')) except CachedEmailAddress.DoesNotExist: return self.error_redirect_url() user = email_address.user user.first_name = user_info.get('first_name', user.first_name) user.last_name = user_info.get('last_name', user.last_name) user.badgrapp = self.badgrapp user.marketing_opt_in = user_info.get('marketing_opt_in', user.marketing_opt_in) user.agreed_terms_version = TermsVersion.cached.latest_version() user.email_verified = True if user_info.get('plaintext_password'): user.set_password(user_info['plaintext_password']) user.save() redirect_url = urllib.parse.urljoin( self.badgrapp.email_confirmation_redirect.rstrip('/') + '/', urllib.parse.quote(user.first_name.encode('utf8'))) redirect_url = set_url_query_params( redirect_url, email=email_address.email.encode('utf8')) return redirect_url
def get_login_redirect_url(self, request): """ If successfully logged in, redirect to the front-end, including an authToken query parameter. """ if request.user.is_authenticated(): badgr_app = BadgrApp.objects.get_current(self.request) if badgr_app is not None: accesstoken = AccessTokenProxy.objects.generate_new_token_for_user( request.user, application=badgr_app.oauth_application if badgr_app.oauth_application_id else None, scope='rw:backpack rw:profile rw:issuer') if badgr_app.use_auth_code_exchange: authcode = authcode_for_accesstoken(accesstoken) params = dict(authCode=authcode) else: params = dict(authToken=accesstoken.token) return set_url_query_params(badgr_app.ui_login_redirect, **params) else: return '/'
def get_redirect_url(self, *args, **kwargs): badgr_app = BadgrApp.objects.get_current(self.request) if badgr_app is not None: return set_url_query_params(badgr_app.ui_signup_failure_redirect, **kwargs)
def get_redirect_url(self): badgr_app = BadgrApp.objects.get_current(self.request) if badgr_app is not None: return set_url_query_params(badgr_app.ui_login_redirect)
def saml2_fail(**kwargs): return set_url_query_params(reverse('saml2_failure'), **kwargs)
def auto_provision(request, email, first_name, last_name, badgr_app, config, idp_name): def login(user, token=None): if token is not None and not token.is_expired(): accesstoken = token else: accesstoken = AccessTokenProxy.objects.generate_new_token_for_user( user, scope='rw:backpack rw:profile rw:issuer') if badgr_app.use_auth_code_exchange: authcode = authcode_for_accesstoken(accesstoken) params = dict(authCode=authcode) else: params = dict(authToken=accesstoken.token) return redirect( set_url_query_params(badgr_app.ui_login_redirect, **params)) def new_account(requested_email): new_user = BadgeUser.objects.create(email=requested_email, first_name=first_name, last_name=last_name, request=request, send_confirmation=False) # Auto verify emails cached_email = CachedEmailAddress.objects.get(email=requested_email) cached_email.verified = True cached_email.save() Saml2Account.objects.create(config=config, user=new_user, uuid=requested_email) return new_user # Get/Create account and redirect with token or with error message saml2_account = Saml2Account.objects.filter(uuid=email, config=config).first() if saml2_account: return login(saml2_account.user) try: existing_email = CachedEmailAddress.cached.get(email=email) if not existing_email.verified: # Email exists but is not verified, auto-provision account and log in new_account = new_account(email) return login(new_account) elif existing_email.verified: # Email exists and is already verified # Override: user has an appropriate authcode for the return flight to the UI authcode = get_session_authcode(request) if authcode is not None: token = accesstoken_for_authcode(authcode) if token is not None and not token.is_expired( ) and token.user == existing_email.user: saml2_account = Saml2Account.objects.create( config=config, user=existing_email.user, uuid=email) return login(saml2_account.user, token) # Fail: user does not have an appropriate authcode url = set_url_query_params( badgr_app.ui_signup_failure_redirect, authError= 'An account already exists with provided email address', email=str(base64.urlsafe_b64encode(email.encode('utf-8')), 'utf'), socialAuthSlug=idp_name) return redirect(url) except CachedEmailAddress.DoesNotExist: authcode = get_session_authcode(request) if authcode is not None: token = accesstoken_for_authcode(authcode) if token is not None and not token.is_expired(): saml2_account = Saml2Account.objects.create(config=config, user=token.user, uuid=email) new_mail = CachedEmailAddress.objects.create(email=email, user=token.user, verified=True, primary=False) return login(saml2_account.user, token) # Email does not exist, nor does existing account. auto-provision new account and log in return login(new_account(email))
def assertion_consumer_service(request, idp_name): saml_client, config = saml2_client_for(idp_name) saml_response = request.POST.get('SAMLResponse') badgr_app = BadgrApp.objects.get_current(request=request) if saml_response is None: logger.error( 'assertion_consumer_service: No SAMLResponse was sent to the system by the identity provider.' ) return redirect( set_url_query_params( badgr_app.ui_signup_failure_redirect, **dict( authError= "No SAMLResponse was sent to the system by the identity provider" ))) saml_info = "assertion_consumer_service: saml_client entityid:{}, reponse: {}".format( saml_client.config.entityid, saml_response) logger.info(saml_info) authn_response = saml_client.parse_authn_request_response( saml_response, entity.BINDING_HTTP_POST) if authn_response is None: logger.error( 'assertion_consumer_service: SAMLResponse processing failed, resulting in no parsed data.' ) return redirect( set_url_query_params( badgr_app.ui_signup_failure_redirect, **dict(authError="Could not process SAMLResponse"))) authn_response.get_identity() if len(set(settings.SAML_EMAIL_KEYS) & set(authn_response.ava.keys())) == 0: raise ValidationError( 'Missing email in SAML assertions, received {}'.format( list(authn_response.ava.keys()))) if len( set(settings.SAML_FIRST_NAME_KEYS) & set(authn_response.ava.keys())) == 0: raise ValidationError( 'Missing first_name in SAML assertions, received {}'.format( list(authn_response.ava.keys()))) if len(set(settings.SAML_LAST_NAME_KEYS) & set(authn_response.ava.keys())) == 0: raise ValidationError( 'Missing last_name in SAML assertions, received {}'.format( list(authn_response.ava.keys()))) email = [ authn_response.ava[key][0] for key in settings.SAML_EMAIL_KEYS if key in authn_response.ava ][0] first_name = [ authn_response.ava[key][0] for key in settings.SAML_FIRST_NAME_KEYS if key in authn_response.ava ][0] last_name = [ authn_response.ava[key][0] for key in settings.SAML_LAST_NAME_KEYS if key in authn_response.ava ][0] return auto_provision(request, email, first_name, last_name, badgr_app, config, idp_name)
def get(self, request, **kwargs): """ Confirm an email address with a token provided in an email --- parameters: - name: token type: string paramType: form description: The token received in the recovery email required: true """ token = request.query_params.get('token', '') badgrapp_id = request.query_params.get('a') # Get BadgrApp instance badgrapp = BadgrApp.objects.get_by_id_or_default(badgrapp_id) # Get EmailConfirmation instance emailconfirmation = EmailConfirmationHMAC.from_key(kwargs.get('confirm_id')) if emailconfirmation is None: logger.event(badgrlog.NoEmailConfirmation()) return redirect_to_frontend_error_toast(request, "Your email confirmation link is invalid. Please attempt to " "create an account with this email address, again.") # 202 # Get EmailAddress instance else: try: email_address = CachedEmailAddress.cached.get( pk=emailconfirmation.email_address.pk) except CachedEmailAddress.DoesNotExist: logger.event(badgrlog.NoEmailConfirmationEmailAddress( request, email_address=emailconfirmation.email_address)) return redirect_to_frontend_error_toast(request, "Your email confirmation link is invalid. Please attempt " "to create an account with this email address, again.") # 202 if email_address.verified: logger.event(badgrlog.EmailConfirmationAlreadyVerified( request, email_address=email_address, token=token)) return redirect_to_frontend_error_toast(request, "Your email address is already verified. You may now log in.") # Validate 'token' syntax from query param matches = re.search(r'([0-9A-Za-z]+)-(.*)', token) if not matches: logger.event(badgrlog.InvalidEmailConfirmationToken( request, token=token, email_address=email_address)) email_address.send_confirmation(request=request, signup=False) return redirect_to_frontend_error_toast(request, "Your email confirmation token is invalid. You have been sent " "a new link. Please check your email and try again.") # 2 uidb36 = matches.group(1) key = matches.group(2) if not (uidb36 and key): logger.event(badgrlog.InvalidEmailConfirmationToken( request, token=token, email_address=email_address)) email_address.send_confirmation(request=request, signup=False) return redirect_to_frontend_error_toast(request, "Your email confirmation token is invalid. You have been sent " "a new link. Please check your email and try again.") # 2 # Get User instance from literal 'token' value user = self._get_user(uidb36) if user is None or not default_token_generator.check_token(user, key): logger.event(badgrlog.EmailConfirmationTokenExpired( request, email_address=email_address)) email_address.send_confirmation(request=request, signup=False) return redirect_to_frontend_error_toast(request, "Your authorization link has expired. You have been sent a new " "link. Please check your email and try again.") if email_address.user != user: logger.event(badgrlog.OtherUsersEmailConfirmationToken( request, email_address=email_address, token=token, other_user=user)) return redirect_to_frontend_error_toast(request, "Your email confirmation token is associated with an unexpected " "user. You may try again") # Perform main operation, set EmaiAddress .verified and .primary True old_primary = CachedEmailAddress.objects.get_primary(user) if old_primary is None: email_address.primary = True email_address.verified = True email_address.save() process_email_verification.delay(email_address.pk) # Create an OAuth AccessTokenProxy instance for this user accesstoken = AccessTokenProxy.objects.generate_new_token_for_user( user, application=badgrapp.oauth_application if badgrapp.oauth_application_id else None, scope='rw:backpack rw:profile rw:issuer') redirect_url = get_adapter().get_email_confirmation_redirect_url( request, badgr_app=badgrapp) if badgrapp.use_auth_code_exchange: authcode = authcode_for_accesstoken(accesstoken) redirect_url = set_url_query_params(redirect_url, authCode=authcode) else: redirect_url = set_url_query_params(redirect_url, authToken=accesstoken.token) return Response(status=HTTP_302_FOUND, headers={'Location': redirect_url})