Commit 504420f0 authored by Lukas Burgey's avatar Lukas Burgey
Browse files

Change the naming schemes of the created users

This prevents name clashes with old user instances. This was usually a
problem when the upstream IdP changed the subjects of our users.

The flow from here on is: When a user logs in with a changed subject
a new user is created. The old user remains (but is not accessable by the
user).
parent b1ca8603
...@@ -18,6 +18,8 @@ def user_info_default(): ...@@ -18,6 +18,8 @@ def user_info_default():
class User(AbstractUser): class User(AbstractUser):
USER_ALREADY_EXISTS = Exception("The user does already exist. This usually implies that the IdP changed the sub. Only possible fix: delete the old user")
TYPE_CHOICES = ( TYPE_CHOICES = (
('apiclient', 'API-Client'), ('apiclient', 'API-Client'),
('oidcuser', 'OIDC User'), ('oidcuser', 'OIDC User'),
...@@ -115,27 +117,37 @@ class User(AbstractUser): ...@@ -115,27 +117,37 @@ class User(AbstractUser):
except cls.DoesNotExist: except cls.DoesNotExist:
return cls.construct_from_userinfo(userinfo, idp) return cls.construct_from_userinfo(userinfo, idp)
@staticmethod
def unique_username(userinfo, idp):
if 'sub' not in userinfo:
raise ValueError("unique_username needs a 'sub' in the userinfo")
return "{}@{}".format(userinfo['sub'], idp.id)
@classmethod @classmethod
def construct_from_userinfo(cls, userinfo, idp): def construct_from_userinfo(cls, userinfo, idp):
if 'sub' not in userinfo: if 'sub' not in userinfo:
raise Exception('Missing attribute in userinfo: sub') raise ValueError('Missing attribute in userinfo: sub')
sub = userinfo['sub']
username = sub
email = ''
if 'email' in userinfo: username = cls.unique_username(userinfo, idp)
username = userinfo['email']
if cls.objects.filter(
username=username,
idp=idp,
).exists():
LOGGER.error('User already exists: %s', username)
raise cls.USER_ALREADY_EXISTS
user = cls( user = cls(
user_type='oidcuser', user_type='oidcuser',
username=username, username=username,
sub=sub, sub=userinfo['sub'],
email=email,
idp=idp, idp=idp,
) )
user.save() user.save()
user.update_userinfo(userinfo) user.update_userinfo(userinfo)
LOGGER.info('construct_from_userinfo: new user: %s', user)
return user return user
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment