def save(self, request, delete_session=False): notify_account_activity( self.user, request, 'password', password=self.user.password ) # Change the password password = self.cleaned_data["new_password1"] self.user.set_password(password) self.user.save(update_fields=['password']) # Updating the password logs out all other sessions for the user # except the current one. update_session_auth_hash(request, self.user) # Change key for current session request.session.cycle_key() # Invalidate password reset codes invalidate_reset_codes(self.user) if delete_session: request.session.flush() messages.success( request, _('Your password has been changed.') )
def email_login(request): """Connect email.""" captcha = None if request.method == 'POST': form = EmailForm(request.POST) if settings.REGISTRATION_CAPTCHA: captcha = CaptchaForm(request, form, request.POST) if (captcha is None or captcha.is_valid()) and form.is_valid(): email_user = form.cleaned_data['email_user'] if email_user and email_user != request.user: notify_account_activity( form.cleaned_data['email_user'], request, 'connect' ) return fake_email_sent(request) store_userid(request) return social_complete(request, 'email') else: form = EmailForm() if settings.REGISTRATION_CAPTCHA: captcha = CaptchaForm(request) return render( request, 'accounts/email.html', { 'title': _('Register email'), 'form': form, 'captcha_form': captcha, } )
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 password_reset(strategy, backend, user, social, details, weblate_action, current_partial, **kwargs): """Set unusable password on reset.""" if (strategy.request is not None and user is not None and weblate_action == 'reset'): notify_account_activity( user, strategy.request, 'reset', method=get_auth_name(backend.name), name=social.uid, password=user.password ) user.set_unusable_password() user.save(update_fields=['password']) # Remove partial pipeline, we do not need it strategy.clean_partial_pipeline(current_partial.token) # Store user ID strategy.request.session['perform_reset'] = user.pk # Set short session expiry strategy.request.session.set_expiry(90) # Redirect to form to change password return redirect('password_reset') return None
def test_notify_html_language(self): self.user.profile.language = 'cs' self.user.profile.save() request = self.get_request('/') notify_account_activity(request.user, request, 'password') self.assertEqual(len(mail.outbox), 1) # There is just one (html) alternative self.assertIn('lang="cs"', mail.outbox[0].alternatives[0][0])
def test_notify_account(self): request = self.get_request('/') notify_account_activity(request.user, request, 'password') self.assertEqual(len(mail.outbox), 1) self.assertEqual( mail.outbox[0].subject, '[Weblate] Activity on your account at Weblate' )
def make_current(self, request): if not self.is_current(): notify_account_activity( self.user, request, 'tos', date=TOS_DATE.isoformat() ) self.tos = TOS_DATE self.address = get_ip_address(request) self.user_agent = get_user_agent(request) self.save()
def notify_disconnect(strategy, backend, entries, user, **kwargs): """Store verified email.""" for social in entries: notify_account_activity( user, strategy.request, 'auth-disconnect', method=get_auth_name(backend.name), name=social.uid )
def notify_connect(strategy, backend, user, social, new_association=False, is_new=False, **kwargs): """Notify about adding new link.""" if user and not is_new: if new_association: action = 'auth-connect' else: action = 'login' notify_account_activity( user, strategy.request, action, method=get_auth_name(backend.name), name=social.uid )
def password_reset(strategy, backend, user, social, details, weblate_action, **kwargs): """Set unusable password on reset.""" if (strategy.request is not None and user is not None and weblate_action == 'reset'): user.set_unusable_password() user.save(update_fields=['password']) notify_account_activity( user, strategy.request, 'reset', method=get_auth_name(backend.name), name=social.uid )
def password(request): """Password change / set form.""" do_change = False if request.method == 'POST': change_form = PasswordConfirmForm(request, request.POST) do_change = change_form.is_valid() else: change_form = PasswordConfirmForm(request) if request.method == 'POST': form = SetPasswordForm(request.user, request.POST) if form.is_valid() and do_change: # Clear flag forcing user to set password redirect_page = '#auth' if 'show_set_password' in request.session: del request.session['show_set_password'] redirect_page = '' # Change the password user = form.save() # Updating the password logs out all other sessions for the user # except the current one. update_session_auth_hash(request, user) # Change key for current session request.session.cycle_key() messages.success( request, _('Your password has been changed.') ) notify_account_activity(request.user, request, 'password') return redirect_profile(redirect_page) else: form = SetPasswordForm(request.user) return render( request, 'accounts/password.html', { 'title': _('Change password'), 'change_form': change_form, 'form': form, } )
def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') if username and password: if not check_rate_limit(self.request): raise forms.ValidationError( _('Too many authentication attempts!') ) self.user_cache = authenticate( username=username, password=password ) if self.user_cache is None: try: notify_account_activity( try_get_user(username), self.request, 'failed-auth', method='Password', name=username, ) except User.DoesNotExist: pass rotate_token(self.request) raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login', ) elif not self.user_cache.is_active: raise forms.ValidationError( self.error_messages['inactive'], code='inactive', ) else: notify_account_activity( self.user_cache, self.request, 'login', method='Password', name=username, ) reset_rate_limit(self.request) return self.cleaned_data
def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') if username and password: if not check_rate_limit('login', self.request): raise forms.ValidationError( _('Too many authentication attempts from this location!') ) self.user_cache = authenticate( self.request, username=username, password=password ) if self.user_cache is None: for user in try_get_user(username, True): notify_account_activity( user, self.request, 'failed-auth', method=ugettext('Password'), name=username, ) rotate_token(self.request) raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login', ) elif not self.user_cache.is_active: raise forms.ValidationError( self.error_messages['inactive'], code='inactive', ) else: notify_account_activity( self.user_cache, self.request, 'login', method=ugettext('Password'), name=username, ) reset_rate_limit('login', self.request) return self.cleaned_data
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 password(request): """Password change / set form.""" do_change = False if request.method == 'POST': change_form = PasswordConfirmForm(request, request.POST) do_change = change_form.is_valid() else: change_form = PasswordConfirmForm(request) if request.method == 'POST': form = SetPasswordForm(request.user, request.POST) if form.is_valid() and do_change: # Clear flag forcing user to set password redirect_page = '#auth' if 'show_set_password' in request.session: del request.session['show_set_password'] redirect_page = '' # Change the password user = form.save() # Updating the password logs out all other sessions for the user # except the current one. update_session_auth_hash(request, user) # Change key for current session request.session.cycle_key() messages.success(request, _('Your password has been changed.')) notify_account_activity(request.user, request, 'password') return redirect_profile(redirect_page) else: form = SetPasswordForm(request.user) return render(request, 'accounts/password.html', { 'title': _('Change password'), 'change_form': change_form, 'form': form, })
def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') if username and password: if not check_rate_limit(self.request): raise forms.ValidationError( _('Too many authentication attempts!')) self.user_cache = authenticate(username=username, password=password) if self.user_cache is None: try: notify_account_activity( try_get_user(username), self.request, 'failed-auth', method='Password', name=username, ) except User.DoesNotExist: pass rotate_token(self.request) raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login', ) elif not self.user_cache.is_active: raise forms.ValidationError( self.error_messages['inactive'], code='inactive', ) else: notify_account_activity( self.user_cache, self.request, 'login', method='Password', name=username, ) reset_rate_limit(self.request) return self.cleaned_data
def register(request): """Registration form.""" captcha = None if request.method == 'POST': form = RegistrationForm(request, request.POST) if settings.REGISTRATION_CAPTCHA: captcha = CaptchaForm(request, form, request.POST) if ((captcha is None or captcha.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' ) return fake_email_sent(request) store_userid(request) return social_complete(request, 'email') else: form = RegistrationForm(request) if settings.REGISTRATION_CAPTCHA: captcha = CaptchaForm(request) backends = set(load_backends(social_django.utils.BACKENDS).keys()) # Redirect if there is only one backend if len(backends) == 1 and 'email' not in backends: return redirect_single(request, 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, } )
def password_reset(strategy, backend, user, social, details, weblate_action, current_partial, **kwargs): """Set unusable password on reset.""" if (strategy.request is not None and user is not None and weblate_action == 'reset'): notify_account_activity(user, strategy.request, 'reset', method=get_auth_name(backend.name), name=social.uid, password=user.password) user.set_unusable_password() user.save(update_fields=['password']) # Remove partial pipeline, we do not need it strategy.clean_partial_pipeline(current_partial.token) # Store user ID strategy.request.session['perform_reset'] = user.pk # Set short session expiry strategy.request.session.set_expiry(90) # Redirect to form to change password return redirect('password_reset')
def save(self, request, delete_session=False): notify_account_activity(self.user, request, 'password', password=self.user.password) # Change the password password = self.cleaned_data["new_password1"] self.user.set_password(password) self.user.save(update_fields=['password']) if delete_session: request.session.flush() else: # Updating the password logs out all other sessions for the user # except the current one. update_session_auth_hash(request, self.user) # Change key for current session request.session.cycle_key() messages.success(request, _('Your password has been changed.'))
def clean(self): username = self.cleaned_data.get('username') password = self.cleaned_data.get('password') if username and password: if not check_rate_limit('login', self.request): raise forms.ValidationError( _('Too many authentication attempts from this location!')) self.user_cache = authenticate(self.request, username=username, password=password) if self.user_cache is None: for user in try_get_user(username, True): notify_account_activity( user, self.request, 'failed-auth', method=ugettext('Password'), name=username, ) rotate_token(self.request) raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login', ) elif not self.user_cache.is_active: raise forms.ValidationError( self.error_messages['inactive'], code='inactive', ) else: notify_account_activity( self.user_cache, self.request, 'login', method=ugettext('Password'), name=username, ) reset_rate_limit('login', self.request) return self.cleaned_data
def remove_user(user, request): """Remove user account.""" # Send signal (to commit any pending changes) user_pre_delete.send(instance=user, sender=user.__class__) # Store activity log and notify notify_account_activity(user, request, 'removed') # Remove any email validation codes Code.objects.filter(email__in=get_all_user_mails(user)).delete() # Change username user.username = '******'.format(user.pk) user.email = 'noreply+{}@weblate.org'.format(user.pk) while User.objects.filter(username=user.username).exists(): user.username = '******'.format( user.pk, binascii.b2a_hex(os.urandom(5)) ) while User.objects.filter(email=user.email).exists(): user.email = 'noreply+{0}-{1}@weblate.org'.format( user.pk, binascii.b2a_hex(os.urandom(5)) ) # Remove user information user.full_name = 'Deleted User' # Disable the user user.is_active = False user.set_unusable_password() user.save() # Remove all social auth associations user.social_auth.all().delete() # Remove user from all groups user.groups.clear()
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 reset_password(request): """Password reset handling.""" if request.user.is_authenticated: redirect_profile() if 'email' not in load_backends(social_django.utils.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) if 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: store_userid(request, True) return social_complete(request, 'email') return fake_email_sent(request, True) 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 password(request): """Password change / set form.""" if settings.DEMO_SERVER and request.user.username == 'demo': return deny_demo(request) do_change = False attempts = request.session.get('auth_attempts', 0) if not request.user.has_usable_password(): do_change = True change_form = None elif request.method == 'POST': if attempts >= settings.AUTH_MAX_ATTEMPTS: logout(request) messages.error(request, _('Too many authentication attempts!')) return redirect('login') else: change_form = PasswordChangeForm(request.POST) if change_form.is_valid(): cur_password = change_form.cleaned_data['password'] do_change = request.user.check_password(cur_password) if not do_change: request.session['auth_attempts'] = attempts + 1 messages.error(request, _('You have entered an invalid password.')) rotate_token(request) else: request.session['auth_attempts'] = 0 else: change_form = PasswordChangeForm() if request.method == 'POST': form = SetPasswordForm(request.user, request.POST) if form.is_valid() and do_change: # Clear flag forcing user to set password redirect_page = '#auth' if 'show_set_password' in request.session: del request.session['show_set_password'] redirect_page = '' # Change the password user = form.save() # Updating the password logs out all other sessions for the user # except the current one. update_session_auth_hash(request, user) # Change key for current session request.session.cycle_key() messages.success(request, _('Your password has been changed.')) notify_account_activity(request.user, request, 'password') return redirect_profile(redirect_page) else: form = SetPasswordForm(request.user) return render(request, 'accounts/password.html', { 'title': _('Change password'), 'change_form': change_form, 'form': form, })
def test_notify_account(self): request = self.get_request('/') notify_account_activity(request.user, request, 'password') self.assertEqual(len(mail.outbox), 1) self.assert_notify_mailbox(mail.outbox[0])
def test_notify_account(self): request = self.get_request() notify_account_activity(request.user, request, 'password') self.assertEqual(len(mail.outbox), 1) self.assert_notify_mailbox(mail.outbox[0])
def ensure_valid(strategy, backend, user, registering_user, weblate_action, weblate_expires, new_association, details, **kwargs): """Ensure the activation link is still.""" # Didn't the link expire? if weblate_expires < time.time(): raise AuthMissingParameter(backend, 'expires') # We allow password reset for unauthenticated users if weblate_action == 'reset': if strategy.request.user.is_authenticated: messages.warning( strategy.request, _('You can not complete password reset while logged in!') ) messages.warning( strategy.request, _('The registration link has been invalidated.') ) raise AuthMissingParameter(backend, 'user') return # Add email/register should stay on same user if user and user.is_authenticated: current_user = user.pk else: current_user = None if current_user != registering_user: if registering_user is None: messages.warning( strategy.request, _('You can not complete registration while logged in!') ) else: messages.warning( strategy.request, _('You can confirm your registration only while logged in!') ) messages.warning( strategy.request, _('The registration link has been invalidated.') ) raise AuthMissingParameter(backend, 'user') # Verify if this mail is not used on other accounts if new_association: same = VerifiedEmail.objects.filter( email=details['email'] ) if user: same = same.exclude(social__user=user) if same.exists(): notify_account_activity( same[0].social.user, strategy.request, 'connect' ) raise AuthAlreadyAssociated(backend, 'Email exists')
def test_notify_account(self): request = self.get_request('/') notify_account_activity(request.user, request, 'password') self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, '[Weblate] Activity on your account at Weblate')