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.

211 lines
7.2 KiB

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