def reset_password(request): ''' Password reset handling. ''' if 'email' not in load_backends(BACKENDS).keys(): messages.error( request, _('Can not reset password, email authentication is disabled!')) return redirect('login') if request.method == 'POST': form = ResetForm(request.POST) if form.is_valid(): # Force creating new session request.session.create() if request.user.is_authenticated: logout(request) request.session['password_reset'] = True return complete(request, 'email') else: return redirect('email-sent') else: form = ResetForm() return render(request, 'accounts/reset.html', { 'title': _('Password reset'), 'form': form, })
def social_complete(request, backend): """Wrapper around social_django.views.complete. - blocks access for demo user - gracefuly handle backend errors """ try: return complete(request, backend) except InvalidEmail: return auth_redirect_token(request) except AuthMissingParameter as error: return handle_missing_parameter(request, backend, error) except (AuthStateMissing, AuthStateForbidden) as error: report_error(error, request) return auth_redirect_state(request) except AuthFailed as error: report_error(error, request) return auth_fail( request, _('Authentication has failed, probably due to expired token ' 'or connection error.')) except AuthCanceled: return auth_fail(request, _('Authentication has been cancelled.')) except AuthForbidden as error: report_error(error, request) return auth_fail(request, _('Authentication has been forbidden by server.')) except AuthAlreadyAssociated: return auth_fail( request, _('Could not complete registration. The supplied authentication, ' 'email or username is already in use for another account.'))
def register(request): ''' Registration form. ''' if settings.REGISTRATION_CAPTCHA: form_class = CaptchaRegistrationForm else: form_class = RegistrationForm if request.method == 'POST': form = form_class(request.POST) if form.is_valid() and settings.REGISTRATION_OPEN: # Ensure we do registration in separate session # not sent to client request.session.create() result = complete(request, 'email') request.session.save() request.session = None return result else: form = form_class() backends = set(load_backends(BACKENDS).keys()) # Redirect if there is only one backend if len(backends) == 1 and 'email' not in backends: return redirect('social:begin', backends.pop()) return render( request, 'accounts/register.html', { 'registration_email': 'email' in backends, 'registration_backends': backends - set(['email']), 'title': _('User registration'), 'form': form, })
def reset_password(request): """Password reset handling.""" if 'email' not in load_backends(BACKENDS).keys(): messages.error( request, _('Can not reset password, email authentication is disabled!')) return redirect('login') if settings.REGISTRATION_CAPTCHA: form_class = CaptchaResetForm else: form_class = ResetForm if request.method == 'POST': form = form_class(request.POST) if form.is_valid(): # Force creating new session request.session.create() if request.user.is_authenticated: logout(request) users = User.objects.filter( email__iexact=form.cleaned_data['email']) if users.exists(): request.session['password_reset'] = True return complete(request, 'email') else: return redirect('email-sent') else: form = form_class() return render(request, 'accounts/reset.html', { 'title': _('Password reset'), 'form': form, })
def register(request): """Registration form.""" captcha_form = None if request.method == 'POST': form = RegistrationForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request, request.POST) if ((captcha_form is None or captcha_form.is_valid()) and form.is_valid() and settings.REGISTRATION_OPEN): if form.cleaned_data['email_user']: notify_account_activity(form.cleaned_data['email_user'], request, 'connect') request.session['registration-email-sent'] = True return redirect('email-sent') return complete(request, 'email') else: form = RegistrationForm() if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request) backends = set(load_backends(BACKENDS).keys()) # Redirect if there is only one backend if len(backends) == 1 and 'email' not in backends: return redirect('social:begin', backends.pop()) return render( request, 'accounts/register.html', { 'registration_email': 'email' in backends, 'registration_backends': backends - set(['email']), 'title': _('User registration'), 'form': form, 'captcha_form': captcha_form, })
def email_login(request): """Connect email.""" captcha_form = None if request.method == 'POST': form = EmailForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request, request.POST) if ((captcha_form is None or captcha_form.is_valid()) and form.is_valid()): if form.cleaned_data['email_user']: notify_account_activity(form.cleaned_data['email_user'], request, 'connect') request.session['registration-email-sent'] = True return redirect('email-sent') return complete(request, 'email') else: form = EmailForm() if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request) return render(request, 'accounts/email.html', { 'title': _('Register email'), 'form': form, 'captcha_form': captcha_form, })
def social_complete(request, backend): """Wrapper around social_django.views.complete. - blocks access for demo user - gracefuly handle backend errors """ try: return complete(request, backend) except InvalidEmail: return auth_redirect_token(request) except AuthMissingParameter as error: return handle_missing_parameter(request, backend, error) except (AuthStateMissing, AuthStateForbidden): return auth_redirect_state(request) except AuthFailed: return auth_fail(request, _( 'Authentication has failed, probably due to expired token ' 'or connection error.' )) except AuthCanceled: return auth_fail( request, _('Authentication has been cancelled.') ) except AuthForbidden: return auth_fail( request, _('Authentication has been forbidden by server.') ) except AuthAlreadyAssociated: return auth_fail(request, _( 'Could not complete registration. The supplied authentication, ' 'email or username is already in use for another account.' ))
def social_complete(request, backend): """Wrapper around social_django.views.complete. - Blocks access for demo user - Handles backend errors gracefully """ try: return complete(request, backend) except InvalidEmail: return auth_redirect_token(request) except AuthMissingParameter as error: result = handle_missing_parameter(request, backend, error) if result: return result raise except (AuthStateMissing, AuthStateForbidden) as error: report_error(error, request) return auth_redirect_state(request) except AuthFailed as error: report_error(error, request) return auth_fail( request, _('Could not authenticate, probably due to an expired token ' 'or connection error.')) except AuthCanceled: return auth_fail(request, _('Authentication cancelled.')) except AuthForbidden as error: report_error(error, request) return auth_fail(request, _('The server does not allow authentication.')) except AuthAlreadyAssociated: return auth_fail( request, _('Could not complete registration. The supplied authentication, ' 'e-mail or username is already in use for another account.'))
def login_wrapper(request, backend, *args, **kwargs): """ Handles the callback from the social django login. Updating the full name of the user, and possibly their username. Usernames are found in NTNUs LDAP server using the email to search. For some reason, some users do not have their email in the NTNU LDAP system. For these users we derive their username from the local part of their email. This will be the correct NTNU username for all students. We have yet to find an employee without their email in LDAP. :return: The landing page after login, as defined by the social django configuration. """ try: response = complete(request, backend, *args, **kwargs) except AuthStateMissing as exception: logging.warning("Authentication through Dataporten failed", exception) return HttpResponseForbidden() user = request.user data = user.social_auth.first().extra_data # Update the full name of the user user.first_name = ' '.join(data['fullname'].split()[:-1]) user.last_name = data['fullname'].split()[-1] # Try to retrieve username from NTNUs LDAP server. Otherwise use the first part of the email as the username ldap_data = get_user_details_from_email(user.email, use_cached=False) if ldap_data: user.username = ldap_data["username"] else: user.username = user.email.split('@')[0] user.save() return response
def email_login(request): """Connect email.""" captcha_form = None if request.method == 'POST': form = EmailForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request, request.POST) if ((captcha_form is None or captcha_form.is_valid()) and form.is_valid()): if form.cleaned_data['email_user']: notify_account_activity( form.cleaned_data['email_user'], request, 'connect' ) request.session['registration-email-sent'] = True return redirect('email-sent') store_userid(request) return complete(request, 'email') else: form = EmailForm() if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request) return render( request, 'accounts/email.html', { 'title': _('Register email'), 'form': form, 'captcha_form': captcha_form, } )
def lti_login_and_complete_view(request, backend, *args, **kwargs): """This is a combination login/complete due to LTI being a one step login""" if request.method != 'POST': return HttpResponseNotAllowed('POST') request.backend.start() return complete(request, backend, *args, **kwargs)
def social_complete(request, backend): """Wrapper around social_django.views.complete. - blocks access for demo user - gracefuly handle backend errors """ # pylint: disable=too-many-branches,too-many-return-statements def fail(message): messages.error(request, message) return redirect(reverse('login')) def redirect_token(): return fail(_( 'Failed to verify your registration! ' 'Probably the verification token has expired. ' 'Please try the registration again.' )) def redirect_state(): return fail( _('Authentication failed due to invalid session state.') ) try: return complete(request, backend) except InvalidEmail: return redirect_token() except AuthMissingParameter as error: report_error(error, sys.exc_info()) if error.parameter in ('email', 'user', 'expires'): return redirect_token() if error.parameter in ('state', 'code'): return redirect_state() if error.parameter == 'demo': return fail( _('Can not change authentication for demo!') ) if error.parameter == 'disabled': return fail( _('New registrations are disabled!') ) raise except (AuthStateMissing, AuthStateForbidden): return redirect_state() except AuthFailed: return fail(_( 'Authentication has failed, probably due to expired token ' 'or connection error.' )) except AuthCanceled: return fail(_('Authentication has been cancelled.')) except AuthForbidden: return fail(_('Authentication has been forbidden by server.')) except AuthAlreadyAssociated: return fail(_( 'Failed to complete your registration! This authentication, ' 'email or username is already associated with another account!' ))
def social_complete(request, backend): """Wrapper around social_django.views.complete. - blocks access for demo user - gracefuly handle backend errors """ # pylint: disable=too-many-branches,too-many-return-statements def fail(message): messages.error(request, message) return redirect(reverse('login')) def redirect_token(): return fail(_( 'Failed to verify your registration! ' 'Probably the verification token has expired. ' 'Please try the registration again.' )) def redirect_state(): return fail( _('Authentication failed due to invalid session state.') ) try: return complete(request, backend) except InvalidEmail: return redirect_token() except AuthMissingParameter as error: if error.parameter in ('email', 'user', 'expires'): return redirect_token() elif error.parameter in ('state', 'code'): return redirect_state() elif error.parameter == 'demo': return fail( _('Can not change authentication for demo!') ) elif error.parameter == 'disabled': return fail( _('New registrations are disabled!') ) raise except (AuthStateMissing, AuthStateForbidden): return redirect_state() except AuthFailed: return fail(_( 'Authentication has failed, probably due to expired token ' 'or connection error.' )) except AuthCanceled: return fail(_('Authentication has been cancelled.')) except AuthForbidden: return fail(_('Authentication has been forbidden by server.')) except AuthAlreadyAssociated: return fail(_( 'Failed to complete your registration! This authentication, ' 'email or username are already associated with another account!' ))
def social_complete(request, backend): """Wrapper around social_django.views.complete. - Handles backend errors gracefully - Intermediate page (autosubmitted by javascript) to avoid confirmations by bots """ if ( 'partial_token' in request.GET and 'verification_code' in request.GET and 'confirm' not in request.GET ): return render( request, 'accounts/token.html', { 'partial_token': request.GET['partial_token'], 'verification_code': request.GET['verification_code'], 'backend': backend, }, ) try: return complete(request, backend) except InvalidEmail: return auth_redirect_token(request) except AuthMissingParameter as error: result = handle_missing_parameter(request, backend, error) if result: return result raise except (AuthStateMissing, AuthStateForbidden) as error: report_error(error, request) return auth_redirect_state(request) except AuthFailed as error: report_error(error, request) return auth_fail( request, _( 'Could not authenticate, probably due to an expired token ' 'or connection error.' ), ) except AuthCanceled: return auth_fail(request, _('Authentication cancelled.')) except AuthForbidden as error: report_error(error, request) return auth_fail(request, _('The server does not allow authentication.')) except AuthAlreadyAssociated: return auth_fail( request, _( 'Could not complete registration. The supplied authentication, ' 'e-mail or username is already in use for another account.' ), )
def save(self, request, commit=True): """ This form calls to `complete` function of python-social-auth. Send email to the user with confirmation link when user changes his email. :param request: django request :param commit: save to db or not? :return: """ if self.initial['email'] != self.cleaned_data['email']: return complete(request, 'email', force_update=True)
def login_wrapper(request, backend, *args, **kwargs): response = complete(request, backend, *args, **kwargs) user = request.user if not user.first_name: try: data = user.social_auth.first().extra_data user.first_name = ' '.join(data['fullname'].split()[:-1]) user.last_name = data['fullname'].split()[-1] user.username = user.email.split('@')[0] user.save() except: pass return response
def email_login(request): """Connect email.""" if request.method == 'POST': form = EmailForm(request.POST) if form.is_valid(): return complete(request, 'email') else: form = EmailForm() return render(request, 'accounts/email.html', { 'title': _('Register email'), 'form': form, })
def invite_user(request, project): """Invite user to a project.""" obj, form = check_user_form(request, project, True, form_class=InviteUserForm) if form is not None: try: user = form.save() obj.add_user(user) Change.objects.create( project=obj, action=Change.ACTION_INVITE_USER, user=request.user, details={'username': user.username}, ) fake = HttpRequest() fake.user = get_anonymous() fake.method = 'POST' fake.session = create_session() fake.session['invitation_context'] = { 'from_user': request.user.full_name, 'project_name': obj.name, } fake.POST['email'] = form.cleaned_data['email'] fake.META = request.META store_userid(fake, invite=True) complete(fake, 'email') messages.success(request, _('User has been invited to this project.')) except Group.DoesNotExist: messages.error(request, _('Failed to find group to add a user!')) return redirect( 'manage-access', project=obj.slug, )
def reset_password(request): """Password reset handling.""" if request.user.is_authenticated: redirect_profile() if 'email' not in load_backends(BACKENDS).keys(): messages.error( request, _('Can not reset password, email authentication is disabled!') ) return redirect('login') captcha = None # We're already in the reset phase if 'perform_reset' in request.session: return reset_password_set(request) elif request.method == 'POST': form = ResetForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha = CaptchaForm(request, form, request.POST) if (captcha is None or captcha.is_valid()) and form.is_valid(): if form.cleaned_data['email_user']: rate_limited = notify_account_activity( form.cleaned_data['email_user'], request, 'reset-request' ) if not rate_limited: request.session['password_reset'] = True store_userid(request) return complete(request, 'email') request.session['registration-email-sent'] = True return redirect('email-sent') else: form = ResetForm() if settings.REGISTRATION_CAPTCHA: captcha = CaptchaForm(request) return render( request, 'accounts/reset.html', { 'title': _('Password reset'), 'form': form, 'captcha_form': captcha, 'second_stage': False, } )
def nhsid_complete(request, *args, **kwargs): """ Return the complete view with expected arguments. A successful authentication from NHS ID returns to /auth. social_django expects to find the backend name in the url (by default /complete/<backend>) """ backend = "nhsid" uri = reverse("gateway:nhsid_complete") request.social_strategy = load_strategy(request) request.backend = load_backend(request.social_strategy, backend, uri) completed = complete(request, backend, *args, **kwargs) logger.info("User logged in", user_id=request.user.pk, username=request.user.username) return completed
def login_wrapper(request, backend, *args, **kwargs): # Needs to be called to fetch the user's Feide data (available through `social_auth`) _response = social_views.complete(request, backend, *args, **kwargs) user = request.user data = user.social_auth.first().extra_data if not user.get_full_name(): # Update the full name of the user user.first_name = " ".join(data["fullname"].split()[:-1]) user.last_name = data["fullname"].split()[-1] user.save() token, _created = Token.objects.get_or_create(user=user) response = redirect(settings.FRONTEND_URL, permanent=True) response.set_cookie("token", token.key, domain=settings.COOKIE_DOMAIN) return response
def reset_password(request): """Password reset handling.""" if 'email' not in load_backends(BACKENDS).keys(): messages.error( request, _('Can not reset password, email authentication is disabled!') ) return redirect('login') captcha_form = None if request.method == 'POST': form = ResetForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request, request.POST) if ((captcha_form is None or captcha_form.is_valid()) and form.is_valid()): # Force creating new session request.session.create() if request.user.is_authenticated: logout(request) if form.cleaned_data['email_user']: request.session['password_reset'] = True store_userid(request) return complete(request, 'email') else: request.session['registration-email-sent'] = True return redirect('email-sent') else: form = ResetForm() if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request) return render( request, 'accounts/reset.html', { 'title': _('Password reset'), 'form': form, 'captcha_form': captcha_form, } )
def register(request): """Registration form.""" captcha_form = None if request.method == 'POST': form = RegistrationForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request, request.POST) if ((captcha_form is None or captcha_form.is_valid()) and form.is_valid() and settings.REGISTRATION_OPEN): if form.cleaned_data['email_user']: notify_account_activity( form.cleaned_data['email_user'], request, 'connect' ) request.session['registration-email-sent'] = True return redirect('email-sent') store_userid(request) return complete(request, 'email') else: form = RegistrationForm() if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request) backends = set(load_backends(BACKENDS).keys()) # Redirect if there is only one backend if len(backends) == 1 and 'email' not in backends: return redirect('social:begin', backends.pop()) return render( request, 'accounts/register.html', { 'registration_email': 'email' in backends, 'registration_backends': backends - set(['email']), 'title': _('User registration'), 'form': form, 'captcha_form': captcha_form, } )
def wrapper(request, *args, **kwargs): import logging logger = logging.getLogger(__name__) logger.info('facebook-decorator') logger.info(request.user) user = request.user # User must me logged via FB backend in order to ensure we talk about # the same person if not is_complete_authentication(request): try: user = complete(request, FacebookAppOAuth2.name) logger.info('complete user') logger.info(user) logger.info(request.user) logger.info('-------') except ValueError: logger.info('could not complete user') # pass # no matter if failed # Not recommended way for FB, but still something we need to be aware # of if isinstance(user, HttpResponse): kwargs.update({'auth_response': user}) else: # Need to re-check the completion if is_complete_authentication(request): kwargs.update({'access_token': get_access_token(request.user)}) else: request.user = AnonymousUser() if hasattr(request, 'backend'): signed_request = request.backend.load_signed_request( request.POST.get('signed_request', '') ) if signed_request: kwargs.update({'signed_request': signed_request}) return func(request, *args, **kwargs)
def reset_password(request): """Password reset handling.""" if 'email' not in load_backends(BACKENDS).keys(): messages.error( request, _('Can not reset password, email authentication is disabled!')) return redirect('login') captcha_form = None if request.method == 'POST': form = ResetForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request, request.POST) if ((captcha_form is None or captcha_form.is_valid()) and form.is_valid()): # Force creating new session request.session.create() if request.user.is_authenticated: logout(request) if form.cleaned_data['email_user']: request.session['password_reset'] = True store_userid(request) return complete(request, 'email') else: request.session['registration-email-sent'] = True return redirect('email-sent') else: form = ResetForm() if settings.REGISTRATION_CAPTCHA: captcha_form = CaptchaForm(request) return render(request, 'accounts/reset.html', { 'title': _('Password reset'), 'form': form, 'captcha_form': captcha_form, })
def login_wrapper(request, backend, *args, **kwargs): response = complete(request, backend, *args, **kwargs) run_handlers(request.user) return response
def get(self, request, *args, **kwargs): backend = kwargs.pop('backend') return complete(request, backend, *args, **kwargs)
def social_complete(request, backend): """Wrapper around social_django.views.complete. - Handles backend errors gracefully - Intermediate page (autosubmitted by JavaScript) to avoid confirmations by bots - Restores session from authid for some backends (see social_auth) """ if "authid" in request.GET and not request.session.session_key: try: session_key, ip_address = loads(request.GET["authid"], max_age=600, salt="weblate.authid") except (BadSignature, SignatureExpired): return auth_redirect_token(request) if ip_address != get_ip_address(request): return auth_redirect_token(request) engine = import_module(settings.SESSION_ENGINE) request.session = engine.SessionStore(session_key) if ("partial_token" in request.GET and "verification_code" in request.GET and "confirm" not in request.GET): return render( request, "accounts/token.html", { "partial_token": request.GET["partial_token"], "verification_code": request.GET["verification_code"], "backend": backend, }, ) try: return complete(request, backend) except InvalidEmail: return auth_redirect_token(request) except AuthMissingParameter as error: report_error() result = handle_missing_parameter(request, backend, error) if result: return result raise except (AuthStateMissing, AuthStateForbidden): report_error() return auth_redirect_state(request) except AuthFailed: report_error() return auth_fail( request, _("Could not authenticate, probably due to an expired token " "or connection error."), ) except AuthCanceled: report_error() return auth_fail(request, _("Authentication cancelled.")) except AuthForbidden: report_error() return auth_fail(request, _("The server does not allow authentication.")) except AuthAlreadyAssociated: return auth_fail( request, _("Could not complete registration. The supplied authentication, " "e-mail address or username is already in use for another account." ), )