Skip to content

Instantly share code, notes, and snippets.

@lucemia
Created January 17, 2018 15:04
Show Gist options
  • Save lucemia/f9c06ea45e99c3c4227f6bd635a84171 to your computer and use it in GitHub Desktop.
Save lucemia/f9c06ea45e99c3c4227f6bd635a84171 to your computer and use it in GitHub Desktop.
django-rules
from __future__ import absolute_import
import rules
from employee.rules import is_project_owner, is_director, is_g3, is_g4, is_bp, is_user, is_team_leader, is_division_manager, is_superuser, is_employee
from .models import Document, Project
from django.db.models import Q
from django.core.cache import cache
import json
def has_perm_projects(user__id):
key = "has_perm_projects__{}".format(user__id)
cached = cache.get(key)
if not cached:
result = [p.id for p in Project.objects.filter(participants__user=user__id)]
# cache can't set empty list
cache.set(key, json.dumps(result), 30)
return result
else:
result = json.loads(cached)
return result
def has_perm_documents(user__id):
key = "has_perm_documents__{}".format(user__id)
cached = cache.get(key)
if not cached:
projects = has_perm_projects(user__id)
documents = Document.objects.filter(Q(project__id__in=projects) | Q(owner__user__id=user__id))
result = [document.id for document in documents]
# cache can't set empty list
cache.set(key, json.dumps(result), 30)
return result
else:
return json.loads(cached)
@rules.predicate
def is_obj(user, obj):
return obj is not None
@rules.predicate
def is_doc_owner(user, document):
return document.id in has_perm_documents(user.id)
@rules.predicate
def can_review_document(user, document):
if document.status == "submit" and is_project_owner(user, document.project):
return True
if document.status == "apply" and (is_director(user, document) or is_g3(user, document) or is_g4(user, document)):
return True
if document.status == "approve" and is_bp(user, document):
return True
return False
@rules.predicate
def can_view_project(user, project):
return project.id in has_perm_projects(user.id)
@rules.predicate
def can_submit_document(user, document):
return can_view_project(user, document.project) and document.status in ('init', 'deny')
def can_view_document_field(f):
@rules.predicate
def can_view(user, document=None):
if document and f in (document.submission_require_field(), 'project', 'type'):
return True
return False
return can_view
def can_change_document_field(f):
@rules.predicate
def can_change(user, document=None):
if document and f == document.submission_require_field() and document.status != 'approve':
return True
return False
return can_change
def can_view_project_field(f):
@rules.predicate
def can_view(user, project=None):
if project and not project.is_open and f in ('profit', 'budget'):
if is_superuser(user, project) or is_director(user):
return True
return False
return True
return can_view
def can_change_project_field(f):
@rules.predicate
def can_change(user, project=None):
if project and f in ('start_date', 'visit_date', 'brainStorm_first_date', 'internal_proposal_date', 'external_proposal_date', 'sign_contract_date', 'execution_start_date', 'execution_end_date', 'internal_closed_date', 'external_closed_date'):
return True
return False
return can_change
def fields(cls):
return [k.name for k in cls._meta.get_fields() if not k.auto_created or k.concrete]
rules.add_perm('project', is_employee)
rules.add_perm('project.add_project', is_employee)
rules.add_perm('project.view_project', is_superuser | can_view_project)
rules.add_perm('project.change_project', (is_employee & ~is_obj) | is_superuser)
for field in fields(Project):
rules.add_perm('project.project.view_%s' % field, can_view_project_field(field))
rules.add_perm('project.project.change_%s' % field, (is_employee & ~is_obj) | is_superuser | can_change_project_field(field))
rules.add_perm('project.change_document', (is_employee & ~is_obj) | is_superuser)
rules.add_perm('project.view_document', is_superuser | is_doc_owner | is_director | can_submit_document)
rules.add_perm('project.review_document', can_review_document)
rules.add_perm('project.submit_document', can_submit_document)
for field in fields(Document):
rules.add_perm('project.document.view_%s' % field, can_view_document_field(field))
rules.add_perm('project.document.change_%s' % field, can_change_document_field(field))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment