diff --git a/src/api/schedule.py b/src/api/schedule.py index 104128c13ea107f3e86b6d766b4b7e9985986c6c..734c8bd22f10eb3bd73ef1c60de5cc830b650e1f 100644 --- a/src/api/schedule.py +++ b/src/api/schedule.py @@ -109,6 +109,7 @@ class ScheduleEncoder(json.JSONEncoder): return {'id': None, 'name': p, 'public_name': p} if isinstance(p, PlatformUser): + # TODO: Update after deciding oh one or more conferences in #648 member: ConferenceMember = p.conferences.first() # TODO search for correct conference name = p.get_display_name() diff --git a/src/backoffice/views/assemblies/members.py b/src/backoffice/views/assemblies/members.py index edd2866c2e43003a98651ccfbf672a175146f7a5..5b0e31a976cab65bc9023aa180341c2acd0bafef 100644 --- a/src/backoffice/views/assemblies/members.py +++ b/src/backoffice/views/assemblies/members.py @@ -69,6 +69,7 @@ class MemberListView(AssemblyMixin, ListView): elif k == 'show': m = self.get_queryset().select_related('member', 'assembly').get(member_id=int(v)) + # TODO: Update after deciding oh one or more conferences in #648 if not m.member.conferences.filter(conference_id=m.assembly.conference_id).exists(): messages.error(self.request, format_lazy(_('Assembly__members__no_member_cant_display'), user=m.member)) continue diff --git a/src/core/models/assemblies.py b/src/core/models/assemblies.py index 52d93e044c02a83ccda6023c5bb2db7bf52679b5..c3497ff6e3e1404f2523368483c376ee960a82c7 100644 --- a/src/core/models/assemblies.py +++ b/src/core/models/assemblies.py @@ -31,6 +31,7 @@ from core.models.invitation import Invitation from core.models.map import MapFloor from core.models.tags import TaggedItemMixin, TagItem from core.models.users import PlatformUser +from core.predicates import has_perms from core.utils import render_markdown_as_text from core.validators import FileSizeValidator, ImageDimensionValidator @@ -56,17 +57,6 @@ def is_habitat_manager(user: PlatformUser, assembly: 'Assembly') -> bool: return assembly.parent.user_can_manage(user) -def perm_is(permission: str): - @rules.predicate - def user_has_permission(user, assembly: 'Assembly'): - if assembly is None: - return False - member = ConferenceMember.get_member(conference=assembly.conference, user=user) - return member.has_perms(permission, require_all=True, require_staff=True) - - return user_has_permission - - class AssemblyManager(ConferenceManagerMixin['Assembly']): staff_permissions = ['core.assembly_team'] assembly_filter = 'self' @@ -95,9 +85,9 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, RulesModel): rules_permissions = { 'view': is_assembly_member, 'add': is_authenticated, - 'change': is_assembly_manager | perm_is('core.change_assembly'), - 'delete': is_assembly_manager | perm_is('core.delete_assembly'), - 'leave_habitat': is_assembly_manager | is_habitat_manager | perm_is('core.change_assembly'), + 'change': is_assembly_manager | has_perms('core.change_assembly', require_staff=True), + 'delete': is_assembly_manager | has_perms('core.delete_assembly', require_staff=True), + 'leave_habitat': is_assembly_manager | is_habitat_manager | has_perms('core.change_assembly', require_staff=True), } class State(models.TextChoices): @@ -420,7 +410,7 @@ class Assembly(TaggedItemMixin, ActivityLogMixin, RulesModel): self.logger.error('Failed to create a technical user "%s" for assembly <%s> (%s): %s', username, self.slug, self.id, err) raise Exception('Technical user for assembly could not be created.') - cm = u.conferences.create(conference=self.conference) + cm = ConferenceMember(conference=self.conference, user=u) cm.save() self.technical_user = u diff --git a/src/core/models/badges.py b/src/core/models/badges.py index 1417a2d3a291a61ba4096f63a3cb73812c075261..16b07ac096233797c23ee5949668c2a7c200e6d4 100644 --- a/src/core/models/badges.py +++ b/src/core/models/badges.py @@ -339,6 +339,7 @@ class UserBadgeManager(models.Manager): defaults={ 'accepted_by_user': not bool(issuer), 'token': token if token else None, + # TODO: Update after deciding oh one or more conferences in #648 'visibility': user.conferences.filter(conference=badge.conference).first().default_badge_visibility, }, ) diff --git a/src/core/predicates.py b/src/core/predicates.py new file mode 100644 index 0000000000000000000000000000000000000000..1e605f879f9ad56784b0d4e907c2c1833d400050 --- /dev/null +++ b/src/core/predicates.py @@ -0,0 +1,31 @@ +from typing import TYPE_CHECKING, Callable + +from rules.predicates import predicate + +if TYPE_CHECKING: + from src.core.models import PlatformUser + + +def has_perms( + *required_permissions: str, + require_all: bool = True, + require_staff: bool = False, +) -> Callable[['PlatformUser'], bool]: + @predicate + def test_team_perms(user: 'PlatformUser') -> bool: + # TODO: Update after deciding oh one or more conferences in #648 + conference_member = user.conferences.first() + if conference_member is None: + return False + return conference_member.has_perms(*required_permissions, require_all=require_all, require_staff=require_staff) + + return test_team_perms + + +@predicate +def is_conference_staff(user: 'PlatformUser') -> bool: + # TODO: Update after deciding oh one or more conferences in #648 + conference_member = user.conferences.first() + if conference_member is None: + return False + return conference_member.is_authenticated and conference_member.is_staff diff --git a/src/plainui/views/user_profile.py b/src/plainui/views/user_profile.py index 12625588bb0fb37fa47823a7e7e521781eeb1585..2ba4f6639f95afdd467d5096e9c27499613882b2 100644 --- a/src/plainui/views/user_profile.py +++ b/src/plainui/views/user_profile.py @@ -63,6 +63,7 @@ class ProfileView(ConferenceRequiredMixin, UpdateView): form2_kwargs = super().get_form_kwargs() if hasattr(self, 'object'): + # TODO: Update after deciding oh one or more conferences in #648 cm = self.object.conferences.filter(conference=self.conf).first() if cm: form2_kwargs['instance'] = cm @@ -119,6 +120,7 @@ class ProfileView(ConferenceRequiredMixin, UpdateView): form1.instance.timezone = form1.cleaned_data['timezone'] form1.instance.save() + # TODO: Update after deciding oh one or more conferences in #648 cm = form1.instance.conferences.filter(conference=self.conf).first() if cm: for lang in AVAILABLE_LANGUAGES: diff --git a/src/plainui/views/users.py b/src/plainui/views/users.py index 785e052416e2cc1e1ba9bac9141ec256702e2f74..a040f4b48e7e7417b58bd5d70394d3922ec04c36 100644 --- a/src/plainui/views/users.py +++ b/src/plainui/views/users.py @@ -33,6 +33,7 @@ class UserView(ConferenceRequiredMixin, TemplateView): context = super().get_context_data(**kwargs) context['conf'] = self.conf context['display_user'] = display_user = get_object_or_404(PlatformUser.objects.filter(slug=user_slug)) + # TODO: Update after deciding oh one or more conferences in #648 conference_member = display_user.conferences.filter(conference=self.conf).first() context['description_html'] = None if not conference_member else conference_member.description_html context['owned_badges'] = owned_badges