skillbox/server/users/models.py

115 lines
4.0 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)
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)
year = models.PositiveIntegerField(blank=False, null=False,
validators=[MinValueValidator(1900), MaxValueValidator(2200)])
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, self.year)
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)