Skip to content

Commit e6db10e

Browse files
5971: added organizations to invitation model (learningequality#6008)
* 5971: added organizations to invitation model * [pre-commit.ci lite] apply automatic fixes * 5971: removed db constraint on invite model, fixed func typos, added exception for invalid share_mode * 5971: added else branch for org roles, replaced save with update_or_create * 5971: replaced Value with Validation error * 5971: lint fix * [pre-commit.ci lite] apply automatic fixes * 5971: fixed migration --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 322c614 commit e6db10e

2 files changed

Lines changed: 64 additions & 7 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 3.2.24 on 2026-07-02 04:15
2+
import django.db.models.deletion
3+
from django.db import migrations
4+
from django.db import models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
("contentcuration", "0168_alter_assessmentitem_type"),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name="invitation",
16+
name="organization",
17+
field=models.ForeignKey(
18+
blank=True,
19+
null=True,
20+
on_delete=django.db.models.deletion.CASCADE,
21+
to="contentcuration.organization",
22+
),
23+
),
24+
]

contentcuration/contentcuration/models.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,17 @@
7979
from contentcuration.constants import feedback
8080
from contentcuration.constants import user_history
8181
from contentcuration.constants.contentnode import kind_activity_map
82+
from contentcuration.constants.organization_roles import ORGANIZATION_ADMIN
83+
from contentcuration.constants.organization_roles import ORGANIZATION_EDITOR
8284
from contentcuration.constants.organization_roles import organization_role_choices
85+
from contentcuration.constants.organization_roles import ORGANIZATION_ROLE_STATUS_ACTIVE
8386
from contentcuration.constants.organization_roles import (
8487
organization_role_status_choices,
8588
)
8689
from contentcuration.constants.organization_roles import (
8790
ORGANIZATION_ROLE_STATUS_PENDING,
8891
)
92+
from contentcuration.constants.organization_roles import ORGANIZATION_VIEWER
8993
from contentcuration.db.models.expressions import Array
9094
from contentcuration.db.models.functions import ArrayRemove
9195
from contentcuration.db.models.functions import Unnest
@@ -102,6 +106,7 @@
102106

103107
EDIT_ACCESS = "edit"
104108
VIEW_ACCESS = "view"
109+
ADMIN_ACCESS = "admin"
105110

106111
DEFAULT_CONTENT_DEFAULTS = {
107112
"license": None,
@@ -3730,6 +3735,9 @@ class Invitation(models.Model):
37303735
)
37313736
first_name = models.CharField(max_length=100, blank=True)
37323737
last_name = models.CharField(max_length=100, blank=True, null=True)
3738+
organization = models.ForeignKey(
3739+
"Organization", null=True, blank=True, on_delete=models.CASCADE
3740+
)
37333741

37343742
class Meta:
37353743
verbose_name = "Invitation"
@@ -3738,13 +3746,38 @@ class Meta:
37383746
def accept(self):
37393747
user = User.objects.filter(email__iexact=self.email).first()
37403748
if self.channel:
3741-
# channel is a nullable field, so check that it exists.
3742-
if self.share_mode == VIEW_ACCESS:
3743-
self.channel.editors.remove(user)
3744-
self.channel.viewers.add(user)
3745-
else:
3746-
self.channel.viewers.remove(user)
3747-
self.channel.editors.add(user)
3749+
self._accept_channel_invitation(user)
3750+
if self.organization:
3751+
self._accept_organization_invitation(user)
3752+
3753+
def _accept_channel_invitation(self, user):
3754+
if self.share_mode == VIEW_ACCESS:
3755+
self.channel.editors.remove(user)
3756+
self.channel.viewers.add(user)
3757+
else:
3758+
self.channel.viewers.remove(user)
3759+
self.channel.editors.add(user)
3760+
3761+
def _accept_organization_invitation(self, user):
3762+
role = None
3763+
if self.share_mode == VIEW_ACCESS:
3764+
role = ORGANIZATION_VIEWER
3765+
elif self.share_mode == EDIT_ACCESS:
3766+
role = ORGANIZATION_EDITOR
3767+
elif self.share_mode == ADMIN_ACCESS:
3768+
role = ORGANIZATION_ADMIN
3769+
else:
3770+
raise ValidationError(f"Invalid share_mode: {self.share_mode}")
3771+
3772+
update_create_defaults = {
3773+
"role": role,
3774+
"status": ORGANIZATION_ROLE_STATUS_ACTIVE,
3775+
}
3776+
OrganizationRole.objects.update_or_create(
3777+
user=user,
3778+
organization=self.organization,
3779+
defaults=update_create_defaults,
3780+
)
37483781

37493782
@classmethod
37503783
def filter_edit_queryset(cls, queryset, user):

0 commit comments

Comments
 (0)