Browse Source

Added policies, permissions, roles, scopes and resources.

hotfix/merge
Marcos Pereira 7 years ago
parent
commit
9cf3c37676
  1. 34
      keycloak/__init__.py
  2. 9
      keycloak/authorization/__init__.py
  3. 16
      keycloak/authorization/permission.py
  4. 23
      keycloak/authorization/policy.py
  5. 12
      keycloak/authorization/role.py
  6. 20
      keycloak/exceptions.py

34
keycloak/__init__.py

@ -15,7 +15,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from keycloak.authorization import Authorization
from keycloak.exceptions import KeycloakAuthorizationConfigError
from keycloak.exceptions import KeycloakAuthorizationConfigError, KeycloakInvalidTokenError
from .exceptions import raise_error_from_response, KeycloakGetError, KeycloakSecretNotFound, \
KeycloakRPTNotFound
from .urls_patterns import (
@ -98,6 +98,9 @@ class Keycloak:
return payload
def _build_name_role(self, role):
return self.client_id + "/" + role
def well_know(self):
""" The most important endpoint to understand is the well-known configuration
endpoint. It lists endpoints and other configuration options relevant to
@ -269,14 +272,39 @@ class Keycloak:
self.authorization.load_config(authorization_json)
authorization_file.close()
def get_permissions(self):
def get_permissions(self, token):
"""
Get permission by user token
:param token: user token
:return: permissions list
"""
if not self.authorization.policies:
raise KeycloakAuthorizationConfigError(
"Keycloak settings not found. Load Authorization Keycloak settings."
)
return
token_info = self.instropect(token)
if not token_info['active']:
raise KeycloakInvalidTokenError(
"Token expired or invalid."
)
user_resources = token_info['resource_access'].get(self.client_id)
if not user_resources:
return None
permissions = []
for policy_name, policy in self.authorization.policies.items():
for role in user_resources['roles']:
if self._build_name_role(role) in policy.roles:
permissions += policy.permissions
return list(set(permissions))

9
keycloak/authorization/__init__.py

@ -24,6 +24,12 @@ from keycloak.authorization.role import Role
class Authorization:
"""
Keycloak Authorization (policies, roles, scopes and resources).
https://keycloak.gitbooks.io/documentation/authorization_services/index.html
"""
def __init__(self):
self._policies = {}
@ -38,8 +44,9 @@ class Authorization:
def load_config(self, data):
"""
Load policies, roles and permissions (scope/resources).
:param data:
:param data: keycloak authorization data (dict)
:return:
"""
for pol in data['policies']:

16
keycloak/authorization/permission.py

@ -17,6 +17,22 @@
class Permission:
"""
Consider this simple and very common permission:
A permission associates the object being protected with the policies that must be evaluated to determine whether access is granted.
X CAN DO Y ON RESOURCE Z
where
X represents one or more users, roles, or groups, or a combination of them. You can
also use claims and context here.
Y represents an action to be performed, for example, write, view, and so on.
Z represents a protected resource, for example, "/accounts".
https://keycloak.gitbooks.io/documentation/authorization_services/topics/permission/overview.html
"""
def __init__(self, name, type, logic, decision_strategy):
self._name = name

23
keycloak/authorization/policy.py

@ -19,6 +19,17 @@ from keycloak.exceptions import KeycloakAuthorizationConfigError
class Policy:
"""
A policy defines the conditions that must be satisfied to grant access to an object.
Unlike permissions, you do not specify the object being protected but rather the conditions
that must be satisfied for access to a given object (for example, resource, scope, or both).
Policies are strongly related to the different access control mechanisms (ACMs) that you can use to
protect your resources. With policies, you can implement strategies for attribute-based access control
(ABAC), role-based access control (RBAC), context-based access control, or any combination of these.
https://keycloak.gitbooks.io/documentation/authorization_services/topics/policy/overview.html
"""
def __init__(self, name, type, logic, decision_strategy):
self._name = name
@ -75,10 +86,22 @@ class Policy:
return self._permissions
def add_role(self, role):
"""
Add keycloak role in policy.
:param role: keycloak role.
:return:
"""
if self.type != 'role':
raise KeycloakAuthorizationConfigError(
"Can't add role. Policy type is different of role")
self._roles.append(role)
def add_permission(self, permission):
"""
Add keycloak permission in policy.
:param permission: keycloak permission.
:return:
"""
self._permissions.append(permission)

12
keycloak/authorization/role.py

@ -17,6 +17,13 @@
class Role:
"""
Roles identify a type or category of user. Admin, user,
manager, and employee are all typical roles that may exist in an organization.
https://keycloak.gitbooks.io/documentation/server_admin/topics/roles.html
"""
def __init__(self, name, required=False):
self.name = name
@ -25,3 +32,8 @@ class Role:
@property
def get_name(self):
return self.name
def __eq__(self, other):
if isinstance(other, str):
return self.name == other
return NotImplemented

20
keycloak/exceptions.py

@ -48,26 +48,10 @@ class KeycloakOperationError(KeycloakError):
pass
class KeycloakListError(KeycloakOperationError):
pass
class KeycloakGetError(KeycloakOperationError):
pass
class KeycloakCreateError(KeycloakOperationError):
pass
class KeycloakUpdateError(KeycloakOperationError):
pass
class KeycloakDeleteError(KeycloakOperationError):
pass
class KeycloakSecretNotFound(KeycloakOperationError):
pass
@ -80,6 +64,10 @@ class KeycloakAuthorizationConfigError(KeycloakOperationError):
pass
class KeycloakInvalidTokenError(KeycloakOperationError):
pass
def raise_error_from_response(response, error, expected_code=200):
if expected_code == response.status_code:

Loading…
Cancel
Save