class AbakusGroup(MPTTModel, PersistentModel): name = models.CharField(max_length=80, unique=True, db_index=True) description = models.CharField(blank=True, max_length=200) contact_email = models.EmailField(blank=True) parent = TreeForeignKey( "self", blank=True, null=True, related_name="children", on_delete=models.SET_NULL, ) logo = FileField(related_name="group_pictures") type = models.CharField(max_length=10, choices=constants.GROUP_TYPES, default=constants.GROUP_OTHER) text = models.TextField(blank=True) permissions = ArrayField( models.CharField(validators=[KeywordPermissionValidator()], max_length=50), verbose_name="permissions", default=list, ) objects = AbakusGroupManagerWithoutText() objects_with_text = AbakusGroupManager() show_badge = models.BooleanField(default=True) class Meta: permission_handler = AbakusGroupPermissionHandler() def __str__(self): return self.name @property def is_committee(self): return self.type == constants.GROUP_COMMITTEE @property def is_grade(self): return self.type == constants.GROUP_GRADE @property def leader(self): """Assume there is only one leader, or that we don't care about which leader we get if there is multiple leaders""" membership = self.memberships.filter(role="leader").first() if membership: return membership.user return None @abakus_cached_property def memberships(self): descendants = self.get_descendants(True) return Membership.objects.filter( deleted=False, is_active=True, user__abakus_groups__in=descendants, abakus_group__in=descendants, ) @abakus_cached_property def number_of_users(self): return self.memberships.distinct("user").count() def add_user(self, user, **kwargs): membership, _ = Membership.objects.update_or_create(user=user, abakus_group=self, defaults={ "deleted": False, **kwargs }) return membership def remove_user(self, user): membership = Membership.objects.get(user=user, abakus_group=self) membership.delete() def natural_key(self): return (self.name, ) def restricted_lookup(self): """ Restricted Mail """ memberships = self.memberships.filter(email_lists_enabled=True) return [membership.user for membership in memberships], [] def announcement_lookup(self): memberships = self.memberships return [membership.user for membership in memberships]
def test_regex_validator_non_letters(self): validator = KeywordPermissionValidator() self.assertRaises(ValidationError, validator.__call__, '/1234/')
def test_regex_validator_starting_slash(self): validator = KeywordPermissionValidator() self.assertRaises(ValidationError, validator.__call__, 'sudo/')
def test_regex_validator_double_start_slash(self): """ Two slashes in the beginning of the string is not allowed. """ validator = KeywordPermissionValidator() self.assertRaises(ValidationError, validator.__call__, '//sudo/')
def test_regex_validator_valid(self): validator = KeywordPermissionValidator() validator.__call__('/sudo/')