test_permission_matrix.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. def test_fixed_role_permission_matrix_is_monotonic():
  2. from app.core.system.permissions import ROLE_PERMISSIONS
  3. viewer = ROLE_PERMISSIONS["viewer"]
  4. editor = ROLE_PERMISSIONS["editor"]
  5. admin = ROLE_PERMISSIONS["admin"]
  6. assert viewer < editor < admin
  7. assert "governance:read" in viewer
  8. assert "governance:edit" in editor
  9. assert "users:manage" in admin
  10. assert "workflow:activate" in admin
  11. def test_permissions_are_derived_server_side_from_roles():
  12. from app.core.system.permissions import permissions_for_roles
  13. permissions = permissions_for_roles(["viewer", "editor"])
  14. assert "governance:read" in permissions
  15. assert "governance:edit" in permissions
  16. assert "users:manage" not in permissions
  17. def test_every_api_path_has_an_explicit_policy():
  18. from app import create_app
  19. from app.core.system.permissions import permission_for_request
  20. app = create_app()
  21. for rule in app.url_map.iter_rules():
  22. if not rule.rule.startswith("/api/"):
  23. continue
  24. for method in rule.methods - {"HEAD", "OPTIONS"}:
  25. assert permission_for_request(rule.rule, method) is not None, (
  26. method,
  27. rule.rule,
  28. )
  29. def test_knowledge_search_and_ask_posts_are_read_only():
  30. from app.core.system.permissions import READ_GOVERNANCE, permission_for_request
  31. assert permission_for_request("/api/knowledge/search", "POST") == (
  32. READ_GOVERNANCE,
  33. )
  34. assert permission_for_request("/api/knowledge/ask", "POST") == (READ_GOVERNANCE,)
  35. def test_knowledge_admin_routes_require_dedicated_manage_permission():
  36. from app.core.system.permissions import KNOWLEDGE_MANAGE, permission_for_request
  37. assert permission_for_request("/api/knowledge/admin/sync", "GET") == (
  38. KNOWLEDGE_MANAGE,
  39. )
  40. assert permission_for_request(
  41. "/api/knowledge/admin/change-sets/id/retry", "POST"
  42. ) == (KNOWLEDGE_MANAGE,)
  43. def test_data_rule_routes_separate_read_authoring_and_release_permissions():
  44. from app.core.system.permissions import (
  45. DATAFLOW_RELEASE,
  46. RULES_EDIT,
  47. RULES_PUBLISH,
  48. RULES_READ,
  49. permission_for_request,
  50. )
  51. assert permission_for_request("/api/rules/capabilities", "GET") == (
  52. RULES_READ,
  53. )
  54. assert permission_for_request("/api/rules/interpret", "POST") == (
  55. RULES_EDIT,
  56. )
  57. assert permission_for_request("/api/rules/validate", "POST") == (
  58. RULES_EDIT,
  59. )
  60. assert permission_for_request(
  61. "/api/rules/versions/id/publish", "POST"
  62. ) == (RULES_PUBLISH,)
  63. assert permission_for_request(
  64. "/api/rules/production-lines/id/release", "POST"
  65. ) == (DATAFLOW_RELEASE,)
  66. def test_data_factory_actions_have_independent_permissions():
  67. from app.core.system.permissions import (
  68. DATAFLOW_ACTIVATE,
  69. DATAFLOW_CANARY,
  70. DATAFLOW_DEPLOY,
  71. DATAFLOW_ROLLBACK,
  72. RULES_EXECUTE,
  73. permission_for_request,
  74. )
  75. assert permission_for_request("/api/rules/deployments", "POST") == (
  76. DATAFLOW_DEPLOY,
  77. )
  78. assert permission_for_request(
  79. "/api/rules/deployments/id/deploy-disabled", "POST"
  80. ) == (DATAFLOW_DEPLOY,)
  81. assert permission_for_request(
  82. "/api/rules/deployments/id/canary", "POST"
  83. ) == (DATAFLOW_CANARY, RULES_EXECUTE)
  84. assert permission_for_request(
  85. "/api/rules/deployments/id/activate", "POST"
  86. ) == (DATAFLOW_ACTIVATE,)
  87. assert permission_for_request(
  88. "/api/rules/deployments/id/rollback", "POST"
  89. ) == (DATAFLOW_ROLLBACK,)
  90. assert permission_for_request(
  91. "/api/rules/deployments/id/reconcile-deploy", "POST"
  92. ) == (DATAFLOW_DEPLOY,)
  93. assert permission_for_request(
  94. "/api/rules/deployments/id/reconcile-activate", "POST"
  95. ) == (DATAFLOW_ACTIVATE,)
  96. assert permission_for_request(
  97. "/api/rules/deployments/id/reconcile-rollback", "POST"
  98. ) == (DATAFLOW_ROLLBACK,)