From e84d85e88012d647b2f79cbdb13a8ac42ad5cdd9 Mon Sep 17 00:00:00 2001 From: Oliver Stolpe Date: Wed, 14 Feb 2024 16:12:59 +0100 Subject: [PATCH] fix: bug uids should be filled from upstream ldap (#154) --- Makefile | 10 ++++++++- hpcaccess/auth_backends.py | 4 ++++ hpcaccess/users/migrations/0004_user_uid.py | 18 ++++++++++++++++ hpcaccess/users/models.py | 3 ++- hpcaccess/users/tests/factories.py | 1 + ...e_hpcuser_uid_remove_hpcuserversion_uid.py | 21 +++++++++++++++++++ usersec/models.py | 5 +---- usersec/serializers.py | 5 ++++- usersec/tests/factories.py | 1 - usersec/tests/test_serializers.py | 1 + 10 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 hpcaccess/users/migrations/0004_user_uid.py create mode 100644 usersec/migrations/0017_remove_hpcuser_uid_remove_hpcuserversion_uid.py diff --git a/Makefile b/Makefile index 703404a..3f2a1f8 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ celery: celery -A config.celery_app worker -l info --beat -.PHONY: lack +.PHONY: black black: black . -l 100 --exclude '/(\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.?v?env|_build|buck-out|build|dist|src)/' $(arg) @@ -36,3 +36,11 @@ test-snap: isort: isort --force-sort-within-sections --profile=black . + +.PHONY: flake8 +flake8: + flake8 + +.PHONY: format +format: isort black flake8 + diff --git a/hpcaccess/auth_backends.py b/hpcaccess/auth_backends.py index b745839..2a75b1d 100644 --- a/hpcaccess/auth_backends.py +++ b/hpcaccess/auth_backends.py @@ -68,10 +68,14 @@ def _ldap_auth_handler(user, ldap_user, **kwargs): """Signal for LDAP login handling""" phone = ldap_user.attrs.get("telephoneNumber") + uid = ldap_user.attrs.get("uidNumber") if phone: user.phone = phone[0] + if uid: + user.uid = uid[0] + if hasattr(user, "ldap_username"): # Make domain in username uppercase if user.username.find("@") != -1 and user.username.split("@")[1].islower(): diff --git a/hpcaccess/users/migrations/0004_user_uid.py b/hpcaccess/users/migrations/0004_user_uid.py new file mode 100644 index 0000000..fe562f9 --- /dev/null +++ b/hpcaccess/users/migrations/0004_user_uid.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.10 on 2024-02-14 15:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("users", "0003_user_phone"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="uid", + field=models.IntegerField(blank=True, null=True, verbose_name="UID of User"), + ), + ] diff --git a/hpcaccess/users/models.py b/hpcaccess/users/models.py index ecf5800..9ea7436 100644 --- a/hpcaccess/users/models.py +++ b/hpcaccess/users/models.py @@ -1,5 +1,5 @@ from django.contrib.auth.models import AbstractUser -from django.db.models import BooleanField, CharField +from django.db.models import BooleanField, CharField, IntegerField from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -21,6 +21,7 @@ class User(AbstractUser): help_text=_("Designates whether the user is an HPC admin."), ) phone = CharField(_("Phone number of User"), blank=True, max_length=32) + uid = IntegerField(_("UID of User"), blank=True, null=True) def get_absolute_url(self): """Get url for user's detail view. diff --git a/hpcaccess/users/tests/factories.py b/hpcaccess/users/tests/factories.py index be6b382..28904a0 100644 --- a/hpcaccess/users/tests/factories.py +++ b/hpcaccess/users/tests/factories.py @@ -10,6 +10,7 @@ class UserFactory(DjangoModelFactory): email = Faker("email") name = Faker("name") phone = Faker("phone_number") + uid = Faker("random_int", min=1000, max=9999) @post_generation def password(self, create: bool, extracted: Sequence[Any], **kwargs): diff --git a/usersec/migrations/0017_remove_hpcuser_uid_remove_hpcuserversion_uid.py b/usersec/migrations/0017_remove_hpcuser_uid_remove_hpcuserversion_uid.py new file mode 100644 index 0000000..6b1be83 --- /dev/null +++ b/usersec/migrations/0017_remove_hpcuser_uid_remove_hpcuserversion_uid.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.10 on 2024-02-14 15:07 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("usersec", "0016_alter_hpcproject_group_alter_hpcprojectversion_group"), + ] + + operations = [ + migrations.RemoveField( + model_name="hpcuser", + name="uid", + ), + migrations.RemoveField( + model_name="hpcuserversion", + name="uid", + ), + ] diff --git a/usersec/models.py b/usersec/models.py index 58f4840..ba1793f 100644 --- a/usersec/models.py +++ b/usersec/models.py @@ -325,9 +325,6 @@ class Meta: help_text="Additional information about the user", ) - #: POSIX id of the user on the cluster. - uid = models.IntegerField(null=True, help_text="Id of the user on the cluster") - #: POSIX username on the cluster. username = models.CharField(max_length=32, help_text="Username of the user on the cluster") @@ -353,7 +350,7 @@ def __repr__(self): self.id, self.user.username if self.user else None, self.username, - self.uid, + self.user.uid if self.user else None, self.primary_group.name, self.status, self.creator.username if self.creator else None, diff --git a/usersec/serializers.py b/usersec/serializers.py index 7d53442..7be50d8 100644 --- a/usersec/serializers.py +++ b/usersec/serializers.py @@ -28,7 +28,7 @@ class HpcUserAbstractSerializer(HpcObjectAbstractSerializer): resources_used = serializers.JSONField() status = serializers.CharField(read_only=True) description = serializers.CharField(read_only=True) - uid = serializers.IntegerField() + uid = serializers.SerializerMethodField() username = serializers.CharField(read_only=True) expiration = serializers.DateTimeField(read_only=True) full_name = serializers.SerializerMethodField() @@ -48,6 +48,9 @@ def get_first_name(self, obj) -> Optional[str]: def get_phone_number(self, obj) -> Optional[str]: return obj.user.phone + def get_uid(self, obj) -> Optional[int]: + return obj.user.uid + class Meta: fields = HpcObjectAbstractSerializer.Meta.fields + [ "full_name", diff --git a/usersec/tests/factories.py b/usersec/tests/factories.py index 1440550..278d715 100644 --- a/usersec/tests/factories.py +++ b/usersec/tests/factories.py @@ -220,7 +220,6 @@ class Meta: resources_used = {"null": "null"} creator = factory.SubFactory(UserFactory) # User description = "this is a user" - uid = 2000 username = factory.Sequence(lambda n: f"user{n}_" + settings.INSTITUTE_USERNAME_SUFFIX) expiration = datetime(2050, 1, 1, tzinfo=utc) diff --git a/usersec/tests/test_serializers.py b/usersec/tests/test_serializers.py index d62056c..63cc298 100644 --- a/usersec/tests/test_serializers.py +++ b/usersec/tests/test_serializers.py @@ -32,6 +32,7 @@ def testSerializeExisting(self): result["primary_group"] = "primary_group_uuid_placeholder" result["phone_number"] = "phone_number_placeholder" result["full_name"] = "name_placeholder" + result["uid"] = 2000 self.assertMatchSnapshot(result)