Completed
Pull Request — master (#18)
by Camille
01:03
created

GroupAcknowledgment   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 12
Duplicated Lines 0 %

Test Coverage

Coverage 0%
Metric Value
dl 0
loc 12
ccs 0
cts 0
cp 0
rs 10
wmc 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A __str__() 0 5 2
1
from django.db import models
2
3
from dry_rest_permissions.generics import allow_staff_or_superuser
4
5
# class GroupManager(models.Manager):
6
#     # TODO: Determine whether 'memberships' fields needs to be retrieved every time or not...
7
#     def get_queryset(self):
8
#         return super(GroupManager, self).get_queryset().prefetch_related('memberships')
9
10
11
class Group(models.Model):
12
    #########################
13
    # Constants and choices #
14
    #########################
15
    ADMINISTRATOR_RANK  = 10
16
17
    VIS_PUBLIC          = 'public'
18
    VIS_PRIVATE         = 'private'
19
    VISIBILITY_CHOICES = (
20
        (VIS_PUBLIC, 'Anyone can see the group'),
21
        (VIS_PRIVATE, 'Group is not visible')
22
    )
23
24
    TYPE_BASIC          = 'basic'
25
    TYPE_CURSUS         = 'cursus'
26
    TYPE_ASSO           = 'association'
27
    TYPE_PROMO          = 'school_promotion'
28
    TYPE_SCHOOL         = 'school'
29
    TYPE_CHOICES = (
30
        (TYPE_BASIC, 'Simple group'),
31
        (TYPE_CURSUS, 'Cursus or department'),
32
        (TYPE_ASSO, 'Association'),
33
        (TYPE_PROMO, 'School promotion'),
34
        (TYPE_SCHOOL, 'School')
35
    )
36
37
    ##########
38
    # Fields #
39
    ##########
40
    name = models.CharField(max_length=254)
41
    visibility = models.CharField(max_length=64, choices=VISIBILITY_CHOICES, default=VIS_PRIVATE)
42
    type = models.CharField(max_length=64, choices=TYPE_CHOICES, default=TYPE_BASIC)
43
44
    # The school responsible of the group in case of admin conflict (can be null for non-school-related groups)
45
    resp_school = models.ForeignKey('School', null=True, blank=True, on_delete=models.SET_NULL)
46
47
    # The permission a member has upon joining
48
    # A value of -1 means that no one can join the group.
49
    # A value of 0 means that anyone can request to join the group
50
    default_member_rank = models.SmallIntegerField(default=-1)
51
    # Invite new members on the group
52
    req_rank_invite = models.SmallIntegerField(default=1)
53
    # Remove a member from the group
54
    req_rank_kick = models.SmallIntegerField(default=ADMINISTRATOR_RANK)
55
    # Upgrade someone rank 0 to rank 1
56
    req_rank_accept_join_requests = models.SmallIntegerField(default=1)
57
    # Upgrade other users (up to $yourRank - 1)
58
    req_rank_promote = models.SmallIntegerField(default=ADMINISTRATOR_RANK)
59
    # Downgrade someone (to rank 1 minimum)
60
    req_rank_demote = models.SmallIntegerField(default=ADMINISTRATOR_RANK)
61
    # Modify group description
62
    req_rank_modify_group_infos = models.SmallIntegerField(default=ADMINISTRATOR_RANK)
63
64
    # Related fields:
65
    #   - invited_users (model User)
66
    #   - memberships (model UserGroup)
67
68
    # objects = GroupManager()
69
70
    @property
71
    def acknowledged_groups(self):
72
        return [ga.asking_group for ga in self.group_acknowledgments.filter(validated=True).select_related('asking_group')]
73
74
    #################
75
    # Model methods #
76
    #################
77
    def can_anyone_join(self):
78
        return self.default_member_rank >= 0
79
80
    def __str__(self):
81
        return "%s (%s)" % (self.name, self.get_type_display())
82
83
    ###############
84
    # Permissions #
85
    ###############
86
87
    # Perms for admin site
88
    def has_perm(self, perm, obj=None):
89
        return True
90
91
    def has_module_perms(self, app_label):
92
        return True
93
94
    # DRY Permissions
95
    @staticmethod
96
    def has_read_permission(request):
97
        """
98
        All groups are visible by default.
99
        """
100
        return True
101
102
    def has_object_read_permission(self, request):
103
        """
104
        Public groups are visible by everybody. Private groups are only visible by members.
105
        """
106
        return self.visibility == Group.VIS_PUBLIC or request.user.is_group_member(self)
107
108
    @staticmethod
109
    def has_write_permission(request):
110
        return True
111
112
    @staticmethod
113
    @allow_staff_or_superuser
114
    def has_create_permission(request):
115
        """
116
        Everybody can create a private group. For other types, user must be school admin or sigma admin.
117
        """
118
        from sigma_core.models.school import School
119
        group_type = request.data.get('type', None)
120
        if group_type == Group.TYPE_BASIC:
121
            return True
122
123
        resp_school = request.data.get('resp_school', None)
124
        try:
125
            school = School.objects.get(pk=resp_school)
126
        except School.DoesNotExist:
127
            school = None
128
        return school is not None and request.user.has_group_admin_perm(school)
129
130
    @allow_staff_or_superuser
131
    def has_object_write_permission(self, request):
132
        return request.user.has_group_admin_perm(self)
133
134
    @allow_staff_or_superuser
135
    def has_object_update_permission(self, request):
136
        """
137
        Only group's admins and Sigma admins can edit a group.
138
        """
139
        return request.user.can_modify_group_infos(self)
140
141
    @allow_staff_or_superuser
142
    def has_object_invite_permission(self, request):
143
        return request.user.can_invite(self)
144
145
146
class GroupAcknowledgment(models.Model):
147
    asking_group = models.ForeignKey(Group, related_name='group_recognizers')
148
    validator_group = models.ForeignKey(Group, related_name='group_acknowledgments')
149
    validated = models.BooleanField(default=False)
150
    created = models.DateTimeField(auto_now_add=True)
151
    updated = models.DateTimeField(auto_now=True)
152
153
    def __str__(self):
154
        if self.validated:
155
            return "Group %s acknowledged by Group %s" % (self.asking_group.__str__(), self.validator_group.__str__())
156
        else:
157
            return "Group %s awaiting for acknowledgment by Group %s since %s" % (self.asking_group.__str__(), self.validator_group.__str__(), self.created.strftime("%Y-%m-%d %H:%M"))
158