permissions.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from django.conf import settings
  2. from django.contrib.contenttypes.models import ContentType
  3. def get_permission_for_model(model, action):
  4. """
  5. Resolve the named permission for a given model (or instance) and action (e.g. view or add).
  6. :param model: A model or instance
  7. :param action: View, add, change, or delete (string)
  8. """
  9. if action not in ('view', 'add', 'change', 'delete'):
  10. raise ValueError(f"Unsupported action: {action}")
  11. return '{}.{}_{}'.format(
  12. model._meta.app_label,
  13. action,
  14. model._meta.model_name
  15. )
  16. def resolve_permission(name):
  17. """
  18. Given a permission name, return the app_label, action, and model_name components. For example, "dcim.view_site"
  19. returns ("dcim", "view", "site").
  20. :param name: Permission name in the format <app_label>.<action>_<model>
  21. """
  22. try:
  23. app_label, codename = name.split('.')
  24. action, model_name = codename.rsplit('_', 1)
  25. except ValueError:
  26. raise ValueError(
  27. f"Invalid permission name: {name}. Must be in the format <app_label>.<action>_<model>"
  28. )
  29. return app_label, action, model_name
  30. def resolve_permission_ct(name):
  31. """
  32. Given a permission name, return the relevant ContentType and action. For example, "dcim.view_site" returns
  33. (Site, "view").
  34. :param name: Permission name in the format <app_label>.<action>_<model>
  35. """
  36. app_label, action, model_name = resolve_permission(name)
  37. try:
  38. content_type = ContentType.objects.get(app_label=app_label, model=model_name)
  39. except ContentType.DoesNotExist:
  40. raise ValueError(f"Unknown app_label/model_name for {name}")
  41. return content_type, action
  42. def permission_is_exempt(name):
  43. """
  44. Determine whether a specified permission is exempt from evaluation.
  45. :param name: Permission name in the format <app_label>.<action>_<model>
  46. """
  47. app_label, action, model_name = resolve_permission(name)
  48. if action == 'view':
  49. if (
  50. # All models are exempt from view permission enforcement
  51. '*' in settings.EXEMPT_VIEW_PERMISSIONS
  52. ) or (
  53. # This specific model is exempt from view permission enforcement
  54. '{}.{}'.format(app_label, model_name) in settings.EXEMPT_VIEW_PERMISSIONS
  55. ):
  56. return True
  57. return False