118 lines
4.1 KiB
Python
118 lines
4.1 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import AbstractUser, Permission
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
|
from django.db import models
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
from users.managers import RoleManager, UserRoleManager
|
|
|
|
DEFAULT_SCHOOL_ID = 1
|
|
|
|
|
|
class User(AbstractUser):
|
|
last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True)
|
|
avatar_url = models.CharField(max_length=254, blank=True, default='')
|
|
email = models.EmailField(_('email address'), unique=True)
|
|
|
|
def get_role_permissions(self):
|
|
perms = set()
|
|
for role in Role.objects.get_roles_for_user(self):
|
|
perms = perms.union(
|
|
('{}.{}'.format(r.content_type.app_label, r.codename) for r in role.role_permission.all())
|
|
)
|
|
return perms
|
|
|
|
def get_all_permissions(self, obj=None):
|
|
"""
|
|
works as long as we have only a single school
|
|
:param obj:
|
|
:return: django permissions and school permissions for single default school
|
|
"""
|
|
django_permissions = super().get_all_permissions(obj)
|
|
return django_permissions.union(self.get_role_permissions())
|
|
|
|
def has_perm(self, perm, obj=None):
|
|
return super(User, self).has_perm(perm, obj) or perm in self.get_all_permissions(obj)
|
|
|
|
def users_in_same_school_class(self):
|
|
return User.objects.filter(school_classes__users=self.pk)
|
|
|
|
@property
|
|
def full_name(self):
|
|
return self.get_full_name()
|
|
|
|
|
|
class SchoolClass(models.Model):
|
|
name = models.CharField(max_length=100, blank=False, null=False, unique=True)
|
|
is_deleted = models.BooleanField(blank=False, null=False, default=False)
|
|
users = models.ManyToManyField(get_user_model(), related_name='school_classes')
|
|
|
|
def __str__(self):
|
|
return 'SchoolClass {}-{}'.format(self.id, self.name)
|
|
|
|
def is_user_in_schoolclass(self, user):
|
|
return user.is_superuser or user.school_classes.filter(pk=self.id).count() > 0
|
|
|
|
|
|
class Role(models.Model):
|
|
key = models.CharField(_('Key'), max_length=100, blank=False, null=False, unique=True)
|
|
name = models.CharField(_('Name'), max_length=100, blank=False, null=False)
|
|
role_permission = models.ManyToManyField(Permission, verbose_name=_('Role permission'),
|
|
blank=True, related_name="role_set", related_query_name="role")
|
|
|
|
objects = RoleManager()
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
def permissions_as_code(self):
|
|
return self.role_permission.values_list('codename', flat=True)
|
|
|
|
def has_permission(self, permission_name):
|
|
try:
|
|
self.role_permission.get(codename=permission_name)
|
|
return True
|
|
except Permission.DoesNotExist:
|
|
return False
|
|
|
|
@staticmethod
|
|
def create_key(name):
|
|
return name.lower()
|
|
|
|
class Meta:
|
|
permissions = (
|
|
# ("can_edit_events", "Can edit events"),
|
|
# ("can_edit_own_comments", "Can edit own comments"),
|
|
# ("can_delete_comments", "Can delete comments"),
|
|
('can_manage_school_class_content', 'Can manage contents for assigned school clases'),
|
|
# ("can_admin_school", "Can admin school"),
|
|
)
|
|
|
|
|
|
class UserRole(models.Model):
|
|
user = models.ForeignKey(User, blank=False, null=False, on_delete=models.CASCADE, related_name='user_roles')
|
|
role = models.ForeignKey(Role, blank=False, null=False, on_delete=models.CASCADE, related_name='user_roles')
|
|
|
|
objects = UserRoleManager()
|
|
|
|
@property
|
|
def groups(self):
|
|
return SchoolClass.objects.filter(users=self.user.id)
|
|
|
|
@property
|
|
def group_ids(self):
|
|
return map(lambda g: g.id, self.groups)
|
|
|
|
@classmethod
|
|
def get_roles_for_user(cls, user):
|
|
roles = UserRole.objects.filter(user=user)
|
|
return roles
|
|
|
|
@classmethod
|
|
def get_role_for_user(cls, user):
|
|
return UserRole.get_roles_for_user(user).first()
|
|
|
|
def __str__(self):
|
|
return '%s: %s' % (self.role, self.user)
|