cheetoriko
cheetoriko

Reputation: 51

User getting added to multiple permission groups instead of the one

In my application, when a user registers, they are identified as either a lecturer or a student. These are categorised as auth_groups, and users are assigned to one with these methods...

services.py

  def register_student(self, data):
    user = User.objects.create(
      user_id = data["user_id"]
    )
    students_group = Group.objects.get(name = "students") 
    user.groups.add(students_group)

    return user
  
  def register_lecturer(self, data):
    user = User.objects.create(
      user_id = data["user_id"]
    )
    lecturers_group = Group.objects.get(name = "lecturers") 
    user.groups.add(lecturers_group)

    return user

On the surface, this appeared to work fine, but when I went to write the test suite, the following issue occurred: When register_student is called, the user is added to both the lecturer and student groups in the line user.groups.add(students_group).

It seemingly identifies the right group that the user should be added to... ...But then adds the user to both groups

I want to mention that "students" have more permissions than "lecturers".

Why is this happening? Thank you for any help!

EDIT: I am using Django as an API with the Django REST framework. Here is the corresponding user model, which is what is being linked to the auth_groups...

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, Group

class UserManager(BaseUserManager):
  def _create_user(self, user_id, password, **kwargs):
    encrypted_user_id = self.cipher.encrypt(user_id.encode("utf-8"))
    user = self.model(
      user_id = user_id,
      **kwargs
    )
    user.set_password(password)
    user.save(using=self._db)
    return user

  def create_user(self, user_id, password=None, **kwargs):
    kwargs.setdefault("is_superuser", False)
    return self._create_user(user_id, password, **kwargs)
  
  def create_lecturer(self, user_id, password=None, **kwargs):
    user = self.create_user(user_id, password, **kwargs)
    lecturers_group = Group.objects.get(name = "lecturers") 
    lecturers_group.user_set.add(user)
    return user
  
  def create_student(self, user_id, password=None, **kwargs):
    user = self.create_user(user_id, password, **kwargs)
    students_group = Group.objects.get(name = "students") 
    students_group.user_set.add(user)
    return user
  
  def create_admin(self, user_id, password=None, **kwargs):
    user = self.create_user(user_id, password, **kwargs)
    admins_group = Group.objects.get(name = "admins") 
    admins_group.user_set.add(user)
    return user

  def create_superuser(self, user_id, password=None, **kwargs):
    kwargs.setdefault("is_superuser", True)
    return self._create_user(user_id, password, **kwargs)

class User(AbstractBaseUser, PermissionsMixin):
    user_id = models.CharField(max_length=255, unique=True, primary_key=True, blank=False, null=False)

    USERNAME_FIELD = "user_id"
    REQUIRED_FIELDS = []
    
    objects = UserManager()
  
    class Meta:
      db_table = "auth_user"

I use the Microsoft Entra API to determine whether a user is a student or a lecturer. On the front end, I receive an access token that I can use to identify the user and send it to the backend to process the requests that fulfil that. Then, when registering a new user, I determine whether a user is a lecturer or a student based on what group they belong to on the Microsoft Entra platform...

services.py


def get_user_role(access_token, student_group_id, staff_group_id):
  try:
    request_url = "https://graph.microsoft.com/v1.0/me/memberOf?$filter=id eq '" + student_group_id + "' or id eq '" + staff_group_id + "'&$count=true&$select=id"
      
    res = requests.get(
      request_url,
      headers = {
        "Authorization": "Bearer " + access_token,
        "ConsistencyLevel": "eventual"
      }
    ).json()
      
    user_group_id = res["value"][0]["id"]
    
    if user_group_id == student_group_id:
      return "STUDENT"
    elif user_group_id == staff_group_id:
      return "LECTURER"
    else:
      raise NotAuthenticated(
        detail = "Could not determine if user is lecturer or student"
      )
  except KeyError:
    raise NotAuthenticated(
      detail = "Could not determine if user is lecturer or student"
    )
views.py

...
      try:
        user_role = get_user_role(access_token)

        serializer = self.serializer_class(data = {"user_id": uid})
        serializer.is_valid(raise_exception = True)
        
        if user_role == "STUDENT":
          user = serializer.register_student(data = {"user_id": uid})
          
        elif user_role == "LECTURER": 
          user = serializer.register_lecturer(data = {"user_id": uid})
      except NotAuthenticated as error:
        raise NotAuthenticated(
          detail = str(error),
          code = 401
        )

I hope this contextualises my question more!

Upvotes: -1

Views: 38

Answers (0)

Related Questions