Add password reset tests
This commit is contained in:
parent
46518a22f8
commit
7e92753977
|
|
@ -7,6 +7,8 @@
|
|||
#
|
||||
# Created on 2019-10-01
|
||||
# @author: chrigu <christian.cueni@iterativ.ch>
|
||||
import re
|
||||
|
||||
import graphene
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.contrib.auth.forms import PasswordResetForm
|
||||
|
|
@ -60,10 +62,14 @@ class PasswordReset(relay.ClientIDMutation):
|
|||
except User.DoesNotExist:
|
||||
return cls(success=False, errors=['invalid_email'])
|
||||
|
||||
password_reset_view = PasswordResetView()
|
||||
password_reset_view.request = info.context
|
||||
form = password_reset_view.form_class({'email': user.email})
|
||||
|
||||
if not form.is_valid():
|
||||
return cls(success=False, errors=form.errors)
|
||||
|
||||
try:
|
||||
password_reset_view = PasswordResetView(request=info.context)
|
||||
form = password_reset_view.form_class({'email': user.email})
|
||||
form.is_valid()
|
||||
password_reset_view.form_valid(form)
|
||||
except Exception:
|
||||
return cls(success=False, errors=['email_error'])
|
||||
|
|
@ -119,9 +125,12 @@ class PasswordResetSetPassword(relay.ClientIDMutation, PasswordConfirm):
|
|||
|
||||
# fake ordinary POST for view
|
||||
info.context.POST = {
|
||||
'new_password1': new_password,
|
||||
'new_password2': confirm_new_password_input
|
||||
}
|
||||
'new_password1': new_password,
|
||||
'new_password2': confirm_new_password_input
|
||||
}
|
||||
|
||||
if not cls.verify_strong_password(new_password):
|
||||
return cls(success=False, errors=['invalid_passwords'])
|
||||
|
||||
http_response = cls.verify_token_and_uidb64(INTERNAL_RESET_URL_TOKEN, uidb64, info.context)
|
||||
|
||||
|
|
@ -130,6 +139,17 @@ class PasswordResetSetPassword(relay.ClientIDMutation, PasswordConfirm):
|
|||
else:
|
||||
return cls(success=False, errors=['invalid_passwords']) # todo: check error from form
|
||||
|
||||
@classmethod
|
||||
def verify_strong_password(cls, password):
|
||||
if len(password) == 0:
|
||||
return password
|
||||
|
||||
has_number = re.search('\d', password)
|
||||
has_upper = re.search('[A-Z]', password)
|
||||
has_lower = re.search('[a-z]', password)
|
||||
has_special = re.search('[!@#$%^&*(),.?":{}|<>\+]', password)
|
||||
|
||||
return has_number and has_upper and has_lower and has_special
|
||||
|
||||
class UserMutations:
|
||||
login = Login.Field()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,136 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ITerativ GmbH
|
||||
# http://www.iterativ.ch/
|
||||
#
|
||||
# Copyright (c) 2019 ITerativ GmbH. All rights reserved.
|
||||
#
|
||||
# Created on 2019-10-02
|
||||
# @author: chrigu <christian.cueni@iterativ.ch>
|
||||
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.core import mail
|
||||
from django.test import TestCase, RequestFactory
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.utils.http import urlsafe_base64_encode
|
||||
from graphene.test import Client
|
||||
|
||||
from api.schema_public import schema
|
||||
from core.factories import UserFactory
|
||||
|
||||
|
||||
class PasswordResetTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory(username='aschi')
|
||||
|
||||
request = RequestFactory().post('/')
|
||||
|
||||
# adding session
|
||||
middleware = SessionMiddleware()
|
||||
middleware.process_request(request)
|
||||
request.session.save()
|
||||
self.client = Client(schema=schema, context_value=request)
|
||||
|
||||
def make_reset_mutation(self, email):
|
||||
mutation = '''
|
||||
mutation PasswordReset($input: PasswordResetInput!){
|
||||
passwordReset(input: $input) {
|
||||
success
|
||||
errors {
|
||||
field
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
return self.client.execute(mutation, variables={
|
||||
'input': {
|
||||
'emailInput': email
|
||||
}
|
||||
})
|
||||
|
||||
def make_set_verify_mutation(self, uidb64, token):
|
||||
mutation = '''
|
||||
mutation PasswordResetVerify($input: PasswordResetVerifyInput!){
|
||||
passwordResetVerify(input: $input) {
|
||||
success
|
||||
errors {
|
||||
field
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
return self.client.execute(mutation, variables={
|
||||
'input': {
|
||||
'uidb64Input': uidb64,
|
||||
'tokenInput': token
|
||||
}
|
||||
})
|
||||
|
||||
def make_set_password_mutation(self, uidb64, new_password, new_password_confirm):
|
||||
mutation = '''
|
||||
mutation PasswordResetSetPassword($input: PasswordResetSetPasswordInput!){
|
||||
passwordResetSetPassword(input: $input) {
|
||||
success
|
||||
errors {
|
||||
field
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
return self.client.execute(mutation, variables={
|
||||
'input': {
|
||||
'uidb64Input': uidb64,
|
||||
'newPasswordInput': new_password,
|
||||
'confirmNewPasswordInput': new_password_confirm,
|
||||
}
|
||||
})
|
||||
|
||||
def test_user_can_initiate_password(self):
|
||||
result = self.make_reset_mutation(self.user.email)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].subject.startswith('Passwort auf'), True)
|
||||
self.assertEqual(result.get('data').get('passwordReset').get('success'), True)
|
||||
|
||||
def test_user_can_verify_and_set_password(self):
|
||||
token_generator = PasswordResetTokenGenerator()
|
||||
token = token_generator.make_token(self.user)
|
||||
uidb64 = urlsafe_base64_encode(force_bytes(self.user.pk)).decode()
|
||||
|
||||
result = self.make_set_verify_mutation(uidb64, token)
|
||||
self.assertEqual(result.get('data').get('passwordResetVerify').get('success'), True)
|
||||
|
||||
new_password = 'Abcd1234!'
|
||||
|
||||
set_result = self.make_set_password_mutation(uidb64, new_password, new_password)
|
||||
print(set_result)
|
||||
self.assertEqual(set_result.get('data').get('passwordResetSetPassword').get('success'), True)
|
||||
|
||||
def test_user_cannot_use_unsafe_password(self):
|
||||
token_generator = PasswordResetTokenGenerator()
|
||||
token = token_generator.make_token(self.user)
|
||||
uidb64 = urlsafe_base64_encode(force_bytes(self.user.pk)).decode()
|
||||
|
||||
result = self.make_set_verify_mutation(uidb64, token)
|
||||
self.assertEqual(result.get('data').get('passwordResetVerify').get('success'), True)
|
||||
|
||||
new_password = 'test'
|
||||
|
||||
set_result = self.make_set_password_mutation(uidb64, new_password, new_password)
|
||||
self.assertEqual(set_result.get('data').get('passwordResetSetPassword').get('success'), False)
|
||||
|
||||
def test_new_passwords_must_match(self):
|
||||
token_generator = PasswordResetTokenGenerator()
|
||||
token = token_generator.make_token(self.user)
|
||||
uidb64 = urlsafe_base64_encode(force_bytes(self.user.pk)).decode()
|
||||
|
||||
result = self.make_set_verify_mutation(uidb64, token)
|
||||
self.assertEqual(result.get('data').get('passwordResetVerify').get('success'), True)
|
||||
|
||||
new_password = 'Abcd1234!'
|
||||
new_password_confirm = 'Abcd1234!1'
|
||||
|
||||
set_result = self.make_set_password_mutation(uidb64, new_password, new_password_confirm)
|
||||
self.assertEqual(set_result.get('data').get('passwordResetSetPassword').get('success'), False)
|
||||
Loading…
Reference in New Issue