Validate license on login

This commit is contained in:
Christian Cueni 2019-10-23 16:08:34 +02:00
parent bceb01c5f4
commit b20917d29a
5 changed files with 71 additions and 17 deletions

View File

@ -14,7 +14,7 @@ describe('The Login Page', () => {
cy.visit('/');
cy.login(username, password);
cy.get('[data-cy=email-local-errors]').contains('ist ein Pflichtfeld');
cy.get('[data-cy=email-local-errors]').contains('E-Mail ist ein Pflichtfeld');
});
it('user sees error message if password is omitted', () => {
@ -23,7 +23,7 @@ describe('The Login Page', () => {
cy.visit('/');
cy.login(username, password);
cy.get('[data-cy=password-local-errors]').contains('ist ein Pflichtfeld');
cy.get('[data-cy=password-local-errors]').contains('Passwort ist ein Pflichtfeld');
});
it('user sees error message if credentials are invalid', () => {

View File

@ -10,6 +10,7 @@
type="text"
v-model="email"
v-validate="'required'"
data-vv-as="E-Mail"
:class="{ 'skillboxform-input__input--error': errors.has('email') }"
class="change-form__email skillbox-input skillboxform-input__input"
autocomplete="off"
@ -33,6 +34,7 @@
id="pw"
name="password"
type="password"
data-vv-as="Passwort"
v-model="password"
v-validate="'required'"
:class="{ 'skillboxform-input__input--error': errors.has('password') }"
@ -93,16 +95,24 @@ export default {
store,
{
data: {
login: { success }
login
}
}
) {
try {
if (success) {
if (login.success) {
const redirectUrl = that.$route.query.redirect ? that.$route.query.redirect : '/'
that.$router.push(redirectUrl);
} else {
that.loginError = 'Die E-Mail oder das Passwort ist falsch. Bitte versuchen Sie nochmals.';
const firstError = login.errors[0];
switch (firstError.field) {
case 'invalid_credentials':
that.loginError = 'Die E-Mail oder das Passwort ist falsch. Bitte versuchen Sie nochmals.';
break;
case 'license_inactive':
that.loginError = 'Ihre Lizenz ist nicht mehr aktiv.';
break;
}
}
} catch (e) {
console.warn(e);

View File

@ -14,7 +14,15 @@ from core.views import SetPasswordView
from registration.models import License
from registration.serializers import RegistrationSerializer
from users.models import User, Role, UserRole, SchoolClass
from users.mutations_public import MutationError, PublicFieldError
class PublicFieldError(graphene.ObjectType):
code = graphene.String()
class MutationError(graphene.ObjectType):
field = graphene.String()
errors = graphene.List(PublicFieldError)
class Registration(relay.ClientIDMutation):

View File

@ -12,14 +12,11 @@ import graphene
from django.contrib.auth import authenticate, login
from graphene import relay
class PublicFieldError(graphene.ObjectType):
code = graphene.String()
from registration.models import License
class MutationError(graphene.ObjectType):
class LoginError(graphene.ObjectType):
field = graphene.String()
errors = graphene.List(PublicFieldError)
class Login(relay.ClientIDMutation):
@ -28,17 +25,30 @@ class Login(relay.ClientIDMutation):
password_input = graphene.String()
success = graphene.Boolean()
errors = graphene.List(MutationError) # todo: change for consistency
errors = graphene.List(LoginError) # todo: change for consistency
@classmethod
def mutate_and_get_payload(cls, root, info, **kwargs):
user = authenticate(username=kwargs.get('username_input'), password=kwargs.get('password_input'))
if user is not None:
login(info.context, user)
return cls(success=True, errors=[])
else:
return cls(success=False, errors=['invalid_credentials'])
if user is None:
error = LoginError(field='invalid_credentials')
return cls(success=False, errors=[error])
user_license = None
try:
user_license = License.objects.get(licensee=user)
except License.DoesNotExist:
# current users have no license, allow them to login
pass
if user_license is not None and not user_license.license_type.active:
error = LoginError(field='license_inactive')
return cls(success=False, errors=[error])
login(info.context, user)
return cls(success=True, errors=[])
class UserMutations:

View File

@ -13,11 +13,15 @@ from graphene.test import Client
from api.schema_public import schema
from core.factories import UserFactory
from registration.factories import LicenseTypeFactory, LicenseFactory
from users.models import Role
class PasswordResetTests(TestCase):
def setUp(self):
self.user = UserFactory(username='aschi@iterativ.ch', email='aschi@iterativ.ch')
self.teacher_role = Role.objects.create(key=Role.objects.TEACHER_KEY, name="Teacher Role")
self.teacher_license_type = LicenseTypeFactory(for_role=self.teacher_role)
request = RequestFactory().post('/')
@ -62,3 +66,25 @@ class PasswordResetTests(TestCase):
result = self.make_login_mutation(self.user.email, 'test1234')
self.assertFalse(result.get('data').get('login').get('success'))
def test_user_with_active_license_can_login(self):
password = 'test123'
self.user.set_password(password)
self.user.save()
LicenseFactory(license_type=self.teacher_license_type, licensee=self.user)
result = self.make_login_mutation(self.user.email, password)
self.assertTrue(result.get('data').get('login').get('success'))
def test_user_with_inactive_license_cannot_login(self):
password = 'test123'
self.user.set_password(password)
self.user.save()
self.teacher_license_type.active = False
self.teacher_license_type.save()
LicenseFactory(license_type=self.teacher_license_type, licensee=self.user)
result = self.make_login_mutation(self.user.email, password)
self.assertFalse(result.get('data').get('login').get('success'))