hobo: store extra user attrs during provisionning (#38703) #1
|
@ -0,0 +1,35 @@
|
||||||
|
# Generated by Django 2.2.26 on 2023-01-03 09:30
|
||||||
|
|
||||||
|
import django.contrib.postgres.fields.jsonb
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('common', '0004_alter_role_uuid'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserExtraAttributes',
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
'id',
|
||||||
|
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||||
|
),
|
||||||
|
('data', django.contrib.postgres.fields.jsonb.JSONField(default=dict)),
|
||||||
|
(
|
||||||
|
'user',
|
||||||
|
models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name='extra_attributes',
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,5 +1,6 @@
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.contrib.postgres.fields import ArrayField
|
from django.contrib.postgres.fields import ArrayField, JSONField
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,3 +12,12 @@ class Role(Group):
|
||||||
emails_to_members = models.BooleanField(default=True)
|
emails_to_members = models.BooleanField(default=True)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
|
|
||||||
|
|
||||||
|
class UserExtraAttributes(models.Model):
|
||||||
|
user = models.OneToOneField(
|
||||||
|
settings.AUTH_USER_MODEL,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='extra_attributes',
|
||||||
|
)
|
||||||
|
data = JSONField(default=dict)
|
||||||
|
|
|
@ -22,7 +22,7 @@ from django.db import IntegrityError
|
||||||
from django.db.models.query import Q
|
from django.db.models.query import Q
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
|
|
||||||
from hobo.agent.common.models import Role
|
from hobo.agent.common.models import Role, UserExtraAttributes
|
||||||
from hobo.multitenant.utils import provision_user_groups
|
from hobo.multitenant.utils import provision_user_groups
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -122,6 +122,12 @@ class NotificationProcessing:
|
||||||
mellon_user = UserSAMLIdentifier.objects.create(
|
mellon_user = UserSAMLIdentifier.objects.create(
|
||||||
user=user, issuer=saml_issuer, name_id=o['uuid']
|
user=user, issuer=saml_issuer, name_id=o['uuid']
|
||||||
)
|
)
|
||||||
|
excluded_attrs = ['roles', 'password']
|
||||||
|
|||||||
|
|
||||||
|
extra_attributes = UserExtraAttributes.objects.update_or_create(
|
||||||
|
user=user,
|
||||||
|
defaults={'data': {k: v for k, v in o.items() if k not in excluded_attrs}},
|
||||||
|
)
|
||||||
if new:
|
if new:
|
||||||
logger.info('provisionned new user %s', user_str(user))
|
logger.info('provisionned new user %s', user_str(user))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -32,12 +32,43 @@ def test_provisionning(app, db, settings):
|
||||||
'@type': 'user',
|
'@type': 'user',
|
||||||
'data': [
|
'data': [
|
||||||
{
|
{
|
||||||
|
'id': 1,
|
||||||
'uuid': 'a' * 32,
|
'uuid': 'a' * 32,
|
||||||
|
'username': 'johndoe',
|
||||||
'first_name': 'John',
|
'first_name': 'John',
|
||||||
'last_name': 'Doe',
|
'last_name': 'Doe',
|
||||||
'email': 'john.doe@example.net',
|
'email': 'john.doe@example.net',
|
||||||
'is_superuser': True,
|
'is_superuser': True,
|
||||||
|
'is_staff': True,
|
||||||
|
'is_active': True,
|
||||||
'roles': [],
|
'roles': [],
|
||||||
|
'ou': {'foo': 'bar'},
|
||||||
|
'date_joined': '2022-07-19T15:07:54.649675+02:00',
|
||||||
|
'last_login': '2023-01-03T10:56:11.552280+01:00',
|
||||||
|
'password': 'pbkdf2_sha256$150000$afVbUpBWl3v7$6D9xCdIf0lnjSGHm+BxPmkWvRvIq0vvP4c/FTFhZnkY=',
|
||||||
|
'email_verified': False,
|
||||||
|
'email_verified_date': None,
|
||||||
|
'phone': '123456',
|
||||||
|
'phone_verified_on': None,
|
||||||
|
'modified': '2023-01-03T10:59:45.103274+01:00',
|
||||||
|
'last_account_deletion_alert': None,
|
||||||
|
'deactivation': None,
|
||||||
|
'deactivation_reason': None,
|
||||||
|
'first_name_verified': False,
|
||||||
|
'last_name_verified': False,
|
||||||
|
'address': 'Somewhere',
|
||||||
|
'address_verified': False,
|
||||||
|
'zipcode': '13333',
|
||||||
|
'zipcode_verified': False,
|
||||||
|
'city': 'Marseille',
|
||||||
|
'city_verified': False,
|
||||||
|
'phone_verified': False,
|
||||||
|
'mobile': '56789',
|
||||||
|
'mobile_verified': False,
|
||||||
|
'preferred_username': 'Blue',
|
||||||
|
'preferred_username_verified': False,
|
||||||
|
'custom_attr': 'foo',
|
||||||
|
'custom_attr_verified': False,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -50,4 +81,10 @@ def test_provisionning(app, db, settings):
|
||||||
sign_url('/__provision__/?orig=%s' % 'hobo.example.invalid', 'xxx'), notification, status=200
|
sign_url('/__provision__/?orig=%s' % 'hobo.example.invalid', 'xxx'), notification, status=200
|
||||||
)
|
)
|
||||||
assert User.objects.count() == 1
|
assert User.objects.count() == 1
|
||||||
assert User.objects.get(email='john.doe@example.net')
|
|
||||||
|
user = User.objects.latest('pk')
|
||||||
|
assert user.email == 'john.doe@example.net'
|
||||||
|
|
||||||
|
excluded_attrs = ['password', 'roles']
|
||||||
|
expected_data = {k: v for k, v in notification['objects']['data'][0].items() if k not in excluded_attrs}
|
||||||
|
assert user.extra_attributes.data == expected_data
|
||||||
|
|
Loading…
Reference in New Issue
Je suis partie du principe que le stockage ne serait pas un souci et qu'à part ces deux attributs on avait pas forcément besoin de se limiter, mais on peut virer des choses.