hobo: store extra user attrs during provisionning (#38703) #1

Merged
aberriot merged 1 commits from wip/38703-store-extra-attributes into main 2023-01-04 10:50:40 +01:00
4 changed files with 91 additions and 3 deletions

View File

@ -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,
),
),
],
),
]

View File

@ -1,5 +1,6 @@
from django.conf import settings
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
@ -11,3 +12,12 @@ class Role(Group):
emails_to_members = models.BooleanField(default=True)
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)

View File

@ -22,7 +22,7 @@ from django.db import IntegrityError
from django.db.models.query import Q
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
logger = logging.getLogger(__name__)
@ -122,6 +122,12 @@ class NotificationProcessing:
mellon_user = UserSAMLIdentifier.objects.create(
user=user, issuer=saml_issuer, name_id=o['uuid']
)
excluded_attrs = ['roles', 'password']
Review

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.

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.
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:
logger.info('provisionned new user %s', user_str(user))
else:

View File

@ -32,12 +32,43 @@ def test_provisionning(app, db, settings):
'@type': 'user',
'data': [
{
'id': 1,
'uuid': 'a' * 32,
'username': 'johndoe',
'first_name': 'John',
'last_name': 'Doe',
'email': 'john.doe@example.net',
'is_superuser': True,
'is_staff': True,
'is_active': True,
'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
)
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