Implement organization rules
This commit is contained in:
parent
f11c1ca5bc
commit
21ff6fe7d0
5 changed files with 41 additions and 33 deletions
|
@ -1,8 +1,9 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rules.contrib.models import RulesModelBase, RulesModelMixin
|
||||||
|
|
||||||
|
|
||||||
class ServalaModelMixin(models.Model):
|
class ServalaModelMixin(RulesModelMixin, models.Model, metaclass=RulesModelBase):
|
||||||
created_at = models.DateTimeField(
|
created_at = models.DateTimeField(
|
||||||
auto_now_add=True, editable=False, verbose_name=_("Created")
|
auto_now_add=True, editable=False, verbose_name=_("Created")
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import rules
|
||||||
import urlman
|
import urlman
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -6,7 +7,8 @@ from django.utils.text import slugify
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_scopes import ScopedManager
|
from django_scopes import ScopedManager
|
||||||
|
|
||||||
from .mixins import ServalaModelMixin
|
from servala.core import rules as perms
|
||||||
|
from servala.core.models.mixins import ServalaModelMixin
|
||||||
|
|
||||||
|
|
||||||
class Organization(ServalaModelMixin, models.Model):
|
class Organization(ServalaModelMixin, models.Model):
|
||||||
|
@ -65,6 +67,12 @@ class Organization(ServalaModelMixin, models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("Organization")
|
verbose_name = _("Organization")
|
||||||
verbose_name_plural = _("Organizations")
|
verbose_name_plural = _("Organizations")
|
||||||
|
rules_permissions = {
|
||||||
|
"view": rules.is_staff | perms.is_organization_member,
|
||||||
|
"change": rules.is_staff | perms.is_organization_admin,
|
||||||
|
"delete": rules.is_staff | perms.is_organization_owner,
|
||||||
|
"add": rules.is_authenticated,
|
||||||
|
}
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
from django.contrib.auth.models import (
|
||||||
|
AbstractBaseUser,
|
||||||
|
BaseUserManager,
|
||||||
|
PermissionsMixin,
|
||||||
|
)
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
@ -32,7 +36,7 @@ class UserManager(BaseUserManager):
|
||||||
return self.create_user(email, password, **extra_fields)
|
return self.create_user(email, password, **extra_fields)
|
||||||
|
|
||||||
|
|
||||||
class User(ServalaModelMixin, AbstractBaseUser):
|
class User(ServalaModelMixin, PermissionsMixin, AbstractBaseUser):
|
||||||
"""The Django model provides a password and last_login field."""
|
"""The Django model provides a password and last_login field."""
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
@ -71,31 +75,3 @@ class User(ServalaModelMixin, AbstractBaseUser):
|
||||||
|
|
||||||
def normalize_username(self, username):
|
def normalize_username(self, username):
|
||||||
return super().normalize_username(username).strip().lower()
|
return super().normalize_username(username).strip().lower()
|
||||||
|
|
||||||
def has_perm(self, perm, obj=None):
|
|
||||||
"""
|
|
||||||
Return True if the user has the specified permission.
|
|
||||||
Superusers automatically have all permissions.
|
|
||||||
"""
|
|
||||||
return self.is_superuser
|
|
||||||
|
|
||||||
def has_module_perms(self, app_label):
|
|
||||||
"""
|
|
||||||
Return True if the user has any permissions in the given app label.
|
|
||||||
Superusers automatically have all permissions.
|
|
||||||
"""
|
|
||||||
return self.is_superuser
|
|
||||||
|
|
||||||
def get_all_permissions(self, obj=None):
|
|
||||||
"""
|
|
||||||
Return a set of permission strings that the user has.
|
|
||||||
Superusers have all permissions.
|
|
||||||
"""
|
|
||||||
if self.is_superuser:
|
|
||||||
from django.contrib.auth.models import Permission
|
|
||||||
|
|
||||||
return {
|
|
||||||
f"{perm.content_type.app_label}.{perm.codename}"
|
|
||||||
for perm in Permission.objects.all()
|
|
||||||
}
|
|
||||||
return set()
|
|
||||||
|
|
23
src/servala/core/rules.py
Normal file
23
src/servala/core/rules.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import rules
|
||||||
|
|
||||||
|
|
||||||
|
def has_organization_role(user, org, roles):
|
||||||
|
memberships = org.memberships.all().filter(user=user)
|
||||||
|
if roles:
|
||||||
|
memberships = memberships.filter(role__in=roles)
|
||||||
|
return memberships.exists()
|
||||||
|
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_organization_owner(user, org):
|
||||||
|
return has_organization_role(user, org, ["owner"])
|
||||||
|
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_organization_admin(user, org):
|
||||||
|
return has_organization_role(user, org, ["owner", "admin"])
|
||||||
|
|
||||||
|
|
||||||
|
@rules.predicate
|
||||||
|
def is_organization_member(user, org):
|
||||||
|
return has_organization_role(user, org, None)
|
|
@ -97,7 +97,7 @@ INSTALLED_APPS = [
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"django.forms",
|
"django.forms",
|
||||||
"template_partials",
|
"template_partials",
|
||||||
"rules",
|
"rules.apps.AutodiscoverRulesConfig",
|
||||||
# The frontend app is loaded early in order to supersede some allauth views/behaviour
|
# The frontend app is loaded early in order to supersede some allauth views/behaviour
|
||||||
"servala.frontend",
|
"servala.frontend",
|
||||||
"allauth",
|
"allauth",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue