Instantly share code, notes, and snippets.
Created
June 29, 2021 19:19
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save rj76/6e19cdf0f3b8a09720765b54aafe9c08 to your computer and use it in GitHub Desktop.
Django templatetag ACL implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# templatetags | |
from django import template | |
from apps.core import utils | |
register = template.Library() | |
module_paths_text = None | |
modules = {} | |
@register.filter(name='member_has_access_to_module', takes_context=True) | |
def member_has_access_to_module(context, module_path): | |
global module_paths_text, modules | |
user = context['request'].user | |
# cache database lookup | |
if not module_paths_text: | |
module_paths_text = context['request'].session['member'].contract.module_paths_text | |
# cache modules | |
if not modules: | |
modules = get_contract_modules(module_paths_text) | |
return utils.member_has_access_to_module(user, module_path, modules=modules) | |
@register.filter(name='usertypes_required', takes_context=True) | |
def usertypes_required(context, usertypes): | |
user = context['request'].user | |
return utils.usertypes_required(user, usertypes) | |
# apps.core.utils | |
def member_has_access_to_module(user, module_path, module_paths_text=None, modules=None): | |
# staff and superusers always have access | |
if user.is_staff or user.is_superuser: | |
return True | |
if not modules and module_paths_text: | |
modules = get_contract_modules(module_paths_text) | |
# module part check (e.g. orders:orders) | |
if ':' in module_path: | |
module, path = module_path.split(':') | |
return path in modules[module] | |
# only a module check | |
return module_path in modules | |
def get_contract_modules(module_paths_text): | |
modules = {} | |
paths = module_paths_text.split('|') | |
for path in paths: | |
_module_name, parts = path.split(':') | |
for part in parts.split(','): | |
modules[_module_name.lower()] = part.lower() | |
return modules | |
def usertypes_required(user, usertypes): | |
# staff and superusers always have access | |
if user.is_staff or user.is_superuser: | |
return True | |
for usertype in usertypes.split(','): | |
if getattr(user, usertype): | |
return True | |
return False | |
# test_utils.py | |
def get_user(is_staff=False, is_superuser=False, is_planning_user=False, is_sales_user=False, is_customer_user=False): | |
class User: | |
def __init__(self, is_staff, is_superuser, is_planning_user, is_sales_user, is_customer_user): | |
self.is_staff = is_staff | |
self.is_superuser = is_superuser | |
self.planning_user = is_planning_user | |
self.sales_user = is_sales_user | |
self.customer_user = is_customer_user | |
return User(is_staff, is_superuser, is_planning_user, is_sales_user, is_customer_user) | |
def test_member_has_access_to_module_normal_user(): | |
user = get_user() | |
module_path = 'orders' | |
module_paths_text = 'orders:order|mobile:dispatch,stats' | |
assert utils.member_has_access_to_module( | |
user, | |
module_path, | |
module_paths_text=module_paths_text) | |
def test_member_has_access_to_module_path_normal_user(): | |
user = get_user() | |
module_path = 'mobile:stats' | |
module_paths_text = 'orders:order|mobile:dispatch,stats' | |
assert utils.member_has_access_to_module( | |
user, | |
module_path, | |
module_paths_text=module_paths_text) | |
def test_member_no_access_to_module_normal_user(): | |
user = get_user() | |
module_path = 'inventory' | |
module_paths_text = 'orders:order|mobile:dispatch,stats' | |
assert not utils.member_has_access_to_module( | |
user, | |
module_path, | |
module_paths_text=module_paths_text) | |
def test_member_no_access_to_module_path_normal_user(): | |
user = get_user() | |
module_path = 'orders:stats' | |
module_paths_text = 'orders:order|mobile:dispatch,stats' | |
assert not utils.member_has_access_to_module( | |
user, | |
module_path, | |
module_paths_text=module_paths_text) | |
def test_member_has_access_to_module_staff(): | |
user = get_user(is_staff=True) | |
module_path = 'inventory' | |
module_paths_text = 'orders:order|mobile:dispatch,stats' | |
assert utils.member_has_access_to_module( | |
user, | |
module_path, | |
module_paths_text=module_paths_text) | |
def test_member_has_access_to_module_superuser(): | |
user = get_user(is_superuser=True) | |
module_path = 'inventory' | |
module_paths_text = 'orders:order|mobile:dispatch,stats' | |
assert utils.member_has_access_to_module( | |
user, | |
module_path, | |
module_paths_text=module_paths_text) | |
def test_usertypes_required_access(): | |
usertypes = 'planning_user,sales_user' | |
user = get_user(is_planning_user=True) | |
assert utils.usertypes_required(user, usertypes) | |
def test_usertypes_required_no_access(): | |
usertypes = 'planning_user' | |
user = get_user(is_sales_user=True) | |
assert not utils.usertypes_required(user, usertypes) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment