Reputation: 51
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)
.
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