Skip to content

Commit

Permalink
Merge pull request #100 from tesla-ce/add_tests
Browse files Browse the repository at this point in the history
Implemented client change password method
  • Loading branch information
xbaro authored Oct 26, 2021
2 parents b5ec9cb + c9ac803 commit f668adc
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
24 changes: 21 additions & 3 deletions src/tesla_ce/apps/api/v2/serializers/admin/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from tesla_ce.models import User
from tesla_ce.models import InstitutionUser
from tesla_ce import get_default_client


class UserSerializer(serializers.ModelSerializer):
Expand All @@ -43,7 +44,7 @@ class UserSerializer(serializers.ModelSerializer):
institution = serializers.SerializerMethodField(read_only=True)
roles = serializers.SerializerMethodField(read_only=True)
institution_id = serializers.IntegerField(write_only=True, allow_null=True, default=None)
login_allowed = serializers.BooleanField(write_only=True, default=True, allow_null=True)
login_allowed = serializers.BooleanField(required=False, default=True, allow_null=False)
uid = serializers.CharField(write_only=True, default=None, allow_null=True)

is_staff = serializers.BooleanField(required=False, allow_null=False, default=False)
Expand Down Expand Up @@ -156,8 +157,11 @@ def create(self, validated_data):
del validated_data['uid']
if 'login_allowed' in validated_data:
del validated_data['login_allowed']

new_password = None
if 'password' in validated_data:
validated_data['password'] = make_password(validated_data['password'])
new_password = validated_data['password']
del validated_data['password']

user = super().create(validated_data)

Expand All @@ -166,6 +170,7 @@ def create(self, validated_data):
if not inst_data['login_allowed']:
user.set_unusable_password()
user.save()
new_password = None

# Create the related institution user
user.institutionuser = InstitutionUser(institution_id=inst_data['institution'],
Expand All @@ -179,6 +184,10 @@ def create(self, validated_data):
user.save()
user.institutionuser.refresh_from_db()

if new_password:
get_default_client().change_user_password(user.email, new_password)
user.refresh_from_db()

return user

def update(self, instance, validated_data):
Expand Down Expand Up @@ -236,5 +245,14 @@ def update(self, instance, validated_data):
instance.save()
instance.institutionuser.refresh_from_db()

return super().update(instance, validated_data)
new_password = None
if 'password' in validated_data:
new_password = validated_data['password']
del validated_data['password']

updated_user = super().update(instance, validated_data)

if new_password is not None:
get_default_client().change_user_password(updated_user.email, new_password)

return updated_user
29 changes: 26 additions & 3 deletions src/tesla_ce/apps/api/v2/serializers/institution/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from rest_framework import serializers
from rest_framework import validators

from tesla_ce import get_default_client

from tesla_ce.models import InstitutionUser
from tesla_ce.models import User

Expand All @@ -43,7 +45,7 @@ class InstitutionUserSerializer(serializers.ModelSerializer):
]
)
institution_id = serializers.HiddenField(default=None)
login_allowed = serializers.BooleanField(required=False, allow_null=True, default=False, write_only=True)
login_allowed = serializers.BooleanField(required=False, allow_null=False, default=False)
inst_admin = serializers.BooleanField(required=False, allow_null=False, default=False)
legal_admin = serializers.BooleanField(required=False, allow_null=False, default=False)
send_admin = serializers.BooleanField(required=False, allow_null=False, default=False)
Expand Down Expand Up @@ -75,12 +77,33 @@ def validate(self, attrs):
raise serializers.ValidationError('Passwords does not match')
if 'password2' in attrs:
del attrs['password2']
if 'password' in attrs:
attrs['password'] = make_password(attrs['password'])
else:
attrs['login_allowed'] = False

# Apply validators
for validator in self.get_validators():
validator(attrs, self)
return super().validate(attrs)

def create(self, validated_data):
new_user = super().create(validated_data)

if 'password' in validated_data:
if new_user.login_allowed:
get_default_client().change_user_password(new_user.email, validated_data['password'])
else:
new_user.set_unusable_password()

return new_user

def update(self, instance, validated_data):
updated_user = super().update(instance, validated_data)

if 'password' in validated_data:
if updated_user.login_allowed:
get_default_client().change_user_password(updated_user.email, validated_data['password'])
else:
updated_user.set_unusable_password()

return updated_user

28 changes: 27 additions & 1 deletion src/tesla_ce/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from .lib.exception import TeslaMissingICException
from .lib.exception import TeslaVaultException

from .models.user import get_institution_roles
from .models.user import get_institution_roles, get_institution_user

#: Client instance
_client = None
Expand Down Expand Up @@ -551,6 +551,28 @@ def validate_token(self, token):

raise TeslaAuthException('Invalid JWT token')

def change_user_password(self, email, password):
"""
Change user credentials
:param email: The user email
:type email: str
:param password: The user password
:type password: str
"""
try:
user = models.User.objects.get(email=email)
if settings.TESLA_PASSWORD_BACKEND == 'DJANGO':
user.set_password(password)
user.save()
if settings.TESLA_PASSWORD_BACKEND == 'VAULT':
# TODO: Create Vault instance
pass
except TeslaVaultException:
raise TeslaAuthException('Invalid user credentials')
except models.User.DoesNotExist:
raise TeslaAuthException('Invalid user credentials')

def verify_user(self, email, password):
"""
Validate user credentials
Expand All @@ -565,6 +587,10 @@ def verify_user(self, email, password):
"""
try:
user = models.User.objects.get(email=email)
if not user.is_staff:
inst_user = get_institution_user(user)
if inst_user is None or not inst_user.login_allowed:
raise TeslaAuthException('User is not allowed to login')
authenticated = False
if settings.TESLA_PASSWORD_BACKEND == 'DJANGO':
if user.check_password(password):
Expand Down
8 changes: 8 additions & 0 deletions src/tests/cases/utils/global_admin/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ def api_create_institution_admin(global_admin, institution):
assert 'ADMIN' in admin_user['roles']
assert admin_user['institution']['id'] == institution['id']

# Check credentials
auth_resp = client.post('/api/v2/auth/login', data={
'email': email,
'password': password
})
assert auth_resp.status_code == 200
assert 'token' in auth_resp.data

# Return credentials
return {
'email': email,
Expand Down

0 comments on commit f668adc

Please sign in to comment.