Commit c3bd363e authored by Laury Bueno's avatar Laury Bueno
Browse files

Merge branch 'develop'

parents 66fab93a 3958eae3
......@@ -122,7 +122,9 @@ class WorkspaceAdmin(admin.ModelAdmin):
@admin.register(ProfessorMessage)
class ProfessorMessageAdmin(admin.ModelAdmin):
pass
filter_horizontal = (
'users',
)
@admin.register(CourseAuthor)
......
......@@ -67,6 +67,9 @@ class Classroom(models.Model):
def chat_url(self):
return '{}group/{}'.format(settings.ROCKET_CHAT['address'], self.group.chatroom.name)
def is_assistant_or_coordinator(self, user):
return user in (self.assistants.all() | self.coordinators.all())
class Event(models.Model):
title = models.CharField(
......
......@@ -64,6 +64,5 @@ class ClassroomSerializer(serializers.ModelSerializer):
def get_can_edit(self, obj):
request = self.context.get("request", None)
if request and hasattr(request, "user"):
return request.user in obj.assistants.all() \
or request.user in obj.coordinators.all() \
return obj.is_assistant_or_coordinator(request.user) \
or request.user.is_superuser
# Generated by Django 2.2.14 on 2020-08-15 02:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('courses', '0013_auto_20200729_1612'),
]
operations = [
migrations.AddField(
model_name='professormessage',
name='classrooms',
field=models.ManyToManyField(blank=True, related_name='messages', to='courses.Classroom', verbose_name='Classrooms'),
),
]
# Generated by Django 2.2.14 on 2020-08-18 06:20
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('courses', '0014_professormessage_classrooms'),
]
operations = [
migrations.AlterField(
model_name='professormessage',
name='course',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='courses.Course', verbose_name='Course'),
),
]
......@@ -664,6 +664,7 @@ class ProfessorMessage(models.Model):
models.CASCADE,
verbose_name=_('Course'),
null=True,
blank=True,
)
groups = models.ManyToManyField(
Group,
......@@ -678,6 +679,12 @@ class ProfessorMessage(models.Model):
related_name='message_courses',
blank=True,
)
classrooms = models.ManyToManyField(
'Classroom',
verbose_name=_('Classrooms'),
related_name='messages',
blank=True,
)
def __str__(self):
return self.professor.name + " - " + self.subject + " - " + str(self.date)
......
......@@ -40,17 +40,26 @@ class IsAdmin(permissions.BasePermission):
elif request.user and request.user.is_superuser:
return True
class IsAssistantOrCoordinatorOrReadOnly(permissions.BasePermission):
class IsAssistantOrCoordinatorOrAdminOrRecipient(permissions.BasePermission):
"""
Check if a user can send messages to students enrolled in a course
Check if a user can send or read messages.
"""
def has_object_permission(self, request, view, obj):
# Read permissions are allowed to any request,
# so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
if request.user and request.user.is_superuser:
return True
elif (request.method in permissions.SAFE_METHODS and
(request.user in obj.users.all() or
request.user.groups.all().intersection(obj.groups.all()).exists())):
return True
else:
elif obj.course:
return obj.course.is_assistant_or_coordinator(request.user)
elif obj.classrooms:
# The user must be assistant or coordinator of all classroom he want to send the message
for classroom in obj.classrooms.all():
if not classroom.is_assistant_or_coordinator(request.user):
return False
class IsAdminOrReadOnly(IsAdmin):
"""
......
......@@ -127,7 +127,9 @@ class ProfessorMessageSerializer(serializers.ModelSerializer):
class Meta:
model = ProfessorMessage
fields = ('id', 'course', 'course_name', 'course_slug', 'professor',
'users', 'subject', 'message', 'date', 'is_read', 'groups', 'classes')
'users', 'subject', 'message', 'date', 'is_read', 'groups', 'classes',
'classrooms',
)
def get_course_slug(self, obj):
try:
......
......@@ -11,7 +11,11 @@ from .serializers import (CourseSerializer, BasicCourseProfessorSerializer,
ProfessorMessageSerializer, ProfessorMessageReadSerializer,
)
from .permissions import (IsProfessorCoordinatorOrAdminPermissionOrReadOnly, IsAssistantOrCoordinatorOrReadOnly, IsAdminOrReadOnly)
from .permissions import (
IsProfessorCoordinatorOrAdminPermissionOrReadOnly,
IsAssistantOrCoordinatorOrAdminOrRecipient,
IsAdminOrReadOnly,
)
class CourseViewSet(viewsets.ModelViewSet):
......@@ -89,14 +93,15 @@ class BaseCourseProfessorViewSet(viewsets.ModelViewSet):
class ProfessorMessageViewSet(viewsets.ModelViewSet):
model = ProfessorMessage
lookup_field = 'id'
filter_fields = ('course',)
queryset = ProfessorMessage.objects.all()
filter_fields = ('course', 'classrooms')
serializer_class = ProfessorMessageSerializer
permission_classes = (IsAssistantOrCoordinatorOrReadOnly,)
permission_classes = (IsAssistantOrCoordinatorOrAdminOrRecipient,)
def perform_create(self, serializer):
classes = serializer.context['request'].data.get('classes', None)
recipients = serializer.context['request'].data.get('users', None)
classrooms = serializer.context['request'].data.get('classroom', None)
users_to_be_added = []
User = get_user_model()
......@@ -110,13 +115,28 @@ class ProfessorMessageViewSet(viewsets.ModelViewSet):
klass = Class.objects.get(id=class_id)
for user in klass.students.all():
users_to_be_added.append(user.id)
elif classrooms:
for classrooms_id in classrooms:
classrooms = Classrooms.objects.get(id=classrooms_id)
users_to_be_added = classrooms.group.user_set.all()
obj = serializer.save(professor=self.request.user, users=users_to_be_added)
if obj:
obj.send()
def get_queryset(self):
queryset = ProfessorMessage.objects.filter(users__in=[self.request.user]).order_by('-id')
queryset = super().get_queryset()
query = Q(
Q(users=self.request.user)
| Q(groups__in=self.request.user.groups.all())
| Q(professor=self.request.user)
)
queryset = queryset.filter(query).order_by('-id').distinct()
classroom = self.request.query_params.get('classroom', None)
if classroom:
queryset = queryset.filter(classrooms=classroom)
unread = self.request.query_params.get('unread', None)
if unread:
......@@ -127,15 +147,14 @@ class ProfessorMessageViewSet(viewsets.ModelViewSet):
if limit_to:
queryset = queryset[:int(limit_to)]
return queryset
return queryset.prefetch_related('classrooms', 'classes', 'users', 'groups',).select_related('course', 'professor')
# This view creates ProfessorMessages targeting specific users and with no ties to any course
# Only site admins can create messages using this endpoint
class ProfessorGlobalMessageViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
class ProfessorGlobalMessageViewSet(ProfessorMessageViewSet):
"""
This view creates ProfessorMessages targeting specific users and with no ties to any course
Only site admins can create messages using this endpoint
"""
model = ProfessorMessage
serializer_class = ProfessorMessageSerializer
permission_classes = (IsAdminOrReadOnly,)
......@@ -163,16 +182,6 @@ class ProfessorGlobalMessageViewSet(mixins.CreateModelMixin,
if obj:
obj.send()
def get_queryset(self):
# Get all admin messages sent using this view
queryset = ProfessorMessage.objects.filter(course=None).order_by('-id')
limit_to = self.request.query_params.get('limit_to', None)
if limit_to:
queryset = queryset[:int(limit_to)]
return queryset
class ProfessorMessageReadViewSet(viewsets.ModelViewSet):
model = ProfessorMessageRead
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment