Add migration, handle sync for mentors and supervisors
This commit is contained in:
parent
cc3b6bbf0d
commit
8af955f794
|
|
@ -147,10 +147,10 @@ class User(AbstractUser):
|
|||
self.additional_json_data = (
|
||||
self.additional_json_data
|
||||
| sanitize_json_data_input(
|
||||
{
|
||||
**data,
|
||||
}
|
||||
)
|
||||
{
|
||||
**data,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ from django.utils.translation import gettext_lazy as _
|
|||
from keycloak.exceptions import KeycloakDeleteError, KeycloakPostError
|
||||
|
||||
from vbv_lernwelt.course.models import CourseSessionUser
|
||||
from vbv_lernwelt.course_session_group.models import CourseSessionGroup
|
||||
from vbv_lernwelt.learning_mentor.models import LearningMentor
|
||||
from vbv_lernwelt.sso.models import SsoSyncError, SsoUser
|
||||
from vbv_lernwelt.sso.role_sync.services import (
|
||||
create_and_update_user,
|
||||
|
|
@ -33,6 +35,16 @@ def sync_sso_roles_from_admin(user: User, request):
|
|||
(csu.course_session.course.slug, csu.role)
|
||||
for csu in CourseSessionUser.objects.filter(user=user)
|
||||
]
|
||||
|
||||
course_roles += [
|
||||
(lm.course_session.course.slug, "LEARNING_MENTOR")
|
||||
for lm in LearningMentor.objects.filter(mentor=user)
|
||||
]
|
||||
|
||||
for csg in CourseSessionGroup.objects.filter(supervisor=user):
|
||||
for course_session in csg.course_session.all():
|
||||
course_roles.append((course_session.course.slug, "SUPERVISOR"))
|
||||
|
||||
try:
|
||||
sync_roles_for_user(user, course_roles)
|
||||
messages.add_message(
|
||||
|
|
|
|||
|
|
@ -1,18 +1,34 @@
|
|||
# Generated by Django 3.2.25 on 2024-06-20 05:24
|
||||
# Generated by Django 3.2.25 on 2024-06-26 15:34
|
||||
|
||||
import django.contrib.auth.models
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
("core", "0007_auto_20240220_1058"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="SsoUser",
|
||||
fields=[],
|
||||
options={
|
||||
"proxy": True,
|
||||
"indexes": [],
|
||||
"constraints": [],
|
||||
},
|
||||
bases=("core.user",),
|
||||
managers=[
|
||||
("objects", django.contrib.auth.models.UserManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="SsoSyncError",
|
||||
fields=[
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ if settings.OAUTH_SYNC_ROLES:
|
|||
user_realm_name=settings.OAUTH_SIGNIN_REALM,
|
||||
client_id=settings.OAUTH_SIGNIN_ADMIN_CLIENT_ID,
|
||||
client_secret_key=settings.OAUTH_SIGNIN_ADMIN_CLIENT_SECRET,
|
||||
verify=False,
|
||||
verify=True,
|
||||
)
|
||||
|
||||
keycloak_admin = KeycloakAdmin(connection=keycloak_connection)
|
||||
|
|
@ -48,7 +48,7 @@ def _handle_add_remove_action(
|
|||
action: SsoSyncError.Action,
|
||||
):
|
||||
user_id = user.additional_json_data.get("intermediate_sso_id", "")
|
||||
if settings.OAUTH_SYNC_ROLES and user_id:
|
||||
if keycloak_admin and user_id:
|
||||
request_roles = _get_role_request_data(course_roles)
|
||||
if not request_roles:
|
||||
return False
|
||||
|
|
@ -65,7 +65,7 @@ def _handle_add_remove_action(
|
|||
def update_roles_for_user(
|
||||
user: User, add_course_roles: CourseRolesType, remove_course_roles: CourseRolesType
|
||||
):
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
if keycloak_admin:
|
||||
remove_ret_value = remove_roles_from_user(user, remove_course_roles)
|
||||
add_ret_value = add_roles_to_user(user, add_course_roles)
|
||||
return remove_ret_value and add_ret_value
|
||||
|
|
@ -73,10 +73,9 @@ def update_roles_for_user(
|
|||
|
||||
|
||||
def sync_roles_for_user(user: User, course_roles: CourseRolesType):
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
if keycloak_admin:
|
||||
user_id = user.additional_json_data.get("intermediate_sso_id", "")
|
||||
if user_id:
|
||||
# ignore for the moment, just in the admin
|
||||
assigned_roles = _filter_non_myvbv_roles(
|
||||
keycloak_admin.get_realm_roles_of_user(user_id=user_id)
|
||||
)
|
||||
|
|
@ -91,7 +90,7 @@ def sync_roles_for_user(user: User, course_roles: CourseRolesType):
|
|||
|
||||
|
||||
def create_user(user: User):
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
if keycloak_admin:
|
||||
return _kc_create_user(user)
|
||||
return ""
|
||||
|
||||
|
|
@ -104,7 +103,7 @@ def create_and_update_user(user: User, save=False):
|
|||
|
||||
|
||||
def get_roles_for_user(user_id: str):
|
||||
if settings.OAUTH_SYNC_ROLES:
|
||||
if keycloak_admin:
|
||||
return keycloak_admin.get_realm_roles_of_user(
|
||||
user_id=user_id,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ def update_sso_roles_in_cs(sender, instance: CourseSessionUser, **kwargs):
|
|||
_add_sso_role(instance.user, instance.course_session.course.slug, instance.role)
|
||||
else:
|
||||
old_csu = CourseSessionUser.objects.get(pk=instance.pk)
|
||||
if old_csu.role != instance.role:
|
||||
if (
|
||||
old_csu.role != instance.role
|
||||
or old_csu.course_session.course != instance.course_session.course
|
||||
):
|
||||
try:
|
||||
update_roles_for_user(
|
||||
instance.user,
|
||||
|
|
@ -42,7 +45,7 @@ def update_sso_roles_in_cs(sender, instance: CourseSessionUser, **kwargs):
|
|||
(instance.course_session.course.slug, instance.role)
|
||||
],
|
||||
remove_course_roles=[
|
||||
(instance.course_session.course.slug, old_csu.role)
|
||||
(old_csu.course_session.course.slug, old_csu.role)
|
||||
],
|
||||
)
|
||||
except KeycloakError:
|
||||
|
|
|
|||
|
|
@ -92,7 +92,9 @@ class CourseSessionUserTests(TestCase):
|
|||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.update_roles_for_user")
|
||||
def test_update_role_for_user_on_creation(self, mock_update_roles_for_user):
|
||||
def test_update_role_for_user_on_update_with_role_change(
|
||||
self, mock_update_roles_for_user
|
||||
):
|
||||
mock_update_roles_for_user.return_value = None
|
||||
self.csu1_student1.role = "TRAINER"
|
||||
|
||||
|
|
@ -113,7 +115,32 @@ class CourseSessionUserTests(TestCase):
|
|||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.update_roles_for_user")
|
||||
def test_dont_update_role_for_user_on_creation(self, mock_update_roles_for_user):
|
||||
def test_update_role_for_user_on_update_with_course_change(
|
||||
self, mock_update_roles_for_user
|
||||
):
|
||||
mock_update_roles_for_user.return_value = None
|
||||
course, self.course_page = create_course("Test Course")
|
||||
course_session = create_course_session(course=course, title="Test VV")
|
||||
old_course_slug = self.csu1_student1.course_session.course.slug
|
||||
|
||||
self.csu1_student1.course_session = course_session
|
||||
|
||||
self.mock_pre_save_signal.send(
|
||||
sender=CourseSessionUser, instance=self.csu1_student1
|
||||
)
|
||||
|
||||
self.assertEqual(mock_update_roles_for_user.call_count, 1)
|
||||
|
||||
mock_update_roles_for_user.assert_called_with(
|
||||
self.student1,
|
||||
add_course_roles=[
|
||||
(self.csu1_student1.course_session.course.slug, "MEMBER")
|
||||
],
|
||||
remove_course_roles=[(old_course_slug, "MEMBER")],
|
||||
)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.update_roles_for_user")
|
||||
def test_dont_update_role_for_user_on_update(self, mock_update_roles_for_user):
|
||||
mock_update_roles_for_user.return_value = None
|
||||
self.csu1_student1.role = "MEMBER"
|
||||
|
||||
|
|
@ -138,12 +165,6 @@ class CourseSessionGroupTests(TestCase):
|
|||
self.trainer = User.objects.get(id=TEST_TRAINER1_USER_ID)
|
||||
self.supervisor = User.objects.get(id=TEST_SUPERVISOR1_USER_ID)
|
||||
|
||||
# m2m_changed.disconnect(receiver=update_sso_roles_in_csg, sender=CourseSessionGroup.supervisor.through)
|
||||
#
|
||||
# # Connect a mock signal handler
|
||||
# self.mock_signal = Signal()
|
||||
# self.mock_signal.connect(receiver=update_sso_roles_in_csg, sender=CourseSessionGroup.supervisor.through)
|
||||
|
||||
@patch("vbv_lernwelt.sso.signals.remove_roles_from_user")
|
||||
def test_remove_roles_for_csg_supervisors(self, mock_remove_roles_from_user):
|
||||
mock_remove_roles_from_user.return_value = None
|
||||
|
|
|
|||
Loading…
Reference in New Issue