You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
7.0 KiB

  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2017 Marcos Pereira <marcospereira.mpj@gmail.com>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Lesser General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Lesser General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Lesser General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. """Test uma permissions."""
  18. import re
  19. import pytest
  20. from keycloak.exceptions import KeycloakPermissionFormatError, PermissionDefinitionError
  21. from keycloak.uma_permissions import (
  22. AuthStatus,
  23. Resource,
  24. Scope,
  25. UMAPermission,
  26. build_permission_param,
  27. )
  28. def test_uma_permission_obj():
  29. """Test generic UMA permission."""
  30. with pytest.raises(PermissionDefinitionError):
  31. UMAPermission(permission="bad")
  32. p1 = UMAPermission(permission=Resource("Resource"))
  33. assert p1.resource == "Resource"
  34. assert p1.scope == ""
  35. assert repr(p1) == "Resource"
  36. assert str(p1) == "Resource"
  37. p2 = UMAPermission(permission=Scope("Scope"))
  38. assert p2.resource == ""
  39. assert p2.scope == "Scope"
  40. assert repr(p2) == "#Scope"
  41. assert str(p2) == "#Scope"
  42. assert {p1, p1} != {p2, p2}
  43. def test_resource_with_scope_obj():
  44. """Test resource with scope."""
  45. r = Resource("Resource1")
  46. s = Scope("Scope1")
  47. assert r(s) == "Resource1#Scope1"
  48. def test_scope_with_resource_obj():
  49. """Test scope with resource."""
  50. r = Resource("Resource1")
  51. s = Scope("Scope1")
  52. assert s(r) == "Resource1#Scope1"
  53. def test_resource_scope_str():
  54. """Test resource scope as string."""
  55. r = Resource("Resource1")
  56. s = "Scope1"
  57. assert r(scope=s) == "Resource1#Scope1"
  58. def test_scope_resource_str():
  59. """Test scope resource as string."""
  60. r = "Resource1"
  61. s = Scope("Scope1")
  62. assert s(resource=r) == "Resource1#Scope1"
  63. def test_resource_scope_list():
  64. """Test resource scope as list."""
  65. r = Resource("Resource1")
  66. s = ["Scope1"]
  67. with pytest.raises(PermissionDefinitionError) as err:
  68. r(s)
  69. assert err.match(re.escape("can't determine if '['Scope1']' is a resource or scope"))
  70. def test_build_permission_none():
  71. """Test build permission param with None."""
  72. assert build_permission_param(None) == set()
  73. def test_build_permission_empty_str():
  74. """Test build permission param with an empty string."""
  75. assert build_permission_param("") == set()
  76. def test_build_permission_empty_list():
  77. """Test build permission param with an empty list."""
  78. assert build_permission_param([]) == set()
  79. def test_build_permission_empty_tuple():
  80. """Test build permission param with an empty tuple."""
  81. assert build_permission_param(()) == set()
  82. def test_build_permission_empty_set():
  83. """Test build permission param with an empty set."""
  84. assert build_permission_param(set()) == set()
  85. def test_build_permission_empty_dict():
  86. """Test build permission param with an empty dict."""
  87. assert build_permission_param({}) == set()
  88. def test_build_permission_str():
  89. """Test build permission param as string."""
  90. assert build_permission_param("resource1") == {"resource1"}
  91. def test_build_permission_list_str():
  92. """Test build permission param with list of strings."""
  93. assert build_permission_param(["res1#scope1", "res1#scope2"]) == {"res1#scope1", "res1#scope2"}
  94. def test_build_permission_tuple_str():
  95. """Test build permission param with tuple of strings."""
  96. assert build_permission_param(("res1#scope1", "res1#scope2")) == {"res1#scope1", "res1#scope2"}
  97. def test_build_permission_set_str():
  98. """Test build permission param with set of strings."""
  99. assert build_permission_param({"res1#scope1", "res1#scope2"}) == {"res1#scope1", "res1#scope2"}
  100. def test_build_permission_tuple_dict_str_str():
  101. """Test build permission param with dictionary."""
  102. assert build_permission_param({"res1": "scope1"}) == {"res1#scope1"}
  103. def test_build_permission_tuple_dict_str_list_str():
  104. """Test build permission param with dictionary of list."""
  105. assert build_permission_param({"res1": ["scope1", "scope2"]}) == {"res1#scope1", "res1#scope2"}
  106. def test_build_permission_tuple_dict_str_list_str2():
  107. """Test build permission param with mutliple-keyed dictionary."""
  108. assert build_permission_param(
  109. {"res1": ["scope1", "scope2"], "res2": ["scope2", "scope3"]}
  110. ) == {"res1#scope1", "res1#scope2", "res2#scope2", "res2#scope3"}
  111. def test_build_permission_uma():
  112. """Test build permission param with UMA."""
  113. assert build_permission_param(Resource("res1")(Scope("scope1"))) == {"res1#scope1"}
  114. def test_build_permission_uma_list():
  115. """Test build permission param with list of UMAs."""
  116. assert build_permission_param(
  117. [Resource("res1")(Scope("scope1")), Resource("res1")(Scope("scope2"))]
  118. ) == {"res1#scope1", "res1#scope2"}
  119. def test_build_permission_misbuilt_dict_str_list_list_str():
  120. """Test bad build of permission param from dictionary."""
  121. with pytest.raises(KeycloakPermissionFormatError) as err:
  122. build_permission_param({"res1": [["scope1", "scope2"]]})
  123. assert err.match(re.escape("misbuilt permission {'res1': [['scope1', 'scope2']]}"))
  124. def test_build_permission_misbuilt_list_list_str():
  125. """Test bad build of permission param from list."""
  126. with pytest.raises(KeycloakPermissionFormatError) as err:
  127. print(build_permission_param([["scope1", "scope2"]]))
  128. assert err.match(re.escape("misbuilt permission [['scope1', 'scope2']]"))
  129. def test_build_permission_misbuilt_list_set_str():
  130. """Test bad build of permission param from set."""
  131. with pytest.raises(KeycloakPermissionFormatError) as err:
  132. build_permission_param([{"scope1", "scope2"}])
  133. assert err.match("misbuilt permission.*")
  134. def test_build_permission_misbuilt_set_set_str():
  135. """Test bad build of permission param from list of set."""
  136. with pytest.raises(KeycloakPermissionFormatError) as err:
  137. build_permission_param([{"scope1"}])
  138. assert err.match(re.escape("misbuilt permission [{'scope1'}]"))
  139. def test_build_permission_misbuilt_dict_non_iterable():
  140. """Test bad build of permission param from non-iterable."""
  141. with pytest.raises(KeycloakPermissionFormatError) as err:
  142. build_permission_param({"res1": 5})
  143. assert err.match(re.escape("misbuilt permission {'res1': 5}"))
  144. def test_auth_status_bool():
  145. """Test bool method of AuthStatus."""
  146. assert not bool(AuthStatus(is_logged_in=True, is_authorized=False, missing_permissions=""))
  147. assert bool(AuthStatus(is_logged_in=True, is_authorized=True, missing_permissions=""))
  148. def test_build_permission_without_scopes():
  149. """Test build permission param with scopes."""
  150. assert build_permission_param(permissions={"Resource": None}) == {"Resource"}