# Propagation extension
* adds sso_identifier as new User model attribute * refactors minor code snippets on user-propagation data resolving * adds updating of username based on propagation data * adds sso_identifier on admin backend view
This commit is contained in:
		
							parent
							
								
									23bc79ee3b
								
							
						
					
					
						commit
						a12c2fb57e
					
				@ -15,6 +15,7 @@ class UserNotificationAdmin(admin.ModelAdmin):
 | 
				
			|||||||
class UserAdmin(admin.ModelAdmin):
 | 
					class UserAdmin(admin.ModelAdmin):
 | 
				
			||||||
    list_display = [
 | 
					    list_display = [
 | 
				
			||||||
        "id",
 | 
					        "id",
 | 
				
			||||||
 | 
					        "sso_identifier",
 | 
				
			||||||
        "username",
 | 
					        "username",
 | 
				
			||||||
        "first_name",
 | 
					        "first_name",
 | 
				
			||||||
        "last_name",
 | 
					        "last_name",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										18
									
								
								user/migrations/0010_user_sso_identifier.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								user/migrations/0010_user_sso_identifier.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.1.6 on 2025-09-12 06:10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('user', '0009_user_oauth_token'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='user',
 | 
				
			||||||
 | 
					            name='sso_identifier',
 | 
				
			||||||
 | 
					            field=models.CharField(blank=True, db_comment='Identifies the account based on an unique identifier from the SSO system', max_length=255, null=True),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@ -6,6 +6,7 @@ Created on: 15.11.21
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
from django.contrib.auth.models import AbstractUser
 | 
					from django.contrib.auth.models import AbstractUser
 | 
				
			||||||
 | 
					from django.core.exceptions import ObjectDoesNotExist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,6 +33,12 @@ class User(AbstractUser):
 | 
				
			|||||||
        db_comment="OAuth token for the user",
 | 
					        db_comment="OAuth token for the user",
 | 
				
			||||||
        related_name="+"
 | 
					        related_name="+"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    sso_identifier = models.CharField(
 | 
				
			||||||
 | 
					        blank=True,
 | 
				
			||||||
 | 
					        null=True,
 | 
				
			||||||
 | 
					        db_comment="Identifies the account based on an unique identifier from the SSO system",
 | 
				
			||||||
 | 
					        max_length=255,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def is_notification_setting_set(self, notification_enum: UserNotificationEnum):
 | 
					    def is_notification_setting_set(self, notification_enum: UserNotificationEnum):
 | 
				
			||||||
        return self.notifications.filter(
 | 
					        return self.notifications.filter(
 | 
				
			||||||
@ -265,3 +272,47 @@ class User(AbstractUser):
 | 
				
			|||||||
        self.oauth_token = token
 | 
					        self.oauth_token = token
 | 
				
			||||||
        self.save()
 | 
					        self.save()
 | 
				
			||||||
        return self
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def resolve_user_using_propagation_data(data: dict):
 | 
				
			||||||
 | 
					        """ Fetches user from db by the given data from propagation process
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Args:
 | 
				
			||||||
 | 
					            data (dict): json containing user information from the sso system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Returns:
 | 
				
			||||||
 | 
					            user (User): The resolved user
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        username = data.get("username", None)
 | 
				
			||||||
 | 
					        sso_identifier = data.get("sso_identifier", None)
 | 
				
			||||||
 | 
					        if not username and not sso_identifier:
 | 
				
			||||||
 | 
					            raise AssertionError("No username or sso identifier provided")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            user = User.objects.get(username=username)
 | 
				
			||||||
 | 
					        except ObjectDoesNotExist:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                user = User.objects.get(sso_identifier=sso_identifier)
 | 
				
			||||||
 | 
					            except ObjectDoesNotExist:
 | 
				
			||||||
 | 
					                raise ObjectDoesNotExist("No user with this username or sso identifier was found")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update_user_using_propagation_data(self, data: dict):
 | 
				
			||||||
 | 
					        """ Update user data based on propagation data from sso system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Args:
 | 
				
			||||||
 | 
					            data (dict): json containing user information from the sso system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Returns:
 | 
				
			||||||
 | 
					            user (User): The updated user
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        skipable_attrs = {
 | 
				
			||||||
 | 
					            "is_staff",
 | 
				
			||||||
 | 
					            "is_superuser",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for _attr, _val in data.items():
 | 
				
			||||||
 | 
					            if _attr in skipable_attrs:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            setattr(self, _attr, _val)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
				
			|||||||
@ -44,17 +44,8 @@ class PropagateUserView(View):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            status = "updated"
 | 
					            status = "updated"
 | 
				
			||||||
            user = User.objects.get(username=body.get('username'))
 | 
					            user = User.resolve_user_using_propagation_data(body)
 | 
				
			||||||
            # Update user data, excluding some changes
 | 
					            user = user.update_user_using_propagation_data(body)
 | 
				
			||||||
            skipable_attrs = {
 | 
					 | 
				
			||||||
                "username",
 | 
					 | 
				
			||||||
                "is_staff",
 | 
					 | 
				
			||||||
                "is_superuser",
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            for _attr, _val in body.items():
 | 
					 | 
				
			||||||
                if _attr in skipable_attrs:
 | 
					 | 
				
			||||||
                    continue
 | 
					 | 
				
			||||||
                setattr(user, _attr, _val)
 | 
					 | 
				
			||||||
        except ObjectDoesNotExist:
 | 
					        except ObjectDoesNotExist:
 | 
				
			||||||
            user = User(**body)
 | 
					            user = User(**body)
 | 
				
			||||||
            status = "created"
 | 
					            status = "created"
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user