api.py 2.1 KB

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