def _run_test(username): try: result = get_account_username_split(username) self.fail("get_account_username_split did not raise an " "exception when provided username for a non unlinked " "Institution.\n'%s' returned '%s'" % (username, result)) except ValueError: pass
def link_from_profile(request, institution): """ Attempts to authenticate a CAS account for the provided institution, and links it to the current Uniauth profile if successful. """ next_url = request.GET.get('next') ticket = request.GET.get('ticket') # Ensure there is an institution with the provided slug try: institution = Institution.objects.get(slug=institution) except Institution.DoesNotExist: raise Http404 if not next_url: next_url = get_redirect_url(request, use_referer=True) # If the user is not already logged into a verified # Uniauth account, raise permission denied if not request.user.is_authenticated or is_tmp_user(request.user) \ or is_unlinked_account(request.user): raise PermissionDenied("Must be logged in as verified Uniauth user.") service_url = get_service_url(request, next_url) client = CASClient(version=2, service_url=service_url, server_url=institution.cas_server_url) # If a ticket was provided, attempt to authenticate with it if ticket: user = authenticate(request=request, institution=institution, ticket=ticket, service=service_url) # Authentication successful: link to Uniauth profile if # the institution account has not been linked yet + proceed if user: if is_unlinked_account(user): merge_model_instances(request.user, [user]) username_split = get_account_username_split(user.username) _add_institution_account(request.user.profile, username_split[1], username_split[2]) return HttpResponseRedirect(next_url) # Authentication failed: raise permission denied else: raise PermissionDenied("Verification of CAS ticket failed") # If no ticket was provided, redirect to the # login URL for the institution's CAS server else: return HttpResponseRedirect(client.get_login_url())
def get_display_id(self): """ Returns a display-friendly ID for this User, using their username. Users created via CAS authentication will have their CAS ID returned (without the cas-institution prefix), and Users with an email address for a username will have the string preceeding the "@" returned. All other users will have their raw username returned. Note that these IDs are not guaranteed to be unique. """ username = self.user.username if "@" in username: return username.split("@")[0] if username.startswith('cas-'): from uniauth.utils import get_account_username_split return get_account_username_split(username)[-1] return username
def verify_token(request, pk_base64, token): """ Verifies a token generated for validating an email address, and notifies the user whether verification was successful. """ next_url = request.GET.get('next') or request.GET.get(REDIRECT_FIELD_NAME) context = {'next_url': next_url, 'is_signup': False} user_model = get_user_model() # Attempt to get the linked email to verify try: email_pk = decode_pk(pk_base64) email = LinkedEmail.objects.get(pk=email_pk) except (TypeError, ValueError, OverflowError, user_model.DoesNotExist, LinkedEmail.DoesNotExist): email = None # In the unlikely scenario that a user is trying to sign up # with an email another verified user has as a primary email # address, reject verification immediately if email is not None and is_tmp_user(email.profile.user) and \ get_user_model().objects.filter(email=email.address).exists(): email = None # If the token successfully verifies, update the linked email if email is not None and token_generator.check_token(email, token): email.is_verified = True email.save() # If the user this email is linked to is a temporary # one, change it to a fully registered user user = email.profile.user if is_tmp_user(user) or is_unlinked_account(user): context['is_signup'] = True old_username = user.username # Change the email + username to the verified email user.email = email.address user.username = choose_username(user.email) user.save() # If the user was created via CAS, add the institution # account described by the temporary username if old_username.startswith("cas"): username_split = get_account_username_split(old_username) _add_institution_account(user.profile, username_split[1], username_split[2]) # If UNIAUTH_ALLOW_SHARED_EMAILS is False, and there were # pending LinkedEmails for this address on other accounts, # delete them if not get_setting('UNIAUTH_ALLOW_SHARED_EMAILS'): LinkedEmail.objects.filter(address=email.address, is_verified=False).delete() return render(request, 'uniauth/verification-success.html', context) # If anything went wrong, just render the failed verification template else: return render(request, 'uniauth/verification-failure.html', context)
def link_to_profile(request): """ If the user is a temporary one who was logged in via an institution (not through a Uniauth profile), offers them the choice between logging to an existing Uniauth account or creating a new one. The institution account is (eventually) linked to the Uniauth profile the user logged into / created. """ next_url = request.GET.get('next') context = _get_global_context(request) if not next_url: next_url = get_redirect_url(request) params = urlencode({'next': next_url}) context['next_url'] = next_url # If the user is not authenticated at all, redirect to login page if not request.user.is_authenticated: return HttpResponseRedirect(reverse('uniauth:login') + '?' + params) # If the user is already authenticated + verified, proceed to next page if not is_tmp_user(request.user) and not is_unlinked_account(request.user): return HttpResponseRedirect(next_url) # If the user is temporary, but was not logged in via an institution # (e.g. created through Uniauth, but not verified), redirect to signup if not is_unlinked_account(request.user): return HttpResponseRedirect(reverse('uniauth:signup') + '?' + params) # At this point, we've ensured the user is temporary and was # logged in via an institution. We just need to handle the # Login Form, if the user chooses to link to an existing account. # If it's a POST request, attempt to validate the form if request.method == "POST": form = LoginForm(request, request.POST) # Authentication successful if form.is_valid(): unlinked_user = request.user username_split = get_account_username_split(request.user.username) # Log in as the authenticated Uniauth user user = form.get_user() auth_login(request, user) # Merge the unlinked account into the logged in profile, # then add the institution account described by the username merge_model_instances(user, [unlinked_user]) _add_institution_account(user.profile, username_split[1], username_split[2]) slug = username_split[1] context['institution'] = Institution.objects.get(slug=slug) return render(request, 'uniauth/link-success.html', context) # Authentication failed: render form errors else: context['form'] = form return render(request, 'uniauth/link-to-profile.html', context) # Otherwise, render a blank Login form else: form = LoginForm(request) context['form'] = form return render(request, 'uniauth/link-to-profile.html', context)
def _run_test(username, expected_result): result = get_account_username_split(username) self.assertEqual(result[0], expected_result[0]) self.assertEqual(result[1], expected_result[1]) self.assertEqual(result[2], expected_result[2])