api.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. """
  2. Module functions for ACLs
  3. Workflow for ACLs in Misago is simple:
  4. First, you get user ACL. Its directory that you can introspect to find out user
  5. permissions, or if you have objects, you can use this acl to make those objects
  6. aware of their ACLs. This gives objects themselves special "acl" attribute with
  7. properties defined by ACL providers within their "add_acl_to_target"
  8. """
  9. import copy
  10. from django.contrib.auth import get_user_model
  11. from misago.acl import version
  12. from misago.acl.builder import build_acl
  13. from misago.acl.providers import providers
  14. from misago.core import threadstore
  15. from misago.core.cache import cache
  16. def get_user_acl(user):
  17. """
  18. Get ACL for User
  19. """
  20. acl_key = 'acl_%s' % user.acl_key
  21. acl_cache = threadstore.get(acl_key)
  22. if not acl_cache:
  23. acl_cache = cache.get(acl_key)
  24. if acl_cache and version.is_valid(acl_cache.get('_acl_version')):
  25. return acl_cache
  26. else:
  27. new_acl = build_acl(user.get_roles())
  28. new_acl['_acl_version'] = version.get_version()
  29. threadstore.set(acl_key, new_acl)
  30. cache.set(acl_key, new_acl)
  31. return new_acl
  32. def add_acl(user, target):
  33. """
  34. Add valid ACL to target (iterable of objects or single object)
  35. """
  36. if hasattr(target, '__iter__'):
  37. for item in target:
  38. _add_acl_to_target(user, item)
  39. else:
  40. _add_acl_to_target(user, target)
  41. def _add_acl_to_target(user, target):
  42. """
  43. Add valid ACL to single target, helper for add_acl function
  44. """
  45. if isinstance(target, get_user_model()):
  46. target.acl_ = {}
  47. else:
  48. target.acl = {}
  49. for annotator in providers.get_type_annotators(target):
  50. annotator(user, target)
  51. def serialize_acl(target):
  52. """
  53. Serialize single target's ACL
  54. Serializers shouldn't really serialize ACL's, only prepare acl dict
  55. for json serialization
  56. """
  57. serialized_acl = copy.deepcopy(target.acl)
  58. for serializer in providers.get_type_serializers(target):
  59. serializer(serialized_acl)
  60. return serialized_acl