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.

144 lines
4.5 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. from keycloak.urls_patterns import URL_ADMIN_USERS_COUNT, URL_ADMIN_USER
  18. from .keycloak_openid import KeycloakOpenID
  19. from .exceptions import raise_error_from_response, KeycloakGetError, KeycloakSecretNotFound, \
  20. KeycloakRPTNotFound, KeycloakAuthorizationConfigError, KeycloakInvalidTokenError
  21. from .urls_patterns import (
  22. URL_ADMIN_USERS,
  23. )
  24. from .connection import ConnectionManager
  25. from jose import jwt
  26. import json
  27. class KeycloakAdmin:
  28. def __init__(self, server_url, username, password, realm_name='master', client_id='admin-cli'):
  29. self._username = username
  30. self._password = password
  31. self._client_id = client_id
  32. self._realm_name = realm_name
  33. # Get token Admin
  34. keycloak_openid = KeycloakOpenID(server_url, client_id, realm_name)
  35. self._token = keycloak_openid.token(username, password)
  36. self._connection = ConnectionManager(base_url=server_url,
  37. headers={'Authorization': 'Bearer ' + self.token.get('access_token'),
  38. 'Content-Type': 'application/json'},
  39. timeout=60)
  40. @property
  41. def realm_name(self):
  42. return self._realm_name
  43. @realm_name.setter
  44. def realm_name(self, value):
  45. self._realm_name = value
  46. @property
  47. def connection(self):
  48. return self._connection
  49. @connection.setter
  50. def connection(self, value):
  51. self._connection = value
  52. @property
  53. def client_id(self):
  54. return self._client_id
  55. @client_id.setter
  56. def client_id(self, value):
  57. self._client_id = value
  58. @property
  59. def username(self):
  60. return self._username
  61. @username.setter
  62. def username(self, value):
  63. self._username = value
  64. @property
  65. def password(self):
  66. return self._password
  67. @password.setter
  68. def password(self, value):
  69. self._password = value
  70. @property
  71. def token(self):
  72. return self._token
  73. @token.setter
  74. def token(self, value):
  75. self._token = value
  76. def list_users(self, query=None):
  77. """
  78. Get users Returns a list of users, filtered according to query parameters
  79. :return: users list
  80. """
  81. params_path = {"realm-name": self.realm_name}
  82. data_raw = self.connection.raw_get(URL_ADMIN_USERS.format(**params_path), **query)
  83. return raise_error_from_response(data_raw, KeycloakGetError)
  84. def create_user(self, payload):
  85. """
  86. Create a new user Username must be unique
  87. UserRepresentation
  88. http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_userrepresentation
  89. :return: UserRepresentation
  90. """
  91. params_path = {"realm-name": self.realm_name}
  92. data_raw = self.connection.raw_post(URL_ADMIN_USERS.format(**params_path),
  93. data=json.dumps(payload))
  94. return raise_error_from_response(data_raw, KeycloakGetError, expected_code=201)
  95. def count_users(self):
  96. """
  97. User counter
  98. :return: counter
  99. """
  100. params_path = {"realm-name": self.realm_name}
  101. data_raw = self.connection.raw_get(URL_ADMIN_USERS_COUNT.format(**params_path))
  102. return raise_error_from_response(data_raw, KeycloakGetError)
  103. def get_user(self, user_id):
  104. """
  105. Get representation of the user
  106. UserRepresentation
  107. http://www.keycloak.org/docs-api/3.3/rest-api/index.html#_userrepresentation
  108. :return: UserRepresentation
  109. """
  110. params_path = {"realm-name": self.realm_name, "id": user_id}
  111. data_raw = self.connection.raw_get(URL_ADMIN_USER.format(**params_path))
  112. return raise_error_from_response(data_raw, KeycloakGetError)