Commit b92d223e authored by Florent Chehab's avatar Florent Chehab
Browse files

Merge branch 'connect_back_front' into 'master'

Connect back front

See merge request chehabfl/outgoing_rex!36
parents a938e15d 6ff038f3
Pipeline #27364 passed with stages
in 3 minutes and 1 second
......@@ -9,7 +9,7 @@ class Currency(MyModel):
code = models.CharField(primary_key=True, max_length=3)
name = models.CharField(max_length=100)
symbol = models.CharField(null=True, blank=True, max_length=30)
symbol = models.CharField(default='', blank=True, max_length=30)
one_EUR_in_this_currency = models.DecimalField(
max_digits=20,
decimal_places=6,
......
......@@ -15,7 +15,7 @@ class Offer(MyModel):
nb_seats_offered_exchange = models.PositiveIntegerField(null=True)
nb_seats_offered_double_degree = models.PositiveIntegerField(null=True)
specialty = models.ManyToManyField(
specialties = models.ManyToManyField(
Specialty, related_name="has_seats_at_univ")
class Meta:
......
......@@ -5,4 +5,3 @@ from .universityDri import UniversityDri, UniversityDriSerializer, UniversityDri
from .universityInfo import UniversityInfo, UniversityInfoSerializer, UniversityInfoViewSet # noqa: F401
from .universitySemestersDates import UniversitySemestersDates, UniversitySemestersDatesSerializer, UniversitySemestersDatesViewSet # noqa: F401
from .universityTaggedItem import UniversityTaggedItem, UniversityTaggedItemSerializer, UniversityTaggedItemViewSet # noqa: F401
from .universityModulesAPI import UniversityModulesViewSet # noqa: F401
......@@ -24,10 +24,10 @@ class University(MyModel):
model_config = get_model_config("University")
name = models.CharField(max_length=200)
acronym = models.CharField(max_length=20, null=True, blank=True)
logo = models.URLField(null=True, blank=True, validators=[
acronym = models.CharField(max_length=20, default='', blank=True)
logo = models.URLField(default='', blank=True, validators=[
validate_extension_django])
website = models.URLField(null=True, blank=True)
website = models.URLField(default='', blank=True, max_length=300)
utc_id = models.IntegerField(unique=True)
......
......@@ -6,7 +6,7 @@ from backend.utils import get_model_config, get_viewset_permissions
class UniversityDri(BasicModule):
model_config = get_model_config("UniversityDri")
university = models.ManyToManyField(
universities = models.ManyToManyField(
University, related_name="university_dri")
@classmethod
......@@ -15,6 +15,7 @@ class UniversityDri(BasicModule):
class UniversityDriSerializer(BasicModuleSerializer):
FORCE_FULL_DISPLAY = True
class Meta:
model = UniversityDri
......@@ -25,3 +26,9 @@ class UniversityDriViewSet(BasicModuleViewSet):
permission_classes = get_viewset_permissions("UniversityDriViewSet")
queryset = UniversityDri.objects.all() # pylint: disable=E1101
serializer_class = UniversityDriSerializer
BYPASS_DICT_MODE = True
def extend_queryset(self):
univ_id = self.kwargs['univ_id']
return self.my_model_queryset.filter(universities__pk=univ_id).distinct()
......@@ -26,7 +26,8 @@ class UniversityInfo(BasicModule):
null=True
)
costs_currency = models.ForeignKey(Currency, on_delete=models.PROTECT)
costs_currency = models.ForeignKey(
Currency, on_delete=models.PROTECT, null=True)
@classmethod
def get_serializer(cls):
......
from backend.models.university import University
from backend.models.campus import CampusSerializer
from backend.models.university import UniversityDriSerializer
from backend.models.university import UniversityInfoSerializer
from backend.models.university import UniversityScholarshipSerializer
from backend.models.university import UniversitySemestersDatesSerializer
from backend.models.university import UniversityTaggedItemSerializer
from backend.models.abstract.my_model import MyModelSerializer, MyModelViewSet
from backend.utils import get_viewset_permissions
class UniversityModulesSerializer(MyModelSerializer):
university_campuses = CampusSerializer(many=True, read_only=True)
university_scholarships = UniversityScholarshipSerializer(
many=True, read_only=True)
university_tagged_items = UniversityTaggedItemSerializer(
many=True, read_only=True)
university_dri = UniversityDriSerializer(many=True, read_only=True)
university_info = UniversityInfoSerializer(read_only=True)
university_semesters_dates = UniversitySemestersDatesSerializer(
read_only=True)
class Meta:
model = University
fields = '__all__'
class UniversityModulesViewSet(MyModelViewSet):
permission_classes = get_viewset_permissions("UniversityModulesViewSet")
serializer_class = UniversityModulesSerializer
queryset = University.objects.all()
LIST_SHOULD_BE_DETAIL = True
def extend_queryset(self):
univ_id = self.kwargs['univ_id']
return self.my_model_queryset.filter(pk=univ_id).prefetch_related(
'university_campuses',
'university_dri',
'university_info',
'university_scholarships',
'university_semesters_dates',
'university_tagged_items'
) # pylint: disable=E1101
......@@ -6,7 +6,8 @@ from backend.utils import get_model_config, get_viewset_permissions
class UniversityScholarship(Scholarship):
model_config = get_model_config("UniversityScholarship")
university = models.ManyToManyField(University, related_name="university_scholarships")
universities = models.ManyToManyField(
University, related_name="university_scholarships")
@classmethod
def get_serializer(cls):
......@@ -14,6 +15,7 @@ class UniversityScholarship(Scholarship):
class UniversityScholarshipSerializer(ScholarshipSerializer):
FORCE_FULL_DISPLAY = True
class Meta:
model = UniversityScholarship
......@@ -25,3 +27,9 @@ class UniversityScholarshipViewSet(ScholarshipViewSet):
"UniversityScholarshipViewSet")
queryset = UniversityScholarship.objects.all() # pylint: disable=E1101
serializer_class = UniversityScholarshipSerializer
BYPASS_DICT_MODE = True
def extend_queryset(self):
univ_id = self.kwargs['univ_id']
return self.my_model_queryset.filter(universities__pk=univ_id).distinct()
......@@ -29,7 +29,8 @@ class UniversitySemestersDates(BasicModule):
class UniversitySemestersDatesSerializer(BasicModuleSerializer):
def my_validate(self, attrs):
attrs = super(UniversitySemestersDatesSerializer, self).my_validate(attrs)
attrs = super(UniversitySemestersDatesSerializer,
self).my_validate(attrs)
s_b, s_e = attrs['spring_begin'], attrs['spring_end']
a_b, a_e = attrs['autumn_begin'], attrs['autumn_end']
......@@ -45,9 +46,6 @@ class UniversitySemestersDatesSerializer(BasicModuleSerializer):
test(s_b, s_e, 'spring')
test(a_b, a_e, 'autumn')
if s_b is None and a_b is None:
semester_error('autaumn and spring')
return attrs
class Meta:
......
......@@ -27,3 +27,9 @@ class UniversityTaggedItemViewSet(TaggedItemViewSet):
permission_classes = get_viewset_permissions("UniversityTaggedItemViewSet")
queryset = UniversityTaggedItem.objects.all() # pylint: disable=E1101
serializer_class = UniversityTaggedItemSerializer
BYPASS_DICT_MODE = True
def extend_queryset(self):
univ_id = self.kwargs['univ_id']
return self.my_model_queryset.filter(university__pk=univ_id).distinct()
......@@ -15,7 +15,7 @@ class PreviousDeparture(MyModel):
university = models.ForeignKey(University, on_delete=models.PROTECT)
specialty = models.ForeignKey(Specialty, on_delete=models.PROTECT)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
# Usefull to relink a departure with a user
# Useful to relink a departure with a user
Utc_departure_id = models.IntegerField()
is_anonymous = models.BooleanField()
......
......@@ -13,8 +13,8 @@ class PreviousDepartureFeedback(UserRestrictedModule):
PreviousDeparture, on_delete=models.CASCADE)
courses_and_courses_feedback = JSONField(default=dict)
adequation_comment = models.TextField()
integration_comment = models.TextField()
adequation_comment = models.CharField(default='', blank=True, max_length=5000)
integration_comment = models.CharField(default='', blank=True, max_length=5000)
adequation_grate = models.PositiveIntegerField(
validators=[MaxValueValidator(20)])
integration_grade = models.PositiveIntegerField(
......
......@@ -17,7 +17,7 @@ class Recommendation(UserRestrictedModule):
specialty = models.ForeignKey(Specialty, on_delete=models.PROTECT)
order_in_list = models.PositiveIntegerField()
comment = models.TextField(null=True, blank=True)
comment = models.CharField(default='', blank=True, max_length=5000)
grade = models.PositiveIntegerField(
null=True, validators=[MaxValueValidator(20)])
......
......@@ -4,13 +4,15 @@ from backend.models.university import University
from backend.fields import JSONField
from backend.models.abstract.my_model import MyModel, MyModelSerializer, MyModelViewSet
from django.contrib.auth.models import User
from backend.utils import get_viewset_permissions, get_model_config
from backend.utils import get_viewset_permissions, get_model_config, get_user_level
from backend.permissions.__list_user_post_permission import list_user_post_permission
class UserData(MyModel):
model_config = get_model_config("UserData")
owner = models.OneToOneField(User, on_delete=models.CASCADE)
owner = models.OneToOneField(
User, on_delete=models.CASCADE, primary_key=True)
contact_info = JSONField(default=dict)
contact_info_is_public = models.BooleanField(default=False)
config = JSONField(default=dict)
......@@ -21,6 +23,14 @@ class UserData(MyModel):
class UserDataSerializer(MyModelSerializer):
owner = serializers.CharField(read_only=True)
owner_level = serializers.SerializerMethodField()
owner_can_post_to = serializers.SerializerMethodField()
def get_owner_level(self, obj):
return get_user_level(obj.owner)
def get_owner_can_post_to(self, obj):
return list_user_post_permission(obj.owner)
def my_pre_save(self):
self.override_validated_data({'owner': self.user})
......@@ -38,7 +48,7 @@ class UserDataSerializer(MyModelSerializer):
class UserDataViewSet(MyModelViewSet):
permission_classes = get_viewset_permissions("UserDataViewSet")
serializer_class = UserDataSerializer
BYPASS_DICT_MODE = True
LIST_SHOULD_BE_DETAIL = True
def get_queryset(self):
return UserData.objects.filter(owner=self.request.user) # pylint: disable=E1101
{
"staff": {
"level": 3,
"label": "Administrateurs et administratrices du site"
},
"DRI": {
"level": 2,
"label": "Membres de la DRI"
},
"moderator": {
"level": 1,
"label": "Modérateurs et modératrices"
},
"authenticated_user": {
"level": 0,
"label": "Utilisateurs et utilisatrices authentifiées"
}
}
\ No newline at end of file
from .noDeleteIfNotStaff import NoDeleteIfNotStaff # noqa: F401
from .isOwner import IsOwner # noqa: F401
from .noDelete import NoDelete # noqa: F401
from .isStaffOrReadOnly import IsStaffOrReadOnly # noqa: F401
from .readOnly import ReadOnly # noqa: F401
from .isDriOrReadOnly import IsDriOrReadOnly # noqa: F401
from .default_viewset_permissions import DEFAULT_VIEWSET_PERMISSIONS # noqa: F401
from .obj_moderation_permission import OBJ_MODERATION_PERMISSIONS # noqa: F401
from .obj_moderation_permission import DEFAULT_OBJ_MODERATION_LV # noqa: F401
from .is_moderation_required import is_moderation_required # noqa: F401
try:
# the two imports are used outside of django
# the try catch is here to prevent the raise of error
from .noDeleteIfNotStaff import NoDeleteIfNotStaff # noqa: F401
from .isOwner import IsOwner # noqa: F401
from .noDelete import NoDelete # noqa: F401
from .isStaffOrReadOnly import IsStaffOrReadOnly # noqa: F401
from .readOnly import ReadOnly # noqa: F401
from .isDriOrReadOnly import IsDriOrReadOnly # noqa: F401
from .isDriOrNoPost import IsDriOrNoPost # noqa: F401
from .noPostIfNotStaff import NoPostIfNotStaff # noqa: F401
from .default_viewset_permissions import DEFAULT_VIEWSET_PERMISSIONS # noqa: F401
from .__is_moderation_required import is_moderation_required # noqa: F401
except Exception:
pass
from backend.utils import get_user_level
from backend.utils.__get_user_level import get_user_level
from django.conf import settings
from .obj_moderation_permission import OBJ_MODERATION_PERMISSIONS
def is_moderation_required(model_moderation_level, obj_in_db, user, user_level=None):
######################################
######################################
##
# IF YOU TOUCH THIS FILE, MODIFY IT'S
# JS EQUIVALENT (isModerationRequired)
##
######################################
######################################
def is_moderation_required(model_config, obj_in_db, user, user_level=None):
model_moderation_level = model_config['moderation_level']
if user_level is None:
user_level = get_user_level(user)
key = 'enforce_moderation_user_level'
if key in model_config.keys() and model_config[key] is not None:
if user_level < model_config[key]:
return True
if model_moderation_level == 0:
return False
else:
......@@ -18,11 +34,11 @@ def is_moderation_required(model_moderation_level, obj_in_db, user, user_level=N
if model_moderation_level == 1:
if settings.MODERATION_ACTIVATED:
return user_level < OBJ_MODERATION_PERMISSIONS["moderator"]
return not user_level >= OBJ_MODERATION_PERMISSIONS["moderator"]
else:
return False
elif model_moderation_level == 2:
return not user_level < OBJ_MODERATION_PERMISSIONS["moderator"]
return not user_level >= OBJ_MODERATION_PERMISSIONS["moderator"]
else:
raise Exception(
"No other moderation level should be defined...")
from rest_framework import permissions
from backend.utils import is_member
class IsDriOrNoPost(permissions.BasePermission):
"""
TODO
"""
def has_permission(self, request, view):
if request.method == 'POST':
return is_member("DRI", request.user) or request.user.is_staff
return True
from rest_framework import permissions
class NoPostIfNotStaff(permissions.BasePermission):
"""
TODO
"""
def has_permission(self, request, view):
if request.method == 'POST':
return request.user.is_staff
return True
OBJ_MODERATION_PERMISSIONS = {
"staff": 3,
"DRI": 2,
"moderator": 1,
"authenticated_user": 0
}
import json
from os.path import join, realpath, dirname
current_dir = dirname(realpath(__file__))
with open(join(current_dir, 'OBJ_MODERATION_PERMISSIONS.json'), 'r') as f:
tmp = json.load(f)
OBJ_MODERATION_PERMISSIONS = {}
for key in tmp:
OBJ_MODERATION_PERMISSIONS[key] = tmp[key]['level']
DEFAULT_OBJ_MODERATION_LV = OBJ_MODERATION_PERMISSIONS["authenticated_user"]
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