mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 09:42:10 +01:00 
			
		
		
		
	Manage channels permissions
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -2,8 +2,11 @@
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from channels.generic.websocket import AsyncJsonWebsocketConsumer
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from registration.models import Registration
 | 
			
		||||
 | 
			
		||||
from .models import Channel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
			
		||||
    """
 | 
			
		||||
@@ -15,6 +18,8 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
			
		||||
        We accept only if this is a user of a team of the associated tournament, or a volunteer
 | 
			
		||||
        of the tournament.
 | 
			
		||||
        """
 | 
			
		||||
        if '_fake_user_id' in self.scope['session']:
 | 
			
		||||
            self.scope['user'] = await User.objects.aget(pk=self.scope['session']['_fake_user_id'])
 | 
			
		||||
 | 
			
		||||
        # Fetch the registration of the current user
 | 
			
		||||
        user = self.scope['user']
 | 
			
		||||
@@ -43,4 +48,28 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
			
		||||
        Called when the client sends us some data, parsed as JSON.
 | 
			
		||||
        :param content: The sent data, decoded from JSON text. Must content a `type` field.
 | 
			
		||||
        """
 | 
			
		||||
        # TODO Process chat protocol
 | 
			
		||||
        match content['type']:
 | 
			
		||||
            case 'fetch_channels':
 | 
			
		||||
                await self.fetch_channels()
 | 
			
		||||
            case unknown:
 | 
			
		||||
                print("Unknown message type:", unknown)
 | 
			
		||||
 | 
			
		||||
    async def fetch_channels(self) -> None:
 | 
			
		||||
        user = self.scope['user']
 | 
			
		||||
 | 
			
		||||
        read_channels = await Channel.get_accessible_channels(user, 'read')
 | 
			
		||||
        write_channels = await Channel.get_accessible_channels(user, 'write')
 | 
			
		||||
        print([channel async for channel in write_channels.all()])
 | 
			
		||||
        message = {
 | 
			
		||||
            'type': 'fetch_channels',
 | 
			
		||||
            'channels': [
 | 
			
		||||
                {
 | 
			
		||||
                    'id': channel.id,
 | 
			
		||||
                    'name': channel.name,
 | 
			
		||||
                    'read_access': True,
 | 
			
		||||
                    'write_access': await write_channels.acontains(channel),
 | 
			
		||||
                }
 | 
			
		||||
                async for channel in read_channels.all()
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
        await self.send_json(message)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,13 @@
 | 
			
		||||
# Copyright (C) 2024 by Animath
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
from django.contrib.auth.models import User
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.db.models import Q, QuerySet
 | 
			
		||||
from django.utils.text import format_lazy
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from participation.models import Tournament
 | 
			
		||||
from registration.models import ParticipantRegistration, Registration, VolunteerRegistration
 | 
			
		||||
from tfjm.permissions import PermissionType
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -74,7 +78,73 @@ class Channel(models.Model):
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return format_lazy(_("Channel {name}"), name=self.name)
 | 
			
		||||
        return str(format_lazy(_("Channel {name}"), name=self.name))
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    async def get_accessible_channels(user: User, permission_type: str = 'read') -> QuerySet["Channel"]:
 | 
			
		||||
        permission_type = 'write_access' if 'write' in permission_type.lower() else 'read_access'
 | 
			
		||||
 | 
			
		||||
        qs = Channel.objects.none()
 | 
			
		||||
        if user.is_anonymous:
 | 
			
		||||
            return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
 | 
			
		||||
 | 
			
		||||
        qs |= Channel.objects.filter(**{permission_type: PermissionType.AUTHENTICATED})
 | 
			
		||||
        registration = await Registration.objects.aget(user_id=user.id)
 | 
			
		||||
 | 
			
		||||
        if registration.is_admin:
 | 
			
		||||
            return Channel.objects.all()
 | 
			
		||||
 | 
			
		||||
        if registration.is_volunteer:
 | 
			
		||||
            registration = await VolunteerRegistration.objects \
 | 
			
		||||
                .prefetch_related('jury_in__tournament', 'organized_tournaments').aget(user_id=user.id)
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(**{permission_type: PermissionType.VOLUNTEER})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(tournament__in=registration.interesting_tournaments),
 | 
			
		||||
                                         **{permission_type: PermissionType.TOURNAMENT_MEMBER})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(tournament__in=registration.organized_tournaments.all()),
 | 
			
		||||
                                         **{permission_type: PermissionType.TOURNAMENT_ORGANIZER})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(tournament__pools__in=registration.pools_presided.all())
 | 
			
		||||
                                         | Q(tournament__in=registration.organized_tournaments.all()),
 | 
			
		||||
                                         **{permission_type: PermissionType.TOURNAMENT_JURY_PRESIDENT})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(pool__in=registration.jury_in.all())
 | 
			
		||||
                                         | Q(pool__tournament__in=registration.organized_tournaments.all())
 | 
			
		||||
                                         | Q(pool__tournament__pools__in=registration.pools_presided.all()),
 | 
			
		||||
                                         **{permission_type: PermissionType.JURY_MEMBER})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(pool__in=registration.jury_in.all())
 | 
			
		||||
                                         | Q(pool__tournament__in=registration.organized_tournaments.all())
 | 
			
		||||
                                         | Q(pool__tournament__pools__in=registration.pools_presided.all()),
 | 
			
		||||
                                         **{permission_type: PermissionType.POOL_MEMBER})
 | 
			
		||||
        else:
 | 
			
		||||
            registration = await ParticipantRegistration.objects \
 | 
			
		||||
                .prefetch_related('team__participation__pools', 'team__participation__tournament').aget(user_id=user.id)
 | 
			
		||||
 | 
			
		||||
            team = registration.team
 | 
			
		||||
            tournaments = []
 | 
			
		||||
            if team.participation.valid:
 | 
			
		||||
                tournaments.append(team.participation.tournament)
 | 
			
		||||
            if team.participation.final:
 | 
			
		||||
                tournaments.append(await Tournament.objects.aget(final=True))
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(tournament__in=tournaments),
 | 
			
		||||
                                         **{permission_type: PermissionType.TOURNAMENT_MEMBER})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(pool__in=team.participation.pools.all()),
 | 
			
		||||
                                         **{permission_type: PermissionType.POOL_MEMBER})
 | 
			
		||||
 | 
			
		||||
            qs |= Channel.objects.filter(Q(team=team),
 | 
			
		||||
                                         **{permission_type: PermissionType.TEAM_MEMBER})
 | 
			
		||||
 | 
			
		||||
        qs |= Channel.objects.filter(invited=user)
 | 
			
		||||
 | 
			
		||||
        print(user)
 | 
			
		||||
        print(qs.query)
 | 
			
		||||
 | 
			
		||||
        return qs
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = _("channel")
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ document.addEventListener('DOMContentLoaded', () => {
 | 
			
		||||
     */
 | 
			
		||||
    function processMessage(data) {
 | 
			
		||||
        // TODO Implement chat protocol
 | 
			
		||||
        console.log(data)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setupSocket(nextDelay = 1000) {
 | 
			
		||||
@@ -46,6 +47,12 @@ document.addEventListener('DOMContentLoaded', () => {
 | 
			
		||||
            console.error('Chat socket closed unexpectedly, restarting…')
 | 
			
		||||
            setTimeout(() => setupSocket(2 * nextDelay), nextDelay)
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        socket.addEventListener('open', e => {
 | 
			
		||||
            socket.send(JSON.stringify({
 | 
			
		||||
                'type': 'fetch_channels',
 | 
			
		||||
            }))
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setupSocket()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user