Skip to content

Commit

Permalink
add manage admins apis to program view
Browse files Browse the repository at this point in the history
  • Loading branch information
AmooHashem committed May 24, 2024
1 parent 6b16233 commit b7d0d13
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 16 deletions.
20 changes: 20 additions & 0 deletions apps/fsm/migrations/0130_program_admins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.1.3 on 2024-05-21 15:43

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('fsm', '0129_rename_event_program'),
]

operations = [
migrations.AddField(
model_name='program',
name='admins',
field=models.ManyToManyField(blank=True, null=True, related_name='administered_programs', to=settings.AUTH_USER_MODEL),
),
]
21 changes: 21 additions & 0 deletions apps/fsm/migrations/0131_alter_registrationreceipt_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 4.1.3 on 2024-05-24 19:11

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('fsm', '0130_program_admins'),
]

operations = [
migrations.AlterField(
model_name='registrationreceipt',
name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='registration_receipts', to=settings.AUTH_USER_MODEL),
),
]
11 changes: 6 additions & 5 deletions apps/fsm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ class ProgramType(models.TextChoices):
Team = "Team"
Individual = "Individual"

admins = models.ManyToManyField(
User, related_name='administered_programs', null=True, blank=True)

website = models.CharField(blank=True, null=True, max_length=50)

merchandise = models.OneToOneField('accounts.Merchandise', related_name='program', on_delete=models.SET_NULL,
Expand Down Expand Up @@ -164,8 +167,7 @@ def __str__(self):
@property
def modifiers(self):
modifiers = {self.creator} if self.creator is not None else set()
modifiers |= set(self.holder.admins.all()
) if self.holder is not None else set()
modifiers |= set(self.admins.all())
return modifiers

@property
Expand Down Expand Up @@ -220,7 +222,7 @@ class FSMPType(models.TextChoices):
website = models.CharField(blank=True, null=True, max_length=50)

program = models.ForeignKey(Program, on_delete=models.SET_NULL, related_name='fsms', default=None, null=True,
blank=True)
blank=True)
merchandise = models.OneToOneField('accounts.Merchandise', related_name='fsm', on_delete=models.SET_NULL, null=True,
blank=True)
registration_form = models.OneToOneField('fsm.RegistrationForm', related_name='fsm', on_delete=models.SET_NULL, null=True,
Expand Down Expand Up @@ -491,8 +493,7 @@ class CorrectionStatus(models.TextChoices):
# should be in every answer sheet child
answer_sheet_of = models.ForeignKey('fsm.RegistrationForm', related_name='registration_receipts', null=True, blank=True,
on_delete=models.SET_NULL)
user = models.ForeignKey('accounts.User', related_name='registration_receipts', on_delete=models.CASCADE,
null=True, blank=True)
user = models.ForeignKey('accounts.User', related_name='registration_receipts', on_delete=models.CASCADE)
status = models.CharField(max_length=25, blank=False,
default='Waiting', choices=RegistrationStatus.choices)
is_participating = models.BooleanField(default=False)
Expand Down
2 changes: 1 addition & 1 deletion apps/fsm/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from apps.fsm.models import RegistrationReceipt, Program, RegistrationForm, FSM, Problem, State, Team


class IsProgramModifier(permissions.BasePermission):
class ProgramAdmin(permissions.BasePermission):
"""
Permission for evet's admin to update program
"""
Expand Down
2 changes: 2 additions & 0 deletions apps/fsm/serializers/program_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def create(self, validated_data):
creator = self.context.get('user', None)
instance = super(ProgramSerializer, self).create(
{'creator': creator, 'website': website, **validated_data})
instance.admins.add(creator)
if merchandise and merchandise.get('name', None) is None:
merchandise['name'] = validated_data.get('name', 'unnamed_program')
serializer = MerchandiseSerializer(data=merchandise)
Expand Down Expand Up @@ -107,3 +108,4 @@ class Meta:
fields = '__all__'
read_only_fields = ['id', 'creator', 'merchandise',
'is_approved', 'registration_form']

52 changes: 42 additions & 10 deletions apps/fsm/views/program_view.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from django.views.decorators.cache import cache_page
from apps.fsm.models import Program
from apps.fsm.permissions import IsProgramModifier, HasActiveRegistration
from django.utils.decorators import method_decorator
from apps.fsm.models import Program, AnswerSheet, RegistrationReceipt, RegistrationReceipt
from apps.fsm.permissions import ProgramAdmin, HasActiveRegistration, MentorPermission, HasActiveRegistration

from apps.fsm.serializers.program_serializers import ProgramSerializer

from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import ParseError
from rest_framework.response import Response

from apps.accounts.serializers import AccountSerializer
from apps.accounts.utils import find_user
from apps.fsm.utils import register_user_in_program
from errors.error_codes import serialize_error
from apps.fsm.serializers.fsm_serializers import FSMSerializer


class ProgramViewSet(ModelViewSet):
serializer_class = ProgramSerializer
Expand All @@ -21,16 +30,39 @@ def get_serializer_context(self):
return context

def get_permissions(self):
if self.action in ['create']:
permission_classes = [permissions.IsAuthenticated]
elif self.action == 'retrieve' or self.action == 'list':
if self.action == 'retrieve' or self.action == 'list':
permission_classes = [permissions.AllowAny]
elif self.action == 'get_fsms':
permission_classes = [HasActiveRegistration]
else:
permission_classes = [IsProgramModifier]
permission_classes = [ProgramAdmin]
return [permission() for permission in permission_classes]

# @method_decorator(cache_page(60 * 1, key_prefix="program"))
def list(self, request, *args, **kwargs):
return super().list(self, request, *args, **kwargs)

@action(detail=True, methods=['get'])
def get_admins(self, request, pk):
admins = self.get_object().admins
return Response(data=AccountSerializer(admins, many=True).data)

@action(detail=True, methods=['post'], serializer_class=AccountSerializer, permission_classes=[ProgramAdmin, ])
def add_admin(self, request, pk=None):
program = self.get_object()
user_serializer = AccountSerializer(data=request.data)
user_serializer.is_valid(raise_exception=True)
new_admin = find_user(user_serializer.validated_data)
program.admins.add(new_admin)
register_user_in_program(new_admin, program)
return Response()

@action(detail=True, methods=['post'], serializer_class=AccountSerializer, permission_classes=[MentorPermission, ])
def remove_admin(self, request, pk=None):
program = self.get_object()
serializer = AccountSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
removed_admin = find_user(serializer.validated_data)
if removed_admin == program.creator:
raise ParseError(serialize_error('5007'))
if removed_admin in program.admins.all():
program.admins.remove(removed_admin)
return Response()

0 comments on commit b7d0d13

Please sign in to comment.