diff options
author | RHE <rebirthmonkey@gmail.com> | 2017-11-24 13:54:26 +0100 |
---|---|---|
committer | RHE <rebirthmonkey@gmail.com> | 2017-11-24 13:54:26 +0100 |
commit | 920a49cfa055733d575282973e23558c33087a4a (patch) | |
tree | d371dab34efa5028600dad2e7ca58063626e7ba4 /keystone-moon/keystone/contrib | |
parent | ef3eefca70d8abb4a00dafb9419ad32738e934b2 (diff) |
remove keystone-moon
Change-Id: I80d7c9b669f19d5f6607e162de8e0e55c2f80fdd
Signed-off-by: RHE <rebirthmonkey@gmail.com>
Diffstat (limited to 'keystone-moon/keystone/contrib')
114 files changed, 0 insertions, 13965 deletions
diff --git a/keystone-moon/keystone/contrib/__init__.py b/keystone-moon/keystone/contrib/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/admin_crud/__init__.py b/keystone-moon/keystone/contrib/admin_crud/__init__.py deleted file mode 100644 index d6020920..00000000 --- a/keystone-moon/keystone/contrib/admin_crud/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.contrib.admin_crud.core import * # noqa diff --git a/keystone-moon/keystone/contrib/admin_crud/core.py b/keystone-moon/keystone/contrib/admin_crud/core.py deleted file mode 100644 index 739cc0ff..00000000 --- a/keystone-moon/keystone/contrib/admin_crud/core.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class CrudExtension(wsgi.Middleware): - def __init__(self, application): - super(CrudExtension, self).__init__(application) - msg = _("Remove admin_crud_extension from the paste pipeline, the " - "admin_crud extension is now always available. Update" - "the [pipeline:admin_api] section in keystone-paste.ini " - "accordingly, as it will be removed in the O release.") - versionutils.report_deprecated_feature(LOG, msg) diff --git a/keystone-moon/keystone/contrib/ec2/__init__.py b/keystone-moon/keystone/contrib/ec2/__init__.py deleted file mode 100644 index 88622e53..00000000 --- a/keystone-moon/keystone/contrib/ec2/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.contrib.ec2 import controllers # noqa -from keystone.contrib.ec2.core import * # noqa -from keystone.contrib.ec2.routers import Ec2Extension # noqa -from keystone.contrib.ec2.routers import Ec2ExtensionV3 # noqa diff --git a/keystone-moon/keystone/contrib/ec2/controllers.py b/keystone-moon/keystone/contrib/ec2/controllers.py deleted file mode 100644 index c0f6067e..00000000 --- a/keystone-moon/keystone/contrib/ec2/controllers.py +++ /dev/null @@ -1,435 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into the EC2 Credentials service. - -This service allows the creation of access/secret credentials used for -the ec2 interop layer of OpenStack. - -A user can create as many access/secret pairs, each of which is mapped to a -specific project. This is required because OpenStack supports a user -belonging to multiple projects, whereas the signatures created on ec2-style -requests don't allow specification of which project the user wishes to act -upon. - -To complete the cycle, we provide a method that OpenStack services can -use to validate a signature and get a corresponding OpenStack token. This -token allows method calls to other services within the context the -access/secret was created. As an example, Nova requests Keystone to validate -the signature of a request, receives a token, and then makes a request to -Glance to list images needed to perform the requested task. - -""" - -import abc -import sys -import uuid - -from keystoneclient.contrib.ec2 import utils as ec2_utils -from oslo_serialization import jsonutils -import six - -from keystone.common import controller -from keystone.common import dependency -from keystone.common import utils -from keystone.common import wsgi -from keystone import exception -from keystone.i18n import _ - -CRED_TYPE_EC2 = 'ec2' - - -@dependency.requires('assignment_api', 'catalog_api', 'credential_api', - 'identity_api', 'resource_api', 'role_api', - 'token_provider_api') -@six.add_metaclass(abc.ABCMeta) -class Ec2ControllerCommon(object): - def check_signature(self, creds_ref, credentials): - signer = ec2_utils.Ec2Signer(creds_ref['secret']) - signature = signer.generate(credentials) - # NOTE(davechen): credentials.get('signature') is not guaranteed to - # exist, we need check it explicitly. - if credentials.get('signature'): - if utils.auth_str_equal(credentials['signature'], signature): - return True - # NOTE(vish): Some client libraries don't use the port when signing - # requests, so try again without port. - elif ':' in credentials['host']: - hostname, _port = credentials['host'].split(':') - credentials['host'] = hostname - # NOTE(davechen): we need reinitialize 'signer' to avoid - # contaminated status of signature, this is similar with - # other programming language libraries, JAVA for example. - signer = ec2_utils.Ec2Signer(creds_ref['secret']) - signature = signer.generate(credentials) - if utils.auth_str_equal(credentials['signature'], - signature): - return True - raise exception.Unauthorized( - message=_('Invalid EC2 signature.')) - else: - raise exception.Unauthorized( - message=_('EC2 signature not supplied.')) - # Raise the exception when credentials.get('signature') is None - else: - raise exception.Unauthorized( - message=_('EC2 signature not supplied.')) - - @abc.abstractmethod - def authenticate(self, context, credentials=None, ec2Credentials=None): - """Validate a signed EC2 request and provide a token. - - Other services (such as Nova) use this **admin** call to determine - if a request they signed received is from a valid user. - - If it is a valid signature, an OpenStack token that maps - to the user/tenant is returned to the caller, along with - all the other details returned from a normal token validation - call. - - The returned token is useful for making calls to other - OpenStack services within the context of the request. - - :param context: standard context - :param credentials: dict of ec2 signature - :param ec2Credentials: DEPRECATED dict of ec2 signature - :returns: token: OpenStack token equivalent to access key along - with the corresponding service catalog and roles - """ - raise exception.NotImplemented() - - def _authenticate(self, credentials=None, ec2credentials=None): - """Common code shared between the V2 and V3 authenticate methods. - - :returns: user_ref, tenant_ref, metadata_ref, roles_ref, catalog_ref - """ - # FIXME(ja): validate that a service token was used! - - # NOTE(termie): backwards compat hack - if not credentials and ec2credentials: - credentials = ec2credentials - - if 'access' not in credentials: - raise exception.Unauthorized( - message=_('EC2 signature not supplied.')) - - creds_ref = self._get_credentials(credentials['access']) - self.check_signature(creds_ref, credentials) - - # TODO(termie): don't create new tokens every time - # TODO(termie): this is copied from TokenController.authenticate - tenant_ref = self.resource_api.get_project(creds_ref['tenant_id']) - user_ref = self.identity_api.get_user(creds_ref['user_id']) - metadata_ref = {} - metadata_ref['roles'] = ( - self.assignment_api.get_roles_for_user_and_project( - user_ref['id'], tenant_ref['id'])) - - trust_id = creds_ref.get('trust_id') - if trust_id: - metadata_ref['trust_id'] = trust_id - metadata_ref['trustee_user_id'] = user_ref['id'] - - # Validate that the auth info is valid and nothing is disabled - try: - self.identity_api.assert_user_enabled( - user_id=user_ref['id'], user=user_ref) - self.resource_api.assert_domain_enabled( - domain_id=user_ref['domain_id']) - self.resource_api.assert_project_enabled( - project_id=tenant_ref['id'], project=tenant_ref) - except AssertionError as e: - six.reraise(exception.Unauthorized, exception.Unauthorized(e), - sys.exc_info()[2]) - - roles = metadata_ref.get('roles', []) - if not roles: - raise exception.Unauthorized( - message=_('User not valid for tenant.')) - roles_ref = [self.role_api.get_role(role_id) for role_id in roles] - - catalog_ref = self.catalog_api.get_catalog( - user_ref['id'], tenant_ref['id']) - - return user_ref, tenant_ref, metadata_ref, roles_ref, catalog_ref - - def create_credential(self, context, user_id, tenant_id): - """Create a secret/access pair for use with ec2 style auth. - - Generates a new set of credentials that map the user/tenant - pair. - - :param context: standard context - :param user_id: id of user - :param tenant_id: id of tenant - :returns: credential: dict of ec2 credential - """ - self.identity_api.get_user(user_id) - self.resource_api.get_project(tenant_id) - trust_id = self._get_trust_id_for_request(context) - blob = {'access': uuid.uuid4().hex, - 'secret': uuid.uuid4().hex, - 'trust_id': trust_id} - credential_id = utils.hash_access_key(blob['access']) - cred_ref = {'user_id': user_id, - 'project_id': tenant_id, - 'blob': jsonutils.dumps(blob), - 'id': credential_id, - 'type': CRED_TYPE_EC2} - self.credential_api.create_credential(credential_id, cred_ref) - return {'credential': self._convert_v3_to_ec2_credential(cred_ref)} - - def get_credentials(self, user_id): - """List all credentials for a user. - - :param user_id: id of user - :returns: credentials: list of ec2 credential dicts - """ - self.identity_api.get_user(user_id) - credential_refs = self.credential_api.list_credentials_for_user( - user_id, type=CRED_TYPE_EC2) - return {'credentials': - [self._convert_v3_to_ec2_credential(credential) - for credential in credential_refs]} - - def get_credential(self, user_id, credential_id): - """Retrieve a user's access/secret pair by the access key. - - Grab the full access/secret pair for a given access key. - - :param user_id: id of user - :param credential_id: access key for credentials - :returns: credential: dict of ec2 credential - """ - self.identity_api.get_user(user_id) - return {'credential': self._get_credentials(credential_id)} - - def delete_credential(self, user_id, credential_id): - """Delete a user's access/secret pair. - - Used to revoke a user's access/secret pair - - :param user_id: id of user - :param credential_id: access key for credentials - :returns: bool: success - """ - self.identity_api.get_user(user_id) - self._get_credentials(credential_id) - ec2_credential_id = utils.hash_access_key(credential_id) - return self.credential_api.delete_credential(ec2_credential_id) - - @staticmethod - def _convert_v3_to_ec2_credential(credential): - # Prior to bug #1259584 fix, blob was stored unserialized - # but it should be stored as a json string for compatibility - # with the v3 credentials API. Fall back to the old behavior - # for backwards compatibility with existing DB contents - try: - blob = jsonutils.loads(credential['blob']) - except TypeError: - blob = credential['blob'] - return {'user_id': credential.get('user_id'), - 'tenant_id': credential.get('project_id'), - 'access': blob.get('access'), - 'secret': blob.get('secret'), - 'trust_id': blob.get('trust_id')} - - def _get_credentials(self, credential_id): - """Return credentials from an ID. - - :param credential_id: id of credential - :raises keystone.exception.Unauthorized: when credential id is invalid - or when the credential type is not ec2 - :returns: credential: dict of ec2 credential. - """ - ec2_credential_id = utils.hash_access_key(credential_id) - cred = self.credential_api.get_credential(ec2_credential_id) - if not cred or cred['type'] != CRED_TYPE_EC2: - raise exception.Unauthorized( - message=_('EC2 access key not found.')) - return self._convert_v3_to_ec2_credential(cred) - - -@dependency.requires('policy_api', 'token_provider_api') -class Ec2Controller(Ec2ControllerCommon, controller.V2Controller): - - @controller.v2_ec2_deprecated - def authenticate(self, context, credentials=None, ec2Credentials=None): - (user_ref, tenant_ref, metadata_ref, roles_ref, - catalog_ref) = self._authenticate(credentials=credentials, - ec2credentials=ec2Credentials) - - # NOTE(morganfainberg): Make sure the data is in correct form since it - # might be consumed external to Keystone and this is a v2.0 controller. - # The token provider does not explicitly care about user_ref version - # in this case, but the data is stored in the token itself and should - # match the version - user_ref = self.v3_to_v2_user(user_ref) - auth_token_data = dict(user=user_ref, - tenant=tenant_ref, - metadata=metadata_ref, - id='placeholder') - (token_id, token_data) = self.token_provider_api.issue_v2_token( - auth_token_data, roles_ref, catalog_ref) - return token_data - - @controller.v2_ec2_deprecated - def get_credential(self, context, user_id, credential_id): - if not self._is_admin(context): - self._assert_identity(context, user_id) - return super(Ec2Controller, self).get_credential(user_id, - credential_id) - - @controller.v2_ec2_deprecated - def get_credentials(self, context, user_id): - if not self._is_admin(context): - self._assert_identity(context, user_id) - return super(Ec2Controller, self).get_credentials(user_id) - - @controller.v2_ec2_deprecated - def create_credential(self, context, user_id, tenant_id): - if not self._is_admin(context): - self._assert_identity(context, user_id) - return super(Ec2Controller, self).create_credential(context, user_id, - tenant_id) - - @controller.v2_ec2_deprecated - def delete_credential(self, context, user_id, credential_id): - if not self._is_admin(context): - self._assert_identity(context, user_id) - self._assert_owner(user_id, credential_id) - return super(Ec2Controller, self).delete_credential(user_id, - credential_id) - - def _assert_identity(self, context, user_id): - """Check that the provided token belongs to the user. - - :param context: standard context - :param user_id: id of user - :raises keystone.exception.Forbidden: when token is invalid - - """ - token_ref = utils.get_token_ref(context) - - if token_ref.user_id != user_id: - raise exception.Forbidden(_('Token belongs to another user')) - - def _is_admin(self, context): - """Wrap admin assertion error return statement. - - :param context: standard context - :returns: bool: success - - """ - try: - # NOTE(morganfainberg): policy_api is required for assert_admin - # to properly perform policy enforcement. - self.assert_admin(context) - return True - except (exception.Forbidden, exception.Unauthorized): - return False - - def _assert_owner(self, user_id, credential_id): - """Ensure the provided user owns the credential. - - :param user_id: expected credential owner - :param credential_id: id of credential object - :raises keystone.exception.Forbidden: on failure - - """ - ec2_credential_id = utils.hash_access_key(credential_id) - cred_ref = self.credential_api.get_credential(ec2_credential_id) - if user_id != cred_ref['user_id']: - raise exception.Forbidden(_('Credential belongs to another user')) - - -@dependency.requires('policy_api', 'token_provider_api') -class Ec2ControllerV3(Ec2ControllerCommon, controller.V3Controller): - - collection_name = 'credentials' - member_name = 'credential' - - def __init__(self): - super(Ec2ControllerV3, self).__init__() - - def _check_credential_owner_and_user_id_match(self, context, prep_info, - user_id, credential_id): - # NOTE(morganfainberg): this method needs to capture the arguments of - # the method that is decorated with @controller.protected() (with - # exception of the first argument ('context') since the protected - # method passes in *args, **kwargs. In this case, it is easier to see - # the expected input if the argspec is `user_id` and `credential_id` - # explicitly (matching the :class:`.ec2_delete_credential()` method - # below). - ref = {} - credential_id = utils.hash_access_key(credential_id) - ref['credential'] = self.credential_api.get_credential(credential_id) - # NOTE(morganfainberg): policy_api is required for this - # check_protection to properly be able to perform policy enforcement. - self.check_protection(context, prep_info, ref) - - def authenticate(self, context, credentials=None, ec2Credentials=None): - (user_ref, project_ref, metadata_ref, roles_ref, - catalog_ref) = self._authenticate(credentials=credentials, - ec2credentials=ec2Credentials) - - method_names = ['ec2credential'] - - token_id, token_data = self.token_provider_api.issue_v3_token( - user_ref['id'], method_names, project_id=project_ref['id'], - metadata_ref=metadata_ref) - return render_token_data_response(token_id, token_data) - - @controller.protected(callback=_check_credential_owner_and_user_id_match) - def ec2_get_credential(self, context, user_id, credential_id): - ref = super(Ec2ControllerV3, self).get_credential(user_id, - credential_id) - return Ec2ControllerV3.wrap_member(context, ref['credential']) - - @controller.protected() - def ec2_list_credentials(self, context, user_id): - refs = super(Ec2ControllerV3, self).get_credentials(user_id) - return Ec2ControllerV3.wrap_collection(context, refs['credentials']) - - @controller.protected() - def ec2_create_credential(self, context, user_id, tenant_id): - ref = super(Ec2ControllerV3, self).create_credential(context, user_id, - tenant_id) - return Ec2ControllerV3.wrap_member(context, ref['credential']) - - @controller.protected(callback=_check_credential_owner_and_user_id_match) - def ec2_delete_credential(self, context, user_id, credential_id): - return super(Ec2ControllerV3, self).delete_credential(user_id, - credential_id) - - @classmethod - def _add_self_referential_link(cls, context, ref): - path = '/users/%(user_id)s/credentials/OS-EC2/%(credential_id)s' - url = cls.base_url(context, path) % { - 'user_id': ref['user_id'], - 'credential_id': ref['access']} - ref.setdefault('links', {}) - ref['links']['self'] = url - - -def render_token_data_response(token_id, token_data): - """Render token data HTTP response. - - Stash token ID into the X-Subject-Token header. - - """ - headers = [('X-Subject-Token', token_id)] - - return wsgi.render_response(body=token_data, - status=(200, 'OK'), headers=headers) diff --git a/keystone-moon/keystone/contrib/ec2/core.py b/keystone-moon/keystone/contrib/ec2/core.py deleted file mode 100644 index 7bba8cab..00000000 --- a/keystone-moon/keystone/contrib/ec2/core.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.common import extension - - -EXTENSION_DATA = { - 'name': 'OpenStack EC2 API', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-EC2/v1.0', - 'alias': 'OS-EC2', - 'updated': '2013-07-07T12:00:0-00:00', - 'description': 'OpenStack EC2 Credentials backend.', - 'links': [ - { - 'rel': 'describedby', - 'type': 'text/html', - 'href': 'http://developer.openstack.org/' - 'api-ref-identity-v2-ext.html', - } - ]} -extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) -extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) diff --git a/keystone-moon/keystone/contrib/ec2/routers.py b/keystone-moon/keystone/contrib/ec2/routers.py deleted file mode 100644 index 97c68cf7..00000000 --- a/keystone-moon/keystone/contrib/ec2/routers.py +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import functools - -from keystone.common import json_home -from keystone.common import wsgi -from keystone.contrib.ec2 import controllers - - -build_resource_relation = functools.partial( - json_home.build_v3_extension_resource_relation, extension_name='OS-EC2', - extension_version='1.0') - - -class Ec2Extension(wsgi.ExtensionRouter): - def add_routes(self, mapper): - ec2_controller = controllers.Ec2Controller() - # validation - mapper.connect( - '/ec2tokens', - controller=ec2_controller, - action='authenticate', - conditions=dict(method=['POST'])) - - # crud - mapper.connect( - '/users/{user_id}/credentials/OS-EC2', - controller=ec2_controller, - action='create_credential', - conditions=dict(method=['POST'])) - mapper.connect( - '/users/{user_id}/credentials/OS-EC2', - controller=ec2_controller, - action='get_credentials', - conditions=dict(method=['GET'])) - mapper.connect( - '/users/{user_id}/credentials/OS-EC2/{credential_id}', - controller=ec2_controller, - action='get_credential', - conditions=dict(method=['GET'])) - mapper.connect( - '/users/{user_id}/credentials/OS-EC2/{credential_id}', - controller=ec2_controller, - action='delete_credential', - conditions=dict(method=['DELETE'])) - - -class Ec2ExtensionV3(wsgi.V3ExtensionRouter): - - def add_routes(self, mapper): - ec2_controller = controllers.Ec2ControllerV3() - # validation - self._add_resource( - mapper, ec2_controller, - path='/ec2tokens', - post_action='authenticate', - rel=build_resource_relation(resource_name='ec2tokens')) - - # crud - self._add_resource( - mapper, ec2_controller, - path='/users/{user_id}/credentials/OS-EC2', - get_action='ec2_list_credentials', - post_action='ec2_create_credential', - rel=build_resource_relation(resource_name='user_credentials'), - path_vars={ - 'user_id': json_home.Parameters.USER_ID, - }) - self._add_resource( - mapper, ec2_controller, - path='/users/{user_id}/credentials/OS-EC2/{credential_id}', - get_action='ec2_get_credential', - delete_action='ec2_delete_credential', - rel=build_resource_relation(resource_name='user_credential'), - path_vars={ - 'credential_id': - json_home.build_v3_parameter_relation('credential_id'), - 'user_id': json_home.Parameters.USER_ID, - }) diff --git a/keystone-moon/keystone/contrib/endpoint_filter/__init__.py b/keystone-moon/keystone/contrib/endpoint_filter/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_filter/backends/__init__.py b/keystone-moon/keystone/contrib/endpoint_filter/backends/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/backends/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_filter/backends/catalog_sql.py b/keystone-moon/keystone/contrib/endpoint_filter/backends/catalog_sql.py deleted file mode 100644 index ad39d045..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/backends/catalog_sql.py +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg - -from keystone.catalog.backends import sql -from keystone.catalog import core as catalog_core -from keystone.common import dependency - - -CONF = cfg.CONF - - -@dependency.requires('catalog_api') -class EndpointFilterCatalog(sql.Catalog): - def get_v3_catalog(self, user_id, project_id): - substitutions = dict(CONF.items()) - substitutions.update({ - 'tenant_id': project_id, - 'project_id': project_id, - 'user_id': user_id, - }) - - services = {} - - dict_of_endpoint_refs = (self.catalog_api. - list_endpoints_for_project(project_id)) - - if (not dict_of_endpoint_refs and - CONF.endpoint_filter.return_all_endpoints_if_no_filter): - return super(EndpointFilterCatalog, self).get_v3_catalog( - user_id, project_id) - - for endpoint_id, endpoint in dict_of_endpoint_refs.items(): - if not endpoint['enabled']: - # Skip disabled endpoints. - continue - service_id = endpoint['service_id'] - services.setdefault( - service_id, - self.get_service(service_id)) - service = services[service_id] - del endpoint['service_id'] - del endpoint['enabled'] - del endpoint['legacy_endpoint_id'] - # Include deprecated region for backwards compatibility - endpoint['region'] = endpoint['region_id'] - endpoint['url'] = catalog_core.format_url( - endpoint['url'], substitutions) - # populate filtered endpoints - if 'endpoints' in services[service_id]: - service['endpoints'].append(endpoint) - else: - service['endpoints'] = [endpoint] - - # format catalog - catalog = [] - for service_id, service in services.items(): - formatted_service = {} - formatted_service['id'] = service['id'] - formatted_service['type'] = service['type'] - formatted_service['name'] = service['name'] - formatted_service['endpoints'] = service['endpoints'] - catalog.append(formatted_service) - - return catalog diff --git a/keystone-moon/keystone/contrib/endpoint_filter/backends/sql.py b/keystone-moon/keystone/contrib/endpoint_filter/backends/sql.py deleted file mode 100644 index 484934bb..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/backends/sql.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import versionutils - -from keystone.catalog.backends import sql - -_OLD = 'keystone.contrib.endpoint_filter.backends.sql.EndpointFilter' -_NEW = 'sql' - - -class EndpointFilter(sql.Catalog): - @versionutils.deprecated( - as_of=versionutils.deprecated.MITAKA, - in_favor_of=_NEW, - what=_OLD, - remove_in=2) - def __init__(self, *args, **kwargs): - super(EndpointFilter, self).__init__(*args, **kwargs) diff --git a/keystone-moon/keystone/contrib/endpoint_filter/controllers.py b/keystone-moon/keystone/contrib/endpoint_filter/controllers.py deleted file mode 100644 index eb627c6b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/controllers.py +++ /dev/null @@ -1,300 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import six - -from keystone.catalog import controllers as catalog_controllers -from keystone.common import controller -from keystone.common import dependency -from keystone.common import validation -from keystone.contrib.endpoint_filter import schema -from keystone import exception -from keystone import notifications -from keystone import resource - - -@dependency.requires('catalog_api', 'endpoint_filter_api', 'resource_api') -class _ControllerBase(controller.V3Controller): - """Base behaviors for endpoint filter controllers.""" - - def _get_endpoint_groups_for_project(self, project_id): - # recover the project endpoint group memberships and for each - # membership recover the endpoint group - self.resource_api.get_project(project_id) - try: - refs = self.endpoint_filter_api.list_endpoint_groups_for_project( - project_id) - endpoint_groups = [self.endpoint_filter_api.get_endpoint_group( - ref['endpoint_group_id']) for ref in refs] - return endpoint_groups - except exception.EndpointGroupNotFound: - return [] - - def _get_endpoints_filtered_by_endpoint_group(self, endpoint_group_id): - endpoints = self.catalog_api.list_endpoints() - filters = self.endpoint_filter_api.get_endpoint_group( - endpoint_group_id)['filters'] - filtered_endpoints = [] - - for endpoint in endpoints: - is_candidate = True - for key, value in filters.items(): - if endpoint[key] != value: - is_candidate = False - break - if is_candidate: - filtered_endpoints.append(endpoint) - return filtered_endpoints - - -class EndpointFilterV3Controller(_ControllerBase): - - def __init__(self): - super(EndpointFilterV3Controller, self).__init__() - notifications.register_event_callback( - notifications.ACTIONS.deleted, 'project', - self._on_project_or_endpoint_delete) - notifications.register_event_callback( - notifications.ACTIONS.deleted, 'endpoint', - self._on_project_or_endpoint_delete) - - def _on_project_or_endpoint_delete(self, service, resource_type, operation, - payload): - project_or_endpoint_id = payload['resource_info'] - if resource_type == 'project': - self.endpoint_filter_api.delete_association_by_project( - project_or_endpoint_id) - else: - self.endpoint_filter_api.delete_association_by_endpoint( - project_or_endpoint_id) - - @controller.protected() - def add_endpoint_to_project(self, context, project_id, endpoint_id): - """Establishes an association between an endpoint and a project.""" - # NOTE(gyee): we just need to make sure endpoint and project exist - # first. We don't really care whether if project is disabled. - # The relationship can still be established even with a disabled - # project as there are no security implications. - self.catalog_api.get_endpoint(endpoint_id) - self.resource_api.get_project(project_id) - self.endpoint_filter_api.add_endpoint_to_project(endpoint_id, - project_id) - - @controller.protected() - def check_endpoint_in_project(self, context, project_id, endpoint_id): - """Verifies endpoint is currently associated with given project.""" - self.catalog_api.get_endpoint(endpoint_id) - self.resource_api.get_project(project_id) - self.endpoint_filter_api.check_endpoint_in_project(endpoint_id, - project_id) - - @controller.protected() - def list_endpoints_for_project(self, context, project_id): - """List all endpoints currently associated with a given project.""" - self.resource_api.get_project(project_id) - refs = self.endpoint_filter_api.list_endpoints_for_project(project_id) - filtered_endpoints = {ref['endpoint_id']: - self.catalog_api.get_endpoint(ref['endpoint_id']) - for ref in refs} - - # need to recover endpoint_groups associated with project - # then for each endpoint group return the endpoints. - endpoint_groups = self._get_endpoint_groups_for_project(project_id) - for endpoint_group in endpoint_groups: - endpoint_refs = self._get_endpoints_filtered_by_endpoint_group( - endpoint_group['id']) - # now check if any endpoints for current endpoint group are not - # contained in the list of filtered endpoints - for endpoint_ref in endpoint_refs: - if endpoint_ref['id'] not in filtered_endpoints: - filtered_endpoints[endpoint_ref['id']] = endpoint_ref - - return catalog_controllers.EndpointV3.wrap_collection( - context, [v for v in six.itervalues(filtered_endpoints)]) - - @controller.protected() - def remove_endpoint_from_project(self, context, project_id, endpoint_id): - """Remove the endpoint from the association with given project.""" - self.endpoint_filter_api.remove_endpoint_from_project(endpoint_id, - project_id) - - @controller.protected() - def list_projects_for_endpoint(self, context, endpoint_id): - """Return a list of projects associated with the endpoint.""" - self.catalog_api.get_endpoint(endpoint_id) - refs = self.endpoint_filter_api.list_projects_for_endpoint(endpoint_id) - - projects = [self.resource_api.get_project( - ref['project_id']) for ref in refs] - return resource.controllers.ProjectV3.wrap_collection(context, - projects) - - -class EndpointGroupV3Controller(_ControllerBase): - collection_name = 'endpoint_groups' - member_name = 'endpoint_group' - - VALID_FILTER_KEYS = ['service_id', 'region_id', 'interface'] - - def __init__(self): - super(EndpointGroupV3Controller, self).__init__() - - @classmethod - def base_url(cls, context, path=None): - """Construct a path and pass it to V3Controller.base_url method.""" - - path = '/OS-EP-FILTER/' + cls.collection_name - return super(EndpointGroupV3Controller, cls).base_url(context, - path=path) - - @controller.protected() - @validation.validated(schema.endpoint_group_create, 'endpoint_group') - def create_endpoint_group(self, context, endpoint_group): - """Creates an Endpoint Group with the associated filters.""" - ref = self._assign_unique_id(self._normalize_dict(endpoint_group)) - self._require_attribute(ref, 'filters') - self._require_valid_filter(ref) - ref = self.endpoint_filter_api.create_endpoint_group(ref['id'], ref) - return EndpointGroupV3Controller.wrap_member(context, ref) - - def _require_valid_filter(self, endpoint_group): - filters = endpoint_group.get('filters') - for key in six.iterkeys(filters): - if key not in self.VALID_FILTER_KEYS: - raise exception.ValidationError( - attribute=self._valid_filter_keys(), - target='endpoint_group') - - def _valid_filter_keys(self): - return ' or '.join(self.VALID_FILTER_KEYS) - - @controller.protected() - def get_endpoint_group(self, context, endpoint_group_id): - """Retrieve the endpoint group associated with the id if exists.""" - ref = self.endpoint_filter_api.get_endpoint_group(endpoint_group_id) - return EndpointGroupV3Controller.wrap_member( - context, ref) - - @controller.protected() - @validation.validated(schema.endpoint_group_update, 'endpoint_group') - def update_endpoint_group(self, context, endpoint_group_id, - endpoint_group): - """Update fixed values and/or extend the filters.""" - if 'filters' in endpoint_group: - self._require_valid_filter(endpoint_group) - ref = self.endpoint_filter_api.update_endpoint_group(endpoint_group_id, - endpoint_group) - return EndpointGroupV3Controller.wrap_member( - context, ref) - - @controller.protected() - def delete_endpoint_group(self, context, endpoint_group_id): - """Delete endpoint_group.""" - self.endpoint_filter_api.delete_endpoint_group(endpoint_group_id) - - @controller.protected() - def list_endpoint_groups(self, context): - """List all endpoint groups.""" - refs = self.endpoint_filter_api.list_endpoint_groups() - return EndpointGroupV3Controller.wrap_collection( - context, refs) - - @controller.protected() - def list_endpoint_groups_for_project(self, context, project_id): - """List all endpoint groups associated with a given project.""" - return EndpointGroupV3Controller.wrap_collection( - context, self._get_endpoint_groups_for_project(project_id)) - - @controller.protected() - def list_projects_associated_with_endpoint_group(self, - context, - endpoint_group_id): - """List all projects associated with endpoint group.""" - endpoint_group_refs = (self.endpoint_filter_api. - list_projects_associated_with_endpoint_group( - endpoint_group_id)) - projects = [] - for endpoint_group_ref in endpoint_group_refs: - project = self.resource_api.get_project( - endpoint_group_ref['project_id']) - if project: - projects.append(project) - return resource.controllers.ProjectV3.wrap_collection(context, - projects) - - @controller.protected() - def list_endpoints_associated_with_endpoint_group(self, - context, - endpoint_group_id): - """List all the endpoints filtered by a specific endpoint group.""" - filtered_endpoints = self._get_endpoints_filtered_by_endpoint_group( - endpoint_group_id) - return catalog_controllers.EndpointV3.wrap_collection( - context, filtered_endpoints) - - -class ProjectEndpointGroupV3Controller(_ControllerBase): - collection_name = 'project_endpoint_groups' - member_name = 'project_endpoint_group' - - def __init__(self): - super(ProjectEndpointGroupV3Controller, self).__init__() - notifications.register_event_callback( - notifications.ACTIONS.deleted, 'project', - self._on_project_delete) - - def _on_project_delete(self, service, resource_type, - operation, payload): - project_id = payload['resource_info'] - (self.endpoint_filter_api. - delete_endpoint_group_association_by_project( - project_id)) - - @controller.protected() - def get_endpoint_group_in_project(self, context, endpoint_group_id, - project_id): - """Retrieve the endpoint group associated with the id if exists.""" - self.resource_api.get_project(project_id) - self.endpoint_filter_api.get_endpoint_group(endpoint_group_id) - ref = self.endpoint_filter_api.get_endpoint_group_in_project( - endpoint_group_id, project_id) - return ProjectEndpointGroupV3Controller.wrap_member( - context, ref) - - @controller.protected() - def add_endpoint_group_to_project(self, context, endpoint_group_id, - project_id): - """Creates an association between an endpoint group and project.""" - self.resource_api.get_project(project_id) - self.endpoint_filter_api.get_endpoint_group(endpoint_group_id) - self.endpoint_filter_api.add_endpoint_group_to_project( - endpoint_group_id, project_id) - - @controller.protected() - def remove_endpoint_group_from_project(self, context, endpoint_group_id, - project_id): - """Remove the endpoint group from associated project.""" - self.resource_api.get_project(project_id) - self.endpoint_filter_api.get_endpoint_group(endpoint_group_id) - self.endpoint_filter_api.remove_endpoint_group_from_project( - endpoint_group_id, project_id) - - @classmethod - def _add_self_referential_link(cls, context, ref): - url = ('/OS-EP-FILTER/endpoint_groups/%(endpoint_group_id)s' - '/projects/%(project_id)s' % { - 'endpoint_group_id': ref['endpoint_group_id'], - 'project_id': ref['project_id']}) - ref.setdefault('links', {}) - ref['links']['self'] = url diff --git a/keystone-moon/keystone/contrib/endpoint_filter/core.py b/keystone-moon/keystone/contrib/endpoint_filter/core.py deleted file mode 100644 index b66465ea..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/core.py +++ /dev/null @@ -1,296 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into the Endpoint Filter service.""" - -import abc - -from oslo_config import cfg -from oslo_log import log -import six - -from keystone.common import dependency -from keystone.common import extension -from keystone.common import manager -from keystone import exception - - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - -extension_data = { - 'name': 'OpenStack Keystone Endpoint Filter API', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-EP-FILTER/v1.0', - 'alias': 'OS-EP-FILTER', - 'updated': '2013-07-23T12:00:0-00:00', - 'description': 'OpenStack Keystone Endpoint Filter API.', - 'links': [ - { - 'rel': 'describedby', - # TODO(ayoung): needs a description - 'type': 'text/html', - 'href': 'https://github.com/openstack/identity-api/blob/master' - '/openstack-identity-api/v3/src/markdown/' - 'identity-api-v3-os-ep-filter-ext.md', - } - ]} -extension.register_admin_extension(extension_data['alias'], extension_data) - - -@dependency.provider('endpoint_filter_api') -class Manager(manager.Manager): - """Default pivot point for the Endpoint Filter backend. - - See :mod:`keystone.common.manager.Manager` for more details on how this - dynamically calls the backend. - - """ - - driver_namespace = 'keystone.endpoint_filter' - - def __init__(self): - super(Manager, self).__init__(CONF.endpoint_filter.driver) - - -@six.add_metaclass(abc.ABCMeta) -class EndpointFilterDriverV8(object): - """Interface description for an Endpoint Filter driver.""" - - @abc.abstractmethod - def add_endpoint_to_project(self, endpoint_id, project_id): - """Create an endpoint to project association. - - :param endpoint_id: identity of endpoint to associate - :type endpoint_id: string - :param project_id: identity of the project to be associated with - :type project_id: string - :raises: keystone.exception.Conflict, - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def remove_endpoint_from_project(self, endpoint_id, project_id): - """Removes an endpoint to project association. - - :param endpoint_id: identity of endpoint to remove - :type endpoint_id: string - :param project_id: identity of the project associated with - :type project_id: string - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def check_endpoint_in_project(self, endpoint_id, project_id): - """Checks if an endpoint is associated with a project. - - :param endpoint_id: identity of endpoint to check - :type endpoint_id: string - :param project_id: identity of the project associated with - :type project_id: string - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_endpoints_for_project(self, project_id): - """List all endpoints associated with a project. - - :param project_id: identity of the project to check - :type project_id: string - :returns: a list of identity endpoint ids or an empty list. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_projects_for_endpoint(self, endpoint_id): - """List all projects associated with an endpoint. - - :param endpoint_id: identity of endpoint to check - :type endpoint_id: string - :returns: a list of projects or an empty list. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_association_by_endpoint(self, endpoint_id): - """Removes all the endpoints to project association with endpoint. - - :param endpoint_id: identity of endpoint to check - :type endpoint_id: string - :returns: None - - """ - raise exception.NotImplemented() - - @abc.abstractmethod - def delete_association_by_project(self, project_id): - """Removes all the endpoints to project association with project. - - :param project_id: identity of the project to check - :type project_id: string - :returns: None - - """ - raise exception.NotImplemented() - - @abc.abstractmethod - def create_endpoint_group(self, endpoint_group): - """Create an endpoint group. - - :param endpoint_group: endpoint group to create - :type endpoint_group: dictionary - :raises: keystone.exception.Conflict, - :returns: an endpoint group representation. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_endpoint_group(self, endpoint_group_id): - """Get an endpoint group. - - :param endpoint_group_id: identity of endpoint group to retrieve - :type endpoint_group_id: string - :raises: exception.NotFound - :returns: an endpoint group representation. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def update_endpoint_group(self, endpoint_group_id, endpoint_group): - """Update an endpoint group. - - :param endpoint_group_id: identity of endpoint group to retrieve - :type endpoint_group_id: string - :param endpoint_group: A full or partial endpoint_group - :type endpoint_group: dictionary - :raises: exception.NotFound - :returns: an endpoint group representation. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_endpoint_group(self, endpoint_group_id): - """Delete an endpoint group. - - :param endpoint_group_id: identity of endpoint group to delete - :type endpoint_group_id: string - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def add_endpoint_group_to_project(self, endpoint_group_id, project_id): - """Adds an endpoint group to project association. - - :param endpoint_group_id: identity of endpoint to associate - :type endpoint_group_id: string - :param project_id: identity of project to associate - :type project_id: string - :raises: keystone.exception.Conflict, - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_endpoint_group_in_project(self, endpoint_group_id, project_id): - """Get endpoint group to project association. - - :param endpoint_group_id: identity of endpoint group to retrieve - :type endpoint_group_id: string - :param project_id: identity of project to associate - :type project_id: string - :raises: exception.NotFound - :returns: a project endpoint group representation. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_endpoint_groups(self): - """List all endpoint groups. - - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_endpoint_groups_for_project(self, project_id): - """List all endpoint group to project associations for a project. - - :param project_id: identity of project to associate - :type project_id: string - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_projects_associated_with_endpoint_group(self, endpoint_group_id): - """List all projects associated with endpoint group. - - :param endpoint_group_id: identity of endpoint to associate - :type endpoint_group_id: string - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def remove_endpoint_group_from_project(self, endpoint_group_id, - project_id): - """Remove an endpoint to project association. - - :param endpoint_group_id: identity of endpoint to associate - :type endpoint_group_id: string - :param project_id: identity of project to associate - :type project_id: string - :raises: exception.NotFound - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_endpoint_group_association_by_project(self, project_id): - """Remove endpoint group to project associations. - - :param project_id: identity of the project to check - :type project_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - -Driver = manager.create_legacy_driver(EndpointFilterDriverV8) diff --git a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/migrate.cfg deleted file mode 100644 index c7d34785..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=endpoint_filter - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/001_add_endpoint_filtering_table.py b/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/001_add_endpoint_filtering_table.py deleted file mode 100644 index ac0a30cc..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/001_add_endpoint_filtering_table.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='endpoint_filter') diff --git a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/002_add_endpoint_groups.py b/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/002_add_endpoint_groups.py deleted file mode 100644 index ac5aa5b3..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/002_add_endpoint_groups.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2014 Hewlett-Packard Company -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='endpoint_filter') diff --git a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_filter/routers.py b/keystone-moon/keystone/contrib/endpoint_filter/routers.py deleted file mode 100644 index f75110f9..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/routers.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class EndpointFilterExtension(wsgi.Middleware): - - def __init__(self, *args, **kwargs): - super(EndpointFilterExtension, self).__init__(*args, **kwargs) - msg = _("Remove endpoint_filter_extension from the paste pipeline, " - "the endpoint filter extension is now always available. " - "Update the [pipeline:api_v3] section in keystone-paste.ini " - "accordingly as it will be removed in the O release.") - versionutils.report_deprecated_feature(LOG, msg) diff --git a/keystone-moon/keystone/contrib/endpoint_filter/schema.py b/keystone-moon/keystone/contrib/endpoint_filter/schema.py deleted file mode 100644 index cbe54e36..00000000 --- a/keystone-moon/keystone/contrib/endpoint_filter/schema.py +++ /dev/null @@ -1,35 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.common import validation -from keystone.common.validation import parameter_types - - -_endpoint_group_properties = { - 'description': validation.nullable(parameter_types.description), - 'filters': { - 'type': 'object' - }, - 'name': parameter_types.name -} - -endpoint_group_create = { - 'type': 'object', - 'properties': _endpoint_group_properties, - 'required': ['name', 'filters'] -} - -endpoint_group_update = { - 'type': 'object', - 'properties': _endpoint_group_properties, - 'minProperties': 1 -} diff --git a/keystone-moon/keystone/contrib/endpoint_policy/__init__.py b/keystone-moon/keystone/contrib/endpoint_policy/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_policy/backends/__init__.py b/keystone-moon/keystone/contrib/endpoint_policy/backends/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/backends/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_policy/backends/sql.py b/keystone-moon/keystone/contrib/endpoint_policy/backends/sql.py deleted file mode 100644 index 93331779..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/backends/sql.py +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import versionutils - -from keystone.endpoint_policy.backends import sql - -_OLD = 'keystone.contrib.endpoint_policy.backends.sql.EndpointPolicy' -_NEW = 'keystone.endpoint_policy.backends.sql.EndpointPolicy' - - -class EndpointPolicy(sql.EndpointPolicy): - - @versionutils.deprecated(versionutils.deprecated.LIBERTY, - in_favor_of=_NEW, - remove_in=1, - what=_OLD) - def __init__(self, *args, **kwargs): - super(EndpointPolicy, self).__init__(*args, **kwargs) diff --git a/keystone-moon/keystone/contrib/endpoint_policy/controllers.py b/keystone-moon/keystone/contrib/endpoint_policy/controllers.py deleted file mode 100644 index b96834dc..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/controllers.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.common import controller -from keystone.common import dependency -from keystone import notifications - - -@dependency.requires('policy_api', 'catalog_api', 'endpoint_policy_api') -class EndpointPolicyV3Controller(controller.V3Controller): - collection_name = 'endpoints' - member_name = 'endpoint' - - def __init__(self): - super(EndpointPolicyV3Controller, self).__init__() - notifications.register_event_callback( - 'deleted', 'endpoint', self._on_endpoint_delete) - notifications.register_event_callback( - 'deleted', 'service', self._on_service_delete) - notifications.register_event_callback( - 'deleted', 'region', self._on_region_delete) - notifications.register_event_callback( - 'deleted', 'policy', self._on_policy_delete) - - def _on_endpoint_delete(self, service, resource_type, operation, payload): - self.endpoint_policy_api.delete_association_by_endpoint( - payload['resource_info']) - - def _on_service_delete(self, service, resource_type, operation, payload): - self.endpoint_policy_api.delete_association_by_service( - payload['resource_info']) - - def _on_region_delete(self, service, resource_type, operation, payload): - self.endpoint_policy_api.delete_association_by_region( - payload['resource_info']) - - def _on_policy_delete(self, service, resource_type, operation, payload): - self.endpoint_policy_api.delete_association_by_policy( - payload['resource_info']) - - @controller.protected() - def create_policy_association_for_endpoint(self, context, - policy_id, endpoint_id): - """Create an association between a policy and an endpoint.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_endpoint(endpoint_id) - self.endpoint_policy_api.create_policy_association( - policy_id, endpoint_id=endpoint_id) - - @controller.protected() - def check_policy_association_for_endpoint(self, context, - policy_id, endpoint_id): - """Check an association between a policy and an endpoint.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_endpoint(endpoint_id) - self.endpoint_policy_api.check_policy_association( - policy_id, endpoint_id=endpoint_id) - - @controller.protected() - def delete_policy_association_for_endpoint(self, context, - policy_id, endpoint_id): - """Delete an association between a policy and an endpoint.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_endpoint(endpoint_id) - self.endpoint_policy_api.delete_policy_association( - policy_id, endpoint_id=endpoint_id) - - @controller.protected() - def create_policy_association_for_service(self, context, - policy_id, service_id): - """Create an association between a policy and a service.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_service(service_id) - self.endpoint_policy_api.create_policy_association( - policy_id, service_id=service_id) - - @controller.protected() - def check_policy_association_for_service(self, context, - policy_id, service_id): - """Check an association between a policy and a service.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_service(service_id) - self.endpoint_policy_api.check_policy_association( - policy_id, service_id=service_id) - - @controller.protected() - def delete_policy_association_for_service(self, context, - policy_id, service_id): - """Delete an association between a policy and a service.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_service(service_id) - self.endpoint_policy_api.delete_policy_association( - policy_id, service_id=service_id) - - @controller.protected() - def create_policy_association_for_region_and_service( - self, context, policy_id, service_id, region_id): - """Create an association between a policy and region+service.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_service(service_id) - self.catalog_api.get_region(region_id) - self.endpoint_policy_api.create_policy_association( - policy_id, service_id=service_id, region_id=region_id) - - @controller.protected() - def check_policy_association_for_region_and_service( - self, context, policy_id, service_id, region_id): - """Check an association between a policy and region+service.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_service(service_id) - self.catalog_api.get_region(region_id) - self.endpoint_policy_api.check_policy_association( - policy_id, service_id=service_id, region_id=region_id) - - @controller.protected() - def delete_policy_association_for_region_and_service( - self, context, policy_id, service_id, region_id): - """Delete an association between a policy and region+service.""" - self.policy_api.get_policy(policy_id) - self.catalog_api.get_service(service_id) - self.catalog_api.get_region(region_id) - self.endpoint_policy_api.delete_policy_association( - policy_id, service_id=service_id, region_id=region_id) - - @controller.protected() - def get_policy_for_endpoint(self, context, endpoint_id): - """Get the effective policy for an endpoint.""" - self.catalog_api.get_endpoint(endpoint_id) - ref = self.endpoint_policy_api.get_policy_for_endpoint(endpoint_id) - # NOTE(henry-nash): since the collection and member for this class is - # set to endpoints, we have to handle wrapping this policy entity - # ourselves. - self._add_self_referential_link(context, ref) - return {'policy': ref} - - # NOTE(henry-nash): As in the catalog controller, we must ensure that the - # legacy_endpoint_id does not escape. - - @classmethod - def filter_endpoint(cls, ref): - if 'legacy_endpoint_id' in ref: - ref.pop('legacy_endpoint_id') - return ref - - @classmethod - def wrap_member(cls, context, ref): - ref = cls.filter_endpoint(ref) - return super(EndpointPolicyV3Controller, cls).wrap_member(context, ref) - - @controller.protected() - def list_endpoints_for_policy(self, context, policy_id): - """List endpoints with the effective association to a policy.""" - self.policy_api.get_policy(policy_id) - refs = self.endpoint_policy_api.list_endpoints_for_policy(policy_id) - return EndpointPolicyV3Controller.wrap_collection(context, refs) diff --git a/keystone-moon/keystone/contrib/endpoint_policy/core.py b/keystone-moon/keystone/contrib/endpoint_policy/core.py deleted file mode 100644 index 1aa03267..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/core.py +++ /dev/null @@ -1,430 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import abc - -from oslo_config import cfg -from oslo_log import log -import six - -from keystone.common import dependency -from keystone.common import manager -from keystone import exception -from keystone.i18n import _, _LE, _LW - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - - -@dependency.provider('endpoint_policy_api') -@dependency.requires('catalog_api', 'policy_api') -class Manager(manager.Manager): - """Default pivot point for the Endpoint Policy backend. - - See :mod:`keystone.common.manager.Manager` for more details on how this - dynamically calls the backend. - - """ - - def __init__(self): - super(Manager, self).__init__(CONF.endpoint_policy.driver) - - def _assert_valid_association(self, endpoint_id, service_id, region_id): - """Assert that the association is supported. - - There are three types of association supported: - - - Endpoint (in which case service and region must be None) - - Service and region (in which endpoint must be None) - - Service (in which case endpoint and region must be None) - - """ - if (endpoint_id is not None and - service_id is None and region_id is None): - return - if (service_id is not None and region_id is not None and - endpoint_id is None): - return - if (service_id is not None and - endpoint_id is None and region_id is None): - return - - raise exception.InvalidPolicyAssociation(endpoint_id=endpoint_id, - service_id=service_id, - region_id=region_id) - - def create_policy_association(self, policy_id, endpoint_id=None, - service_id=None, region_id=None): - self._assert_valid_association(endpoint_id, service_id, region_id) - self.driver.create_policy_association(policy_id, endpoint_id, - service_id, region_id) - - def check_policy_association(self, policy_id, endpoint_id=None, - service_id=None, region_id=None): - self._assert_valid_association(endpoint_id, service_id, region_id) - self.driver.check_policy_association(policy_id, endpoint_id, - service_id, region_id) - - def delete_policy_association(self, policy_id, endpoint_id=None, - service_id=None, region_id=None): - self._assert_valid_association(endpoint_id, service_id, region_id) - self.driver.delete_policy_association(policy_id, endpoint_id, - service_id, region_id) - - def list_endpoints_for_policy(self, policy_id): - - def _get_endpoint(endpoint_id, policy_id): - try: - return self.catalog_api.get_endpoint(endpoint_id) - except exception.EndpointNotFound: - msg = _LW('Endpoint %(endpoint_id)s referenced in ' - 'association for policy %(policy_id)s not found.') - LOG.warning(msg, {'policy_id': policy_id, - 'endpoint_id': endpoint_id}) - raise - - def _get_endpoints_for_service(service_id, endpoints): - # TODO(henry-nash): Consider optimizing this in the future by - # adding an explicit list_endpoints_for_service to the catalog API. - return [ep for ep in endpoints if ep['service_id'] == service_id] - - def _get_endpoints_for_service_and_region( - service_id, region_id, endpoints, regions): - # TODO(henry-nash): Consider optimizing this in the future. - # The lack of a two-way pointer in the region tree structure - # makes this somewhat inefficient. - - def _recursively_get_endpoints_for_region( - region_id, service_id, endpoint_list, region_list, - endpoints_found, regions_examined): - """Recursively search down a region tree for endpoints. - - :param region_id: the point in the tree to examine - :param service_id: the service we are interested in - :param endpoint_list: list of all endpoints - :param region_list: list of all regions - :param endpoints_found: list of matching endpoints found so - far - which will be updated if more are - found in this iteration - :param regions_examined: list of regions we have already looked - at - used to spot illegal circular - references in the tree to avoid never - completing search - :returns: list of endpoints that match - - """ - - if region_id in regions_examined: - msg = _LE('Circular reference or a repeated entry found ' - 'in region tree - %(region_id)s.') - LOG.error(msg, {'region_id': ref.region_id}) - return - - regions_examined.append(region_id) - endpoints_found += ( - [ep for ep in endpoint_list if - ep['service_id'] == service_id and - ep['region_id'] == region_id]) - - for region in region_list: - if region['parent_region_id'] == region_id: - _recursively_get_endpoints_for_region( - region['id'], service_id, endpoints, regions, - endpoints_found, regions_examined) - - endpoints_found = [] - regions_examined = [] - - # Now walk down the region tree - _recursively_get_endpoints_for_region( - region_id, service_id, endpoints, regions, - endpoints_found, regions_examined) - - return endpoints_found - - matching_endpoints = [] - endpoints = self.catalog_api.list_endpoints() - regions = self.catalog_api.list_regions() - for ref in self.driver.list_associations_for_policy(policy_id): - if ref.get('endpoint_id') is not None: - matching_endpoints.append( - _get_endpoint(ref['endpoint_id'], policy_id)) - continue - - if (ref.get('service_id') is not None and - ref.get('region_id') is None): - matching_endpoints += _get_endpoints_for_service( - ref['service_id'], endpoints) - continue - - if (ref.get('service_id') is not None and - ref.get('region_id') is not None): - matching_endpoints += ( - _get_endpoints_for_service_and_region( - ref['service_id'], ref['region_id'], - endpoints, regions)) - continue - - msg = _LW('Unsupported policy association found - ' - 'Policy %(policy_id)s, Endpoint %(endpoint_id)s, ' - 'Service %(service_id)s, Region %(region_id)s, ') - LOG.warning(msg, {'policy_id': policy_id, - 'endpoint_id': ref['endpoint_id'], - 'service_id': ref['service_id'], - 'region_id': ref['region_id']}) - - return matching_endpoints - - def get_policy_for_endpoint(self, endpoint_id): - - def _get_policy(policy_id, endpoint_id): - try: - return self.policy_api.get_policy(policy_id) - except exception.PolicyNotFound: - msg = _LW('Policy %(policy_id)s referenced in association ' - 'for endpoint %(endpoint_id)s not found.') - LOG.warning(msg, {'policy_id': policy_id, - 'endpoint_id': endpoint_id}) - raise - - def _look_for_policy_for_region_and_service(endpoint): - """Look in the region and its parents for a policy. - - Examine the region of the endpoint for a policy appropriate for - the service of the endpoint. If there isn't a match, then chase up - the region tree to find one. - - """ - region_id = endpoint['region_id'] - regions_examined = [] - while region_id is not None: - try: - ref = self.driver.get_policy_association( - service_id=endpoint['service_id'], - region_id=region_id) - return ref['policy_id'] - except exception.PolicyAssociationNotFound: - pass - - # There wasn't one for that region & service, let's - # chase up the region tree - regions_examined.append(region_id) - region = self.catalog_api.get_region(region_id) - region_id = None - if region.get('parent_region_id') is not None: - region_id = region['parent_region_id'] - if region_id in regions_examined: - msg = _LE('Circular reference or a repeated entry ' - 'found in region tree - %(region_id)s.') - LOG.error(msg, {'region_id': region_id}) - break - - # First let's see if there is a policy explicitly defined for - # this endpoint. - - try: - ref = self.driver.get_policy_association(endpoint_id=endpoint_id) - return _get_policy(ref['policy_id'], endpoint_id) - except exception.PolicyAssociationNotFound: - pass - - # There wasn't a policy explicitly defined for this endpoint, so - # now let's see if there is one for the Region & Service. - - endpoint = self.catalog_api.get_endpoint(endpoint_id) - policy_id = _look_for_policy_for_region_and_service(endpoint) - if policy_id is not None: - return _get_policy(policy_id, endpoint_id) - - # Finally, just check if there is one for the service. - try: - ref = self.driver.get_policy_association( - service_id=endpoint['service_id']) - return _get_policy(ref['policy_id'], endpoint_id) - except exception.PolicyAssociationNotFound: - pass - - msg = _('No policy is associated with endpoint ' - '%(endpoint_id)s.') % {'endpoint_id': endpoint_id} - raise exception.NotFound(msg) - - -@six.add_metaclass(abc.ABCMeta) -class Driver(object): - """Interface description for an Endpoint Policy driver.""" - - @abc.abstractmethod - def create_policy_association(self, policy_id, endpoint_id=None, - service_id=None, region_id=None): - """Creates a policy association. - - :param policy_id: identity of policy that is being associated - :type policy_id: string - :param endpoint_id: identity of endpoint to associate - :type endpoint_id: string - :param service_id: identity of the service to associate - :type service_id: string - :param region_id: identity of the region to associate - :type region_id: string - :returns: None - - There are three types of association permitted: - - - Endpoint (in which case service and region must be None) - - Service and region (in which endpoint must be None) - - Service (in which case endpoint and region must be None) - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def check_policy_association(self, policy_id, endpoint_id=None, - service_id=None, region_id=None): - """Checks existence a policy association. - - :param policy_id: identity of policy that is being associated - :type policy_id: string - :param endpoint_id: identity of endpoint to associate - :type endpoint_id: string - :param service_id: identity of the service to associate - :type service_id: string - :param region_id: identity of the region to associate - :type region_id: string - :raises: keystone.exception.PolicyAssociationNotFound if there is no - match for the specified association - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_policy_association(self, policy_id, endpoint_id=None, - service_id=None, region_id=None): - """Deletes a policy association. - - :param policy_id: identity of policy that is being associated - :type policy_id: string - :param endpoint_id: identity of endpoint to associate - :type endpoint_id: string - :param service_id: identity of the service to associate - :type service_id: string - :param region_id: identity of the region to associate - :type region_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_policy_association(self, endpoint_id=None, - service_id=None, region_id=None): - """Gets the policy for an explicit association. - - This method is not exposed as a public API, but is used by - get_policy_for_endpoint(). - - :param endpoint_id: identity of endpoint - :type endpoint_id: string - :param service_id: identity of the service - :type service_id: string - :param region_id: identity of the region - :type region_id: string - :raises: keystone.exception.PolicyAssociationNotFound if there is no - match for the specified association - :returns: dict containing policy_id - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_associations_for_policy(self, policy_id): - """List the associations for a policy. - - This method is not exposed as a public API, but is used by - list_endpoints_for_policy(). - - :param policy_id: identity of policy - :type policy_id: string - :returns: List of association dicts - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_endpoints_for_policy(self, policy_id): - """List all the endpoints using a given policy. - - :param policy_id: identity of policy that is being associated - :type policy_id: string - :returns: list of endpoints that have an effective association with - that policy - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_policy_for_endpoint(self, endpoint_id): - """Get the appropriate policy for a given endpoint. - - :param endpoint_id: identity of endpoint - :type endpoint_id: string - :returns: Policy entity for the endpoint - - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_association_by_endpoint(self, endpoint_id): - """Removes all the policy associations with the specific endpoint. - - :param endpoint_id: identity of endpoint to check - :type endpoint_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_association_by_service(self, service_id): - """Removes all the policy associations with the specific service. - - :param service_id: identity of endpoint to check - :type service_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_association_by_region(self, region_id): - """Removes all the policy associations with the specific region. - - :param region_id: identity of endpoint to check - :type region_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_association_by_policy(self, policy_id): - """Removes all the policy associations with the specific policy. - - :param policy_id: identity of endpoint to check - :type policy_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover diff --git a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/migrate.cfg deleted file mode 100644 index 62895d6f..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=endpoint_policy - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/versions/001_add_endpoint_policy_table.py b/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/versions/001_add_endpoint_policy_table.py deleted file mode 100644 index 32bdabdd..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/versions/001_add_endpoint_policy_table.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2014 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='endpoint_policy') diff --git a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/endpoint_policy/routers.py b/keystone-moon/keystone/contrib/endpoint_policy/routers.py deleted file mode 100644 index c8f7f154..00000000 --- a/keystone-moon/keystone/contrib/endpoint_policy/routers.py +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import versionutils - -from keystone.common import wsgi - -_OLD = 'keystone.contrib.endpoint_policy.routers.EndpointPolicyExtension' -_NEW = 'keystone.endpoint_policy.routers.Routers' - - -class EndpointPolicyExtension(wsgi.Middleware): - - @versionutils.deprecated(versionutils.deprecated.LIBERTY, - in_favor_of=_NEW, - remove_in=1, - what=_OLD) - def __init__(self, *args, **kwargs): - super(EndpointPolicyExtension, self).__init__(*args, **kwargs) diff --git a/keystone-moon/keystone/contrib/example/__init__.py b/keystone-moon/keystone/contrib/example/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/example/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/example/configuration.rst b/keystone-moon/keystone/contrib/example/configuration.rst deleted file mode 100644 index 979d3457..00000000 --- a/keystone-moon/keystone/contrib/example/configuration.rst +++ /dev/null @@ -1,31 +0,0 @@ -.. - Copyright 2013 OpenStack, Foundation - All Rights Reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); you may - not use this file except in compliance with the License. You may obtain - a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - License for the specific language governing permissions and limitations - under the License. - -================= -Extension Example -================= - -Please describe here in details how to enable your extension: - -1. Add the required fields and values in the ``[example]`` section - in ``keystone.conf``. - -2. Optional: add the required ``filter`` to the ``pipeline`` in ``keystone-paste.ini`` - -3. Optional: create the extension tables if using the provided sql backend. Example:: - - - ./bin/keystone-manage db_sync --extension example
\ No newline at end of file diff --git a/keystone-moon/keystone/contrib/example/controllers.py b/keystone-moon/keystone/contrib/example/controllers.py deleted file mode 100644 index 95b3e82f..00000000 --- a/keystone-moon/keystone/contrib/example/controllers.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -from keystone.common import controller -from keystone.common import dependency - - -@dependency.requires('example_api') -class ExampleV3Controller(controller.V3Controller): - - @controller.protected() - def example_get(self, context): - """Description of the controller logic.""" - self.example_api.do_something(context) diff --git a/keystone-moon/keystone/contrib/example/core.py b/keystone-moon/keystone/contrib/example/core.py deleted file mode 100644 index e369dc4d..00000000 --- a/keystone-moon/keystone/contrib/example/core.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into this Example service.""" - -from oslo_log import log - -from keystone.common import dependency -from keystone.common import manager -from keystone import exception -from keystone.i18n import _LI -from keystone import notifications - - -LOG = log.getLogger(__name__) - - -@notifications.listener # NOTE(dstanek): only needed if using event_callbacks -@dependency.provider('example_api') -class ExampleManager(manager.Manager): - """Default pivot point for this Example backend. - - See :mod:`keystone.common.manager.Manager` for more details on - how this dynamically calls the backend. - - """ - - driver_namespace = 'keystone.example' - - def __init__(self): - # The following is an example of event callbacks. In this setup, - # ExampleManager's data model is depended on project's data model. - # It must create additional aggregates when a new project is created, - # and it must cleanup data related to the project whenever a project - # has been deleted. - # - # In this example, the project_deleted_callback will be invoked - # whenever a project has been deleted. Similarly, the - # project_created_callback will be invoked whenever a new project is - # created. - - # This information is used when the @notifications.listener decorator - # acts on the class. - self.event_callbacks = { - notifications.ACTIONS.deleted: { - 'project': [self.project_deleted_callback], - }, - notifications.ACTIONS.created: { - 'project': [self.project_created_callback], - }, - } - super(ExampleManager, self).__init__( - 'keystone.contrib.example.core.ExampleDriver') - - def project_deleted_callback(self, service, resource_type, operation, - payload): - # The code below is merely an example. - msg = _LI('Received the following notification: service %(service)s, ' - 'resource_type: %(resource_type)s, operation %(operation)s ' - 'payload %(payload)s') - LOG.info(msg, {'service': service, 'resource_type': resource_type, - 'operation': operation, 'payload': payload}) - - def project_created_callback(self, service, resource_type, operation, - payload): - # The code below is merely an example. - msg = _LI('Received the following notification: service %(service)s, ' - 'resource_type: %(resource_type)s, operation %(operation)s ' - 'payload %(payload)s') - LOG.info(msg, {'service': service, 'resource_type': resource_type, - 'operation': operation, 'payload': payload}) - - -class ExampleDriver(object): - """Interface description for Example driver.""" - - def do_something(self, data): - """Do something - - :param data: example data - :type data: string - :raises: keystone.exception, - :returns: None. - - """ - raise exception.NotImplemented() diff --git a/keystone-moon/keystone/contrib/example/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/example/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/example/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/example/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/example/migrate_repo/migrate.cfg deleted file mode 100644 index 5b1b1c0a..00000000 --- a/keystone-moon/keystone/contrib/example/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=example - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/example/migrate_repo/versions/001_example_table.py b/keystone-moon/keystone/contrib/example/migrate_repo/versions/001_example_table.py deleted file mode 100644 index 35061780..00000000 --- a/keystone-moon/keystone/contrib/example/migrate_repo/versions/001_example_table.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import sqlalchemy as sql - - -def upgrade(migrate_engine): - # Upgrade operations go here. Don't create your own engine; bind - # migrate_engine to your metadata - meta = sql.MetaData() - meta.bind = migrate_engine - - # catalog - - service_table = sql.Table( - 'example', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('type', sql.String(255)), - sql.Column('extra', sql.Text())) - service_table.create(migrate_engine, checkfirst=True) diff --git a/keystone-moon/keystone/contrib/example/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/example/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/example/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/example/routers.py b/keystone-moon/keystone/contrib/example/routers.py deleted file mode 100644 index 30cffe1b..00000000 --- a/keystone-moon/keystone/contrib/example/routers.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import functools - -from keystone.common import json_home -from keystone.common import wsgi -from keystone.contrib.example import controllers - - -build_resource_relation = functools.partial( - json_home.build_v3_extension_resource_relation, - extension_name='OS-EXAMPLE', extension_version='1.0') - - -class ExampleRouter(wsgi.V3ExtensionRouter): - - PATH_PREFIX = '/OS-EXAMPLE' - - def add_routes(self, mapper): - example_controller = controllers.ExampleV3Controller() - - self._add_resource( - mapper, example_controller, - path=self.PATH_PREFIX + '/example', - get_action='do_something', - rel=build_resource_relation(resource_name='example')) diff --git a/keystone-moon/keystone/contrib/federation/__init__.py b/keystone-moon/keystone/contrib/federation/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/federation/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/federation/backends/__init__.py b/keystone-moon/keystone/contrib/federation/backends/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/federation/backends/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/federation/backends/sql.py b/keystone-moon/keystone/contrib/federation/backends/sql.py deleted file mode 100644 index 3c24d9c0..00000000 --- a/keystone-moon/keystone/contrib/federation/backends/sql.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2014 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import versionutils - -from keystone.federation.backends import sql - -_OLD = "keystone.contrib.federation.backends.sql.Federation" -_NEW = "sql" - - -class Federation(sql.Federation): - - @versionutils.deprecated(versionutils.deprecated.MITAKA, - in_favor_of=_NEW, - what=_OLD) - def __init__(self, *args, **kwargs): - super(Federation, self).__init__(*args, **kwargs) diff --git a/keystone-moon/keystone/contrib/federation/constants.py b/keystone-moon/keystone/contrib/federation/constants.py deleted file mode 100644 index afb38494..00000000 --- a/keystone-moon/keystone/contrib/federation/constants.py +++ /dev/null @@ -1,15 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -FEDERATION = 'OS-FEDERATION' -IDENTITY_PROVIDER = 'OS-FEDERATION:identity_provider' -PROTOCOL = 'OS-FEDERATION:protocol' diff --git a/keystone-moon/keystone/contrib/federation/controllers.py b/keystone-moon/keystone/contrib/federation/controllers.py deleted file mode 100644 index d0bd2bce..00000000 --- a/keystone-moon/keystone/contrib/federation/controllers.py +++ /dev/null @@ -1,520 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Workflow logic for the Federation service.""" - -import string - -from oslo_config import cfg -from oslo_log import log -import six -from six.moves import urllib -import webob - -from keystone.auth import controllers as auth_controllers -from keystone.common import authorization -from keystone.common import controller -from keystone.common import dependency -from keystone.common import validation -from keystone.common import wsgi -from keystone.contrib.federation import idp as keystone_idp -from keystone.contrib.federation import schema -from keystone.contrib.federation import utils -from keystone import exception -from keystone.i18n import _ -from keystone.models import token_model - - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - - -class _ControllerBase(controller.V3Controller): - """Base behaviors for federation controllers.""" - - @classmethod - def base_url(cls, context, path=None): - """Construct a path and pass it to V3Controller.base_url method.""" - - path = '/OS-FEDERATION/' + cls.collection_name - return super(_ControllerBase, cls).base_url(context, path=path) - - -@dependency.requires('federation_api') -class IdentityProvider(_ControllerBase): - """Identity Provider representation.""" - collection_name = 'identity_providers' - member_name = 'identity_provider' - - _mutable_parameters = frozenset(['description', 'enabled', 'remote_ids']) - _public_parameters = frozenset(['id', 'enabled', 'description', - 'remote_ids', 'links' - ]) - - @classmethod - def _add_related_links(cls, context, ref): - """Add URLs for entities related with Identity Provider. - - Add URLs pointing to: - - protocols tied to the Identity Provider - - """ - ref.setdefault('links', {}) - base_path = ref['links'].get('self') - if base_path is None: - base_path = '/'.join([IdentityProvider.base_url(context), - ref['id']]) - for name in ['protocols']: - ref['links'][name] = '/'.join([base_path, name]) - - @classmethod - def _add_self_referential_link(cls, context, ref): - id = ref.get('id') - self_path = '/'.join([cls.base_url(context), id]) - ref.setdefault('links', {}) - ref['links']['self'] = self_path - - @classmethod - def wrap_member(cls, context, ref): - cls._add_self_referential_link(context, ref) - cls._add_related_links(context, ref) - ref = cls.filter_params(ref) - return {cls.member_name: ref} - - @controller.protected() - def create_identity_provider(self, context, idp_id, identity_provider): - identity_provider = self._normalize_dict(identity_provider) - identity_provider.setdefault('enabled', False) - IdentityProvider.check_immutable_params(identity_provider) - idp_ref = self.federation_api.create_idp(idp_id, identity_provider) - response = IdentityProvider.wrap_member(context, idp_ref) - return wsgi.render_response(body=response, status=('201', 'Created')) - - @controller.protected() - def list_identity_providers(self, context): - ref = self.federation_api.list_idps() - ref = [self.filter_params(x) for x in ref] - return IdentityProvider.wrap_collection(context, ref) - - @controller.protected() - def get_identity_provider(self, context, idp_id): - ref = self.federation_api.get_idp(idp_id) - return IdentityProvider.wrap_member(context, ref) - - @controller.protected() - def delete_identity_provider(self, context, idp_id): - self.federation_api.delete_idp(idp_id) - - @controller.protected() - def update_identity_provider(self, context, idp_id, identity_provider): - identity_provider = self._normalize_dict(identity_provider) - IdentityProvider.check_immutable_params(identity_provider) - idp_ref = self.federation_api.update_idp(idp_id, identity_provider) - return IdentityProvider.wrap_member(context, idp_ref) - - -@dependency.requires('federation_api') -class FederationProtocol(_ControllerBase): - """A federation protocol representation. - - See IdentityProvider docstring for explanation on _mutable_parameters - and _public_parameters class attributes. - - """ - collection_name = 'protocols' - member_name = 'protocol' - - _public_parameters = frozenset(['id', 'mapping_id', 'links']) - _mutable_parameters = frozenset(['mapping_id']) - - @classmethod - def _add_self_referential_link(cls, context, ref): - """Add 'links' entry to the response dictionary. - - Calls IdentityProvider.base_url() class method, as it constructs - proper URL along with the 'identity providers' part included. - - :param ref: response dictionary - - """ - ref.setdefault('links', {}) - base_path = ref['links'].get('identity_provider') - if base_path is None: - base_path = [IdentityProvider.base_url(context), ref['idp_id']] - base_path = '/'.join(base_path) - self_path = [base_path, 'protocols', ref['id']] - self_path = '/'.join(self_path) - ref['links']['self'] = self_path - - @classmethod - def _add_related_links(cls, context, ref): - """Add new entries to the 'links' subdictionary in the response. - - Adds 'identity_provider' key with URL pointing to related identity - provider as a value. - - :param ref: response dictionary - - """ - ref.setdefault('links', {}) - base_path = '/'.join([IdentityProvider.base_url(context), - ref['idp_id']]) - ref['links']['identity_provider'] = base_path - - @classmethod - def wrap_member(cls, context, ref): - cls._add_related_links(context, ref) - cls._add_self_referential_link(context, ref) - ref = cls.filter_params(ref) - return {cls.member_name: ref} - - @controller.protected() - def create_protocol(self, context, idp_id, protocol_id, protocol): - ref = self._normalize_dict(protocol) - FederationProtocol.check_immutable_params(ref) - ref = self.federation_api.create_protocol(idp_id, protocol_id, ref) - response = FederationProtocol.wrap_member(context, ref) - return wsgi.render_response(body=response, status=('201', 'Created')) - - @controller.protected() - def update_protocol(self, context, idp_id, protocol_id, protocol): - ref = self._normalize_dict(protocol) - FederationProtocol.check_immutable_params(ref) - ref = self.federation_api.update_protocol(idp_id, protocol_id, - protocol) - return FederationProtocol.wrap_member(context, ref) - - @controller.protected() - def get_protocol(self, context, idp_id, protocol_id): - ref = self.federation_api.get_protocol(idp_id, protocol_id) - return FederationProtocol.wrap_member(context, ref) - - @controller.protected() - def list_protocols(self, context, idp_id): - protocols_ref = self.federation_api.list_protocols(idp_id) - protocols = list(protocols_ref) - return FederationProtocol.wrap_collection(context, protocols) - - @controller.protected() - def delete_protocol(self, context, idp_id, protocol_id): - self.federation_api.delete_protocol(idp_id, protocol_id) - - -@dependency.requires('federation_api') -class MappingController(_ControllerBase): - collection_name = 'mappings' - member_name = 'mapping' - - @controller.protected() - def create_mapping(self, context, mapping_id, mapping): - ref = self._normalize_dict(mapping) - utils.validate_mapping_structure(ref) - mapping_ref = self.federation_api.create_mapping(mapping_id, ref) - response = MappingController.wrap_member(context, mapping_ref) - return wsgi.render_response(body=response, status=('201', 'Created')) - - @controller.protected() - def list_mappings(self, context): - ref = self.federation_api.list_mappings() - return MappingController.wrap_collection(context, ref) - - @controller.protected() - def get_mapping(self, context, mapping_id): - ref = self.federation_api.get_mapping(mapping_id) - return MappingController.wrap_member(context, ref) - - @controller.protected() - def delete_mapping(self, context, mapping_id): - self.federation_api.delete_mapping(mapping_id) - - @controller.protected() - def update_mapping(self, context, mapping_id, mapping): - mapping = self._normalize_dict(mapping) - utils.validate_mapping_structure(mapping) - mapping_ref = self.federation_api.update_mapping(mapping_id, mapping) - return MappingController.wrap_member(context, mapping_ref) - - -@dependency.requires('federation_api') -class Auth(auth_controllers.Auth): - - def _get_sso_origin_host(self, context): - """Validate and return originating dashboard URL. - - Make sure the parameter is specified in the request's URL as well its - value belongs to a list of trusted dashboards. - - :param context: request's context - :raises: exception.ValidationError: ``origin`` query parameter was not - specified. The URL is deemed invalid. - :raises: exception.Unauthorized: URL specified in origin query - parameter does not exist in list of websso trusted dashboards. - :returns: URL with the originating dashboard - - """ - if 'origin' in context['query_string']: - origin = context['query_string'].get('origin') - host = urllib.parse.unquote_plus(origin) - else: - msg = _('Request must have an origin query parameter') - LOG.error(msg) - raise exception.ValidationError(msg) - - if host not in CONF.federation.trusted_dashboard: - msg = _('%(host)s is not a trusted dashboard host') - msg = msg % {'host': host} - LOG.error(msg) - raise exception.Unauthorized(msg) - - return host - - def federated_authentication(self, context, identity_provider, protocol): - """Authenticate from dedicated url endpoint. - - Build HTTP request body for federated authentication and inject - it into the ``authenticate_for_token`` function. - - """ - auth = { - 'identity': { - 'methods': [protocol], - protocol: { - 'identity_provider': identity_provider, - 'protocol': protocol - } - } - } - - return self.authenticate_for_token(context, auth=auth) - - def federated_sso_auth(self, context, protocol_id): - try: - remote_id_name = utils.get_remote_id_parameter(protocol_id) - remote_id = context['environment'][remote_id_name] - except KeyError: - msg = _('Missing entity ID from environment') - LOG.error(msg) - raise exception.Unauthorized(msg) - - host = self._get_sso_origin_host(context) - - ref = self.federation_api.get_idp_from_remote_id(remote_id) - # NOTE(stevemar): the returned object is a simple dict that - # contains the idp_id and remote_id. - identity_provider = ref['idp_id'] - res = self.federated_authentication(context, identity_provider, - protocol_id) - token_id = res.headers['X-Subject-Token'] - return self.render_html_response(host, token_id) - - def federated_idp_specific_sso_auth(self, context, idp_id, protocol_id): - host = self._get_sso_origin_host(context) - - # NOTE(lbragstad): We validate that the Identity Provider actually - # exists in the Mapped authentication plugin. - res = self.federated_authentication(context, idp_id, protocol_id) - token_id = res.headers['X-Subject-Token'] - return self.render_html_response(host, token_id) - - def render_html_response(self, host, token_id): - """Forms an HTML Form from a template with autosubmit.""" - - headers = [('Content-Type', 'text/html')] - - with open(CONF.federation.sso_callback_template) as template: - src = string.Template(template.read()) - - subs = {'host': host, 'token': token_id} - body = src.substitute(subs) - return webob.Response(body=body, status='200', - headerlist=headers) - - def _create_base_saml_assertion(self, context, auth): - issuer = CONF.saml.idp_entity_id - sp_id = auth['scope']['service_provider']['id'] - service_provider = self.federation_api.get_sp(sp_id) - utils.assert_enabled_service_provider_object(service_provider) - sp_url = service_provider.get('sp_url') - - token_id = auth['identity']['token']['id'] - token_data = self.token_provider_api.validate_token(token_id) - token_ref = token_model.KeystoneToken(token_id, token_data) - - if not token_ref.project_scoped: - action = _('Use a project scoped token when attempting to create ' - 'a SAML assertion') - raise exception.ForbiddenAction(action=action) - - subject = token_ref.user_name - roles = token_ref.role_names - project = token_ref.project_name - # NOTE(rodrigods): the domain name is necessary in order to distinguish - # between projects and users with the same name in different domains. - project_domain_name = token_ref.project_domain_name - subject_domain_name = token_ref.user_domain_name - - generator = keystone_idp.SAMLGenerator() - response = generator.samlize_token( - issuer, sp_url, subject, subject_domain_name, - roles, project, project_domain_name) - return (response, service_provider) - - def _build_response_headers(self, service_provider): - return [('Content-Type', 'text/xml'), - ('X-sp-url', six.binary_type(service_provider['sp_url'])), - ('X-auth-url', six.binary_type(service_provider['auth_url']))] - - @validation.validated(schema.saml_create, 'auth') - def create_saml_assertion(self, context, auth): - """Exchange a scoped token for a SAML assertion. - - :param auth: Dictionary that contains a token and service provider ID - :returns: SAML Assertion based on properties from the token - """ - - t = self._create_base_saml_assertion(context, auth) - (response, service_provider) = t - - headers = self._build_response_headers(service_provider) - return wsgi.render_response(body=response.to_string(), - status=('200', 'OK'), - headers=headers) - - @validation.validated(schema.saml_create, 'auth') - def create_ecp_assertion(self, context, auth): - """Exchange a scoped token for an ECP assertion. - - :param auth: Dictionary that contains a token and service provider ID - :returns: ECP Assertion based on properties from the token - """ - - t = self._create_base_saml_assertion(context, auth) - (saml_assertion, service_provider) = t - relay_state_prefix = service_provider.get('relay_state_prefix') - - generator = keystone_idp.ECPGenerator() - ecp_assertion = generator.generate_ecp(saml_assertion, - relay_state_prefix) - - headers = self._build_response_headers(service_provider) - return wsgi.render_response(body=ecp_assertion.to_string(), - status=('200', 'OK'), - headers=headers) - - -@dependency.requires('assignment_api', 'resource_api') -class DomainV3(controller.V3Controller): - collection_name = 'domains' - member_name = 'domain' - - def __init__(self): - super(DomainV3, self).__init__() - self.get_member_from_driver = self.resource_api.get_domain - - @controller.protected() - def list_domains_for_groups(self, context): - """List all domains available to an authenticated user's groups. - - :param context: request context - :returns: list of accessible domains - - """ - auth_context = context['environment'][authorization.AUTH_CONTEXT_ENV] - domains = self.assignment_api.list_domains_for_groups( - auth_context['group_ids']) - return DomainV3.wrap_collection(context, domains) - - -@dependency.requires('assignment_api', 'resource_api') -class ProjectAssignmentV3(controller.V3Controller): - collection_name = 'projects' - member_name = 'project' - - def __init__(self): - super(ProjectAssignmentV3, self).__init__() - self.get_member_from_driver = self.resource_api.get_project - - @controller.protected() - def list_projects_for_groups(self, context): - """List all projects available to an authenticated user's groups. - - :param context: request context - :returns: list of accessible projects - - """ - auth_context = context['environment'][authorization.AUTH_CONTEXT_ENV] - projects = self.assignment_api.list_projects_for_groups( - auth_context['group_ids']) - return ProjectAssignmentV3.wrap_collection(context, projects) - - -@dependency.requires('federation_api') -class ServiceProvider(_ControllerBase): - """Service Provider representation.""" - - collection_name = 'service_providers' - member_name = 'service_provider' - - _mutable_parameters = frozenset(['auth_url', 'description', 'enabled', - 'relay_state_prefix', 'sp_url']) - _public_parameters = frozenset(['auth_url', 'id', 'enabled', 'description', - 'links', 'relay_state_prefix', 'sp_url']) - - @controller.protected() - @validation.validated(schema.service_provider_create, 'service_provider') - def create_service_provider(self, context, sp_id, service_provider): - service_provider = self._normalize_dict(service_provider) - service_provider.setdefault('enabled', False) - service_provider.setdefault('relay_state_prefix', - CONF.saml.relay_state_prefix) - ServiceProvider.check_immutable_params(service_provider) - sp_ref = self.federation_api.create_sp(sp_id, service_provider) - response = ServiceProvider.wrap_member(context, sp_ref) - return wsgi.render_response(body=response, status=('201', 'Created')) - - @controller.protected() - def list_service_providers(self, context): - ref = self.federation_api.list_sps() - ref = [self.filter_params(x) for x in ref] - return ServiceProvider.wrap_collection(context, ref) - - @controller.protected() - def get_service_provider(self, context, sp_id): - ref = self.federation_api.get_sp(sp_id) - return ServiceProvider.wrap_member(context, ref) - - @controller.protected() - def delete_service_provider(self, context, sp_id): - self.federation_api.delete_sp(sp_id) - - @controller.protected() - @validation.validated(schema.service_provider_update, 'service_provider') - def update_service_provider(self, context, sp_id, service_provider): - service_provider = self._normalize_dict(service_provider) - ServiceProvider.check_immutable_params(service_provider) - sp_ref = self.federation_api.update_sp(sp_id, service_provider) - return ServiceProvider.wrap_member(context, sp_ref) - - -class SAMLMetadataV3(_ControllerBase): - member_name = 'metadata' - - def get_metadata(self, context): - metadata_path = CONF.saml.idp_metadata_path - try: - with open(metadata_path, 'r') as metadata_handler: - metadata = metadata_handler.read() - except IOError as e: - # Raise HTTP 500 in case Metadata file cannot be read. - raise exception.MetadataFileError(reason=e) - return wsgi.render_response(body=metadata, status=('200', 'OK'), - headers=[('Content-Type', 'text/xml')]) diff --git a/keystone-moon/keystone/contrib/federation/core.py b/keystone-moon/keystone/contrib/federation/core.py deleted file mode 100644 index 1595be1d..00000000 --- a/keystone-moon/keystone/contrib/federation/core.py +++ /dev/null @@ -1,355 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into the Federation service.""" - -import abc - -from oslo_config import cfg -from oslo_log import log as logging -import six - -from keystone.common import dependency -from keystone.common import extension -from keystone.common import manager -from keystone.contrib.federation import utils -from keystone import exception - - -CONF = cfg.CONF -LOG = logging.getLogger(__name__) -EXTENSION_DATA = { - 'name': 'OpenStack Federation APIs', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-FEDERATION/v1.0', - 'alias': 'OS-FEDERATION', - 'updated': '2013-12-17T12:00:0-00:00', - 'description': 'OpenStack Identity Providers Mechanism.', - 'links': [{ - 'rel': 'describedby', - 'type': 'text/html', - 'href': 'https://github.com/openstack/identity-api' - }]} -extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) -extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) - - -@dependency.provider('federation_api') -class Manager(manager.Manager): - """Default pivot point for the Federation backend. - - See :mod:`keystone.common.manager.Manager` for more details on how this - dynamically calls the backend. - - """ - - driver_namespace = 'keystone.federation' - - def __init__(self): - super(Manager, self).__init__(CONF.federation.driver) - - def get_enabled_service_providers(self): - """List enabled service providers for Service Catalog - - Service Provider in a catalog contains three attributes: ``id``, - ``auth_url``, ``sp_url``, where: - - - id is an unique, user defined identifier for service provider object - - auth_url is a authentication URL of remote Keystone - - sp_url a URL accessible at the remote service provider where SAML - assertion is transmitted. - - :returns: list of dictionaries with enabled service providers - :rtype: list of dicts - - """ - def normalize(sp): - ref = { - 'auth_url': sp.auth_url, - 'id': sp.id, - 'sp_url': sp.sp_url - } - return ref - - service_providers = self.driver.get_enabled_service_providers() - return [normalize(sp) for sp in service_providers] - - def evaluate(self, idp_id, protocol_id, assertion_data): - mapping = self.get_mapping_from_idp_and_protocol(idp_id, protocol_id) - rules = mapping['rules'] - rule_processor = utils.RuleProcessor(rules) - mapped_properties = rule_processor.process(assertion_data) - return mapped_properties, mapping['id'] - - -@six.add_metaclass(abc.ABCMeta) -class FederationDriverV8(object): - - @abc.abstractmethod - def create_idp(self, idp_id, idp): - """Create an identity provider. - - :returns: idp_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_idp(self, idp_id): - """Delete an identity provider. - - :raises: keystone.exception.IdentityProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_idps(self): - """List all identity providers. - - :raises: keystone.exception.IdentityProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_idp(self, idp_id): - """Get an identity provider by ID. - - :raises: keystone.exception.IdentityProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_idp_from_remote_id(self, remote_id): - """Get an identity provider by remote ID. - - :raises: keystone.exception.IdentityProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def update_idp(self, idp_id, idp): - """Update an identity provider by ID. - - :raises: keystone.exception.IdentityProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def create_protocol(self, idp_id, protocol_id, protocol): - """Add an IdP-Protocol configuration. - - :raises: keystone.exception.IdentityProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def update_protocol(self, idp_id, protocol_id, protocol): - """Change an IdP-Protocol configuration. - - :raises: keystone.exception.IdentityProviderNotFound, - keystone.exception.FederatedProtocolNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_protocol(self, idp_id, protocol_id): - """Get an IdP-Protocol configuration. - - :raises: keystone.exception.IdentityProviderNotFound, - keystone.exception.FederatedProtocolNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_protocols(self, idp_id): - """List an IdP's supported protocols. - - :raises: keystone.exception.IdentityProviderNotFound, - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_protocol(self, idp_id, protocol_id): - """Delete an IdP-Protocol configuration. - - :raises: keystone.exception.IdentityProviderNotFound, - keystone.exception.FederatedProtocolNotFound, - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def create_mapping(self, mapping_ref): - """Create a mapping. - - :param mapping_ref: mapping ref with mapping name - :type mapping_ref: dict - :returns: mapping_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_mapping(self, mapping_id): - """Delete a mapping. - - :param mapping_id: id of mapping to delete - :type mapping_ref: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def update_mapping(self, mapping_id, mapping_ref): - """Update a mapping. - - :param mapping_id: id of mapping to update - :type mapping_id: string - :param mapping_ref: new mapping ref - :type mapping_ref: dict - :returns: mapping_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_mappings(self): - """List all mappings. - - returns: list of mappings - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_mapping(self, mapping_id): - """Get a mapping, returns the mapping based - on mapping_id. - - :param mapping_id: id of mapping to get - :type mapping_ref: string - :returns: mapping_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_mapping_from_idp_and_protocol(self, idp_id, protocol_id): - """Get mapping based on idp_id and protocol_id. - - :param idp_id: id of the identity provider - :type idp_id: string - :param protocol_id: id of the protocol - :type protocol_id: string - :raises: keystone.exception.IdentityProviderNotFound, - keystone.exception.FederatedProtocolNotFound, - :returns: mapping_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def create_sp(self, sp_id, sp): - """Create a service provider. - - :param sp_id: id of the service provider - :type sp_id: string - :param sp: service prvider object - :type sp: dict - - :returns: sp_ref - :rtype: dict - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_sp(self, sp_id): - """Delete a service provider. - - :param sp_id: id of the service provider - :type sp_id: string - - :raises: keystone.exception.ServiceProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_sps(self): - """List all service providers. - - :returns List of sp_ref objects - :rtype: list of dicts - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_sp(self, sp_id): - """Get a service provider. - - :param sp_id: id of the service provider - :type sp_id: string - - :returns: sp_ref - :raises: keystone.exception.ServiceProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def update_sp(self, sp_id, sp): - """Update a service provider. - - :param sp_id: id of the service provider - :type sp_id: string - :param sp: service prvider object - :type sp: dict - - :returns: sp_ref - :rtype: dict - - :raises: keystone.exception.ServiceProviderNotFound - - """ - raise exception.NotImplemented() # pragma: no cover - - def get_enabled_service_providers(self): - """List enabled service providers for Service Catalog - - Service Provider in a catalog contains three attributes: ``id``, - ``auth_url``, ``sp_url``, where: - - - id is an unique, user defined identifier for service provider object - - auth_url is a authentication URL of remote Keystone - - sp_url a URL accessible at the remote service provider where SAML - assertion is transmitted. - - :returns: list of dictionaries with enabled service providers - :rtype: list of dicts - - """ - raise exception.NotImplemented() # pragma: no cover - - -Driver = manager.create_legacy_driver(FederationDriverV8) diff --git a/keystone-moon/keystone/contrib/federation/idp.py b/keystone-moon/keystone/contrib/federation/idp.py deleted file mode 100644 index 51689989..00000000 --- a/keystone-moon/keystone/contrib/federation/idp.py +++ /dev/null @@ -1,609 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import datetime -import os -import uuid - -from oslo_config import cfg -from oslo_log import log -from oslo_utils import fileutils -from oslo_utils import importutils -from oslo_utils import timeutils -import saml2 -from saml2 import client_base -from saml2 import md -from saml2.profile import ecp -from saml2 import saml -from saml2 import samlp -from saml2.schema import soapenv -from saml2 import sigver -xmldsig = importutils.try_import("saml2.xmldsig") -if not xmldsig: - xmldsig = importutils.try_import("xmldsig") - -from keystone.common import environment -from keystone.common import utils -from keystone import exception -from keystone.i18n import _, _LE - - -subprocess = environment.subprocess - -LOG = log.getLogger(__name__) -CONF = cfg.CONF - - -class SAMLGenerator(object): - """A class to generate SAML assertions.""" - - def __init__(self): - self.assertion_id = uuid.uuid4().hex - - def samlize_token(self, issuer, recipient, user, user_domain_name, roles, - project, project_domain_name, expires_in=None): - """Convert Keystone attributes to a SAML assertion. - - :param issuer: URL of the issuing party - :type issuer: string - :param recipient: URL of the recipient - :type recipient: string - :param user: User name - :type user: string - :param user_domain_name: User Domain name - :type user_domain_name: string - :param roles: List of role names - :type roles: list - :param project: Project name - :type project: string - :param project_domain_name: Project Domain name - :type project_domain_name: string - :param expires_in: Sets how long the assertion is valid for, in seconds - :type expires_in: int - - :return: XML <Response> object - - """ - expiration_time = self._determine_expiration_time(expires_in) - status = self._create_status() - saml_issuer = self._create_issuer(issuer) - subject = self._create_subject(user, expiration_time, recipient) - attribute_statement = self._create_attribute_statement( - user, user_domain_name, roles, project, project_domain_name) - authn_statement = self._create_authn_statement(issuer, expiration_time) - signature = self._create_signature() - - assertion = self._create_assertion(saml_issuer, signature, - subject, authn_statement, - attribute_statement) - - assertion = _sign_assertion(assertion) - - response = self._create_response(saml_issuer, status, assertion, - recipient) - return response - - def _determine_expiration_time(self, expires_in): - if expires_in is None: - expires_in = CONF.saml.assertion_expiration_time - now = timeutils.utcnow() - future = now + datetime.timedelta(seconds=expires_in) - return utils.isotime(future, subsecond=True) - - def _create_status(self): - """Create an object that represents a SAML Status. - - <ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"> - <ns0:StatusCode - Value="urn:oasis:names:tc:SAML:2.0:status:Success" /> - </ns0:Status> - - :return: XML <Status> object - - """ - status = samlp.Status() - status_code = samlp.StatusCode() - status_code.value = samlp.STATUS_SUCCESS - status_code.set_text('') - status.status_code = status_code - return status - - def _create_issuer(self, issuer_url): - """Create an object that represents a SAML Issuer. - - <ns0:Issuer - xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion" - Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"> - https://acme.com/FIM/sps/openstack/saml20</ns0:Issuer> - - :return: XML <Issuer> object - - """ - issuer = saml.Issuer() - issuer.format = saml.NAMEID_FORMAT_ENTITY - issuer.set_text(issuer_url) - return issuer - - def _create_subject(self, user, expiration_time, recipient): - """Create an object that represents a SAML Subject. - - <ns0:Subject> - <ns0:NameID> - john@smith.com</ns0:NameID> - <ns0:SubjectConfirmation - Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> - <ns0:SubjectConfirmationData - NotOnOrAfter="2014-08-19T11:53:57.243106Z" - Recipient="http://beta.com/Shibboleth.sso/SAML2/POST" /> - </ns0:SubjectConfirmation> - </ns0:Subject> - - :return: XML <Subject> object - - """ - name_id = saml.NameID() - name_id.set_text(user) - subject_conf_data = saml.SubjectConfirmationData() - subject_conf_data.recipient = recipient - subject_conf_data.not_on_or_after = expiration_time - subject_conf = saml.SubjectConfirmation() - subject_conf.method = saml.SCM_BEARER - subject_conf.subject_confirmation_data = subject_conf_data - subject = saml.Subject() - subject.subject_confirmation = subject_conf - subject.name_id = name_id - return subject - - def _create_attribute_statement(self, user, user_domain_name, roles, - project, project_domain_name): - """Create an object that represents a SAML AttributeStatement. - - <ns0:AttributeStatement> - <ns0:Attribute Name="openstack_user"> - <ns0:AttributeValue - xsi:type="xs:string">test_user</ns0:AttributeValue> - </ns0:Attribute> - <ns0:Attribute Name="openstack_user_domain"> - <ns0:AttributeValue - xsi:type="xs:string">Default</ns0:AttributeValue> - </ns0:Attribute> - <ns0:Attribute Name="openstack_roles"> - <ns0:AttributeValue - xsi:type="xs:string">admin</ns0:AttributeValue> - <ns0:AttributeValue - xsi:type="xs:string">member</ns0:AttributeValue> - </ns0:Attribute> - <ns0:Attribute Name="openstack_project"> - <ns0:AttributeValue - xsi:type="xs:string">development</ns0:AttributeValue> - </ns0:Attribute> - <ns0:Attribute Name="openstack_project_domain"> - <ns0:AttributeValue - xsi:type="xs:string">Default</ns0:AttributeValue> - </ns0:Attribute> - </ns0:AttributeStatement> - - :return: XML <AttributeStatement> object - - """ - - def _build_attribute(attribute_name, attribute_values): - attribute = saml.Attribute() - attribute.name = attribute_name - - for value in attribute_values: - attribute_value = saml.AttributeValue() - attribute_value.set_text(value) - attribute.attribute_value.append(attribute_value) - - return attribute - - user_attribute = _build_attribute('openstack_user', [user]) - roles_attribute = _build_attribute('openstack_roles', roles) - project_attribute = _build_attribute('openstack_project', [project]) - project_domain_attribute = _build_attribute( - 'openstack_project_domain', [project_domain_name]) - user_domain_attribute = _build_attribute( - 'openstack_user_domain', [user_domain_name]) - - attribute_statement = saml.AttributeStatement() - attribute_statement.attribute.append(user_attribute) - attribute_statement.attribute.append(roles_attribute) - attribute_statement.attribute.append(project_attribute) - attribute_statement.attribute.append(project_domain_attribute) - attribute_statement.attribute.append(user_domain_attribute) - return attribute_statement - - def _create_authn_statement(self, issuer, expiration_time): - """Create an object that represents a SAML AuthnStatement. - - <ns0:AuthnStatement xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion" - AuthnInstant="2014-07-30T03:04:25Z" SessionIndex="47335964efb" - SessionNotOnOrAfter="2014-07-30T03:04:26Z"> - <ns0:AuthnContext> - <ns0:AuthnContextClassRef> - urn:oasis:names:tc:SAML:2.0:ac:classes:Password - </ns0:AuthnContextClassRef> - <ns0:AuthenticatingAuthority> - https://acme.com/FIM/sps/openstack/saml20 - </ns0:AuthenticatingAuthority> - </ns0:AuthnContext> - </ns0:AuthnStatement> - - :return: XML <AuthnStatement> object - - """ - authn_statement = saml.AuthnStatement() - authn_statement.authn_instant = utils.isotime() - authn_statement.session_index = uuid.uuid4().hex - authn_statement.session_not_on_or_after = expiration_time - - authn_context = saml.AuthnContext() - authn_context_class = saml.AuthnContextClassRef() - authn_context_class.set_text(saml.AUTHN_PASSWORD) - - authn_authority = saml.AuthenticatingAuthority() - authn_authority.set_text(issuer) - authn_context.authn_context_class_ref = authn_context_class - authn_context.authenticating_authority = authn_authority - - authn_statement.authn_context = authn_context - - return authn_statement - - def _create_assertion(self, issuer, signature, subject, authn_statement, - attribute_statement): - """Create an object that represents a SAML Assertion. - - <ns0:Assertion - ID="35daed258ba647ba8962e9baff4d6a46" - IssueInstant="2014-06-11T15:45:58Z" - Version="2.0"> - <ns0:Issuer> ... </ns0:Issuer> - <ns1:Signature> ... </ns1:Signature> - <ns0:Subject> ... </ns0:Subject> - <ns0:AuthnStatement> ... </ns0:AuthnStatement> - <ns0:AttributeStatement> ... </ns0:AttributeStatement> - </ns0:Assertion> - - :return: XML <Assertion> object - - """ - assertion = saml.Assertion() - assertion.id = self.assertion_id - assertion.issue_instant = utils.isotime() - assertion.version = '2.0' - assertion.issuer = issuer - assertion.signature = signature - assertion.subject = subject - assertion.authn_statement = authn_statement - assertion.attribute_statement = attribute_statement - return assertion - - def _create_response(self, issuer, status, assertion, recipient): - """Create an object that represents a SAML Response. - - <ns0:Response - Destination="http://beta.com/Shibboleth.sso/SAML2/POST" - ID="c5954543230e4e778bc5b92923a0512d" - IssueInstant="2014-07-30T03:19:45Z" - Version="2.0" /> - <ns0:Issuer> ... </ns0:Issuer> - <ns0:Assertion> ... </ns0:Assertion> - <ns0:Status> ... </ns0:Status> - </ns0:Response> - - :return: XML <Response> object - - """ - response = samlp.Response() - response.id = uuid.uuid4().hex - response.destination = recipient - response.issue_instant = utils.isotime() - response.version = '2.0' - response.issuer = issuer - response.status = status - response.assertion = assertion - return response - - def _create_signature(self): - """Create an object that represents a SAML <Signature>. - - This must be filled with algorithms that the signing binary will apply - in order to sign the whole message. - Currently we enforce X509 signing. - Example of the template:: - - <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> - <SignedInfo> - <CanonicalizationMethod - Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> - <SignatureMethod - Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> - <Reference URI="#<Assertion ID>"> - <Transforms> - <Transform - Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> - <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> - <DigestValue /> - </Reference> - </SignedInfo> - <SignatureValue /> - <KeyInfo> - <X509Data /> - </KeyInfo> - </Signature> - - :return: XML <Signature> object - - """ - canonicalization_method = xmldsig.CanonicalizationMethod() - canonicalization_method.algorithm = xmldsig.ALG_EXC_C14N - signature_method = xmldsig.SignatureMethod( - algorithm=xmldsig.SIG_RSA_SHA1) - - transforms = xmldsig.Transforms() - envelope_transform = xmldsig.Transform( - algorithm=xmldsig.TRANSFORM_ENVELOPED) - - c14_transform = xmldsig.Transform(algorithm=xmldsig.ALG_EXC_C14N) - transforms.transform = [envelope_transform, c14_transform] - - digest_method = xmldsig.DigestMethod(algorithm=xmldsig.DIGEST_SHA1) - digest_value = xmldsig.DigestValue() - - reference = xmldsig.Reference() - reference.uri = '#' + self.assertion_id - reference.digest_method = digest_method - reference.digest_value = digest_value - reference.transforms = transforms - - signed_info = xmldsig.SignedInfo() - signed_info.canonicalization_method = canonicalization_method - signed_info.signature_method = signature_method - signed_info.reference = reference - - key_info = xmldsig.KeyInfo() - key_info.x509_data = xmldsig.X509Data() - - signature = xmldsig.Signature() - signature.signed_info = signed_info - signature.signature_value = xmldsig.SignatureValue() - signature.key_info = key_info - - return signature - - -def _sign_assertion(assertion): - """Sign a SAML assertion. - - This method utilizes ``xmlsec1`` binary and signs SAML assertions in a - separate process. ``xmlsec1`` cannot read input data from stdin so the - prepared assertion needs to be serialized and stored in a temporary - file. This file will be deleted immediately after ``xmlsec1`` returns. - The signed assertion is redirected to a standard output and read using - subprocess.PIPE redirection. A ``saml.Assertion`` class is created - from the signed string again and returned. - - Parameters that are required in the CONF:: - * xmlsec_binary - * private key file path - * public key file path - :return: XML <Assertion> object - - """ - xmlsec_binary = CONF.saml.xmlsec1_binary - idp_private_key = CONF.saml.keyfile - idp_public_key = CONF.saml.certfile - - # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file> - certificates = '%(idp_private_key)s,%(idp_public_key)s' % { - 'idp_public_key': idp_public_key, - 'idp_private_key': idp_private_key - } - - command_list = [xmlsec_binary, '--sign', '--privkey-pem', certificates, - '--id-attr:ID', 'Assertion'] - - file_path = None - try: - # NOTE(gyee): need to make the namespace prefixes explicit so - # they won't get reassigned when we wrap the assertion into - # SAML2 response - file_path = fileutils.write_to_tempfile(assertion.to_string( - nspair={'saml': saml2.NAMESPACE, - 'xmldsig': xmldsig.NAMESPACE})) - command_list.append(file_path) - stdout = subprocess.check_output(command_list, - stderr=subprocess.STDOUT) - except Exception as e: - msg = _LE('Error when signing assertion, reason: %(reason)s%(output)s') - LOG.error(msg, - {'reason': e, - 'output': ' ' + e.output if hasattr(e, 'output') else ''}) - raise exception.SAMLSigningError(reason=e) - finally: - try: - if file_path: - os.remove(file_path) - except OSError: - pass - - return saml2.create_class_from_xml_string(saml.Assertion, stdout) - - -class MetadataGenerator(object): - """A class for generating SAML IdP Metadata.""" - - def generate_metadata(self): - """Generate Identity Provider Metadata. - - Generate and format metadata into XML that can be exposed and - consumed by a federated Service Provider. - - :return: XML <EntityDescriptor> object. - :raises: keystone.exception.ValidationError: Raises if the required - config options aren't set. - - """ - self._ensure_required_values_present() - entity_descriptor = self._create_entity_descriptor() - entity_descriptor.idpsso_descriptor = ( - self._create_idp_sso_descriptor()) - return entity_descriptor - - def _create_entity_descriptor(self): - ed = md.EntityDescriptor() - ed.entity_id = CONF.saml.idp_entity_id - return ed - - def _create_idp_sso_descriptor(self): - - def get_cert(): - try: - return sigver.read_cert_from_file(CONF.saml.certfile, 'pem') - except (IOError, sigver.CertificateError) as e: - msg = _('Cannot open certificate %(cert_file)s. ' - 'Reason: %(reason)s') - msg = msg % {'cert_file': CONF.saml.certfile, 'reason': e} - LOG.error(msg) - raise IOError(msg) - - def key_descriptor(): - cert = get_cert() - return md.KeyDescriptor( - key_info=xmldsig.KeyInfo( - x509_data=xmldsig.X509Data( - x509_certificate=xmldsig.X509Certificate(text=cert) - ) - ), use='signing' - ) - - def single_sign_on_service(): - idp_sso_endpoint = CONF.saml.idp_sso_endpoint - return md.SingleSignOnService( - binding=saml2.BINDING_URI, - location=idp_sso_endpoint) - - def organization(): - name = md.OrganizationName(lang=CONF.saml.idp_lang, - text=CONF.saml.idp_organization_name) - display_name = md.OrganizationDisplayName( - lang=CONF.saml.idp_lang, - text=CONF.saml.idp_organization_display_name) - url = md.OrganizationURL(lang=CONF.saml.idp_lang, - text=CONF.saml.idp_organization_url) - - return md.Organization( - organization_display_name=display_name, - organization_url=url, organization_name=name) - - def contact_person(): - company = md.Company(text=CONF.saml.idp_contact_company) - given_name = md.GivenName(text=CONF.saml.idp_contact_name) - surname = md.SurName(text=CONF.saml.idp_contact_surname) - email = md.EmailAddress(text=CONF.saml.idp_contact_email) - telephone = md.TelephoneNumber( - text=CONF.saml.idp_contact_telephone) - contact_type = CONF.saml.idp_contact_type - - return md.ContactPerson( - company=company, given_name=given_name, sur_name=surname, - email_address=email, telephone_number=telephone, - contact_type=contact_type) - - def name_id_format(): - return md.NameIDFormat(text=saml.NAMEID_FORMAT_TRANSIENT) - - idpsso = md.IDPSSODescriptor() - idpsso.protocol_support_enumeration = samlp.NAMESPACE - idpsso.key_descriptor = key_descriptor() - idpsso.single_sign_on_service = single_sign_on_service() - idpsso.name_id_format = name_id_format() - if self._check_organization_values(): - idpsso.organization = organization() - if self._check_contact_person_values(): - idpsso.contact_person = contact_person() - return idpsso - - def _ensure_required_values_present(self): - """Ensure idp_sso_endpoint and idp_entity_id have values.""" - - if CONF.saml.idp_entity_id is None: - msg = _('Ensure configuration option idp_entity_id is set.') - raise exception.ValidationError(msg) - if CONF.saml.idp_sso_endpoint is None: - msg = _('Ensure configuration option idp_sso_endpoint is set.') - raise exception.ValidationError(msg) - - def _check_contact_person_values(self): - """Determine if contact information is included in metadata.""" - - # Check if we should include contact information - params = [CONF.saml.idp_contact_company, - CONF.saml.idp_contact_name, - CONF.saml.idp_contact_surname, - CONF.saml.idp_contact_email, - CONF.saml.idp_contact_telephone] - for value in params: - if value is None: - return False - - # Check if contact type is an invalid value - valid_type_values = ['technical', 'other', 'support', 'administrative', - 'billing'] - if CONF.saml.idp_contact_type not in valid_type_values: - msg = _('idp_contact_type must be one of: [technical, other, ' - 'support, administrative or billing.') - raise exception.ValidationError(msg) - return True - - def _check_organization_values(self): - """Determine if organization information is included in metadata.""" - - params = [CONF.saml.idp_organization_name, - CONF.saml.idp_organization_display_name, - CONF.saml.idp_organization_url] - for value in params: - if value is None: - return False - return True - - -class ECPGenerator(object): - """A class for generating an ECP assertion.""" - - @staticmethod - def generate_ecp(saml_assertion, relay_state_prefix): - ecp_generator = ECPGenerator() - header = ecp_generator._create_header(relay_state_prefix) - body = ecp_generator._create_body(saml_assertion) - envelope = soapenv.Envelope(header=header, body=body) - return envelope - - def _create_header(self, relay_state_prefix): - relay_state_text = relay_state_prefix + uuid.uuid4().hex - relay_state = ecp.RelayState(actor=client_base.ACTOR, - must_understand='1', - text=relay_state_text) - header = soapenv.Header() - header.extension_elements = ( - [saml2.element_to_extension_element(relay_state)]) - return header - - def _create_body(self, saml_assertion): - body = soapenv.Body() - body.extension_elements = ( - [saml2.element_to_extension_element(saml_assertion)]) - return body diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/federation/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/federation/migrate_repo/migrate.cfg deleted file mode 100644 index 464ab62b..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=federation - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/001_add_identity_provider_table.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/001_add_identity_provider_table.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/001_add_identity_provider_table.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/002_add_mapping_tables.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/002_add_mapping_tables.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/002_add_mapping_tables.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/003_mapping_id_nullable_false.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/003_mapping_id_nullable_false.py deleted file mode 100644 index 8ce8c6fa..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/003_mapping_id_nullable_false.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2014 Mirantis.inc -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/004_add_remote_id_column.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/004_add_remote_id_column.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/004_add_remote_id_column.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/005_add_service_provider_table.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/005_add_service_provider_table.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/005_add_service_provider_table.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/006_fixup_service_provider_attributes.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/006_fixup_service_provider_attributes.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/006_fixup_service_provider_attributes.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/007_add_remote_id_table.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/007_add_remote_id_table.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/007_add_remote_id_table.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/008_add_relay_state_to_sp.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/008_add_relay_state_to_sp.py deleted file mode 100644 index d9b24a00..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/008_add_relay_state_to_sp.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='federation') diff --git a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/federation/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/federation/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/federation/routers.py b/keystone-moon/keystone/contrib/federation/routers.py deleted file mode 100644 index d5857ca6..00000000 --- a/keystone-moon/keystone/contrib/federation/routers.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class FederationExtension(wsgi.Middleware): - - def __init__(self, *args, **kwargs): - super(FederationExtension, self).__init__(*args, **kwargs) - msg = _("Remove federation_extension from the paste pipeline, the " - "federation extension is now always available. Update the " - "[pipeline:api_v3] section in keystone-paste.ini accordingly, " - "as it will be removed in the O release.") - versionutils.report_deprecated_feature(LOG, msg) diff --git a/keystone-moon/keystone/contrib/federation/schema.py b/keystone-moon/keystone/contrib/federation/schema.py deleted file mode 100644 index 17818a98..00000000 --- a/keystone-moon/keystone/contrib/federation/schema.py +++ /dev/null @@ -1,79 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.common import validation -from keystone.common.validation import parameter_types - - -basic_property_id = { - 'type': 'object', - 'properties': { - 'id': { - 'type': 'string' - } - }, - 'required': ['id'], - 'additionalProperties': False -} - -saml_create = { - 'type': 'object', - 'properties': { - 'identity': { - 'type': 'object', - 'properties': { - 'token': basic_property_id, - 'methods': { - 'type': 'array' - } - }, - 'required': ['token'], - 'additionalProperties': False - }, - 'scope': { - 'type': 'object', - 'properties': { - 'service_provider': basic_property_id - }, - 'required': ['service_provider'], - 'additionalProperties': False - }, - }, - 'required': ['identity', 'scope'], - 'additionalProperties': False -} - -_service_provider_properties = { - # NOTE(rodrigods): The database accepts URLs with 256 as max length, - # but parameter_types.url uses 225 as max length. - 'auth_url': parameter_types.url, - 'sp_url': parameter_types.url, - 'description': validation.nullable(parameter_types.description), - 'enabled': parameter_types.boolean, - 'relay_state_prefix': validation.nullable(parameter_types.description) -} - -service_provider_create = { - 'type': 'object', - 'properties': _service_provider_properties, - # NOTE(rodrigods): 'id' is not required since it is passed in the URL - 'required': ['auth_url', 'sp_url'], - 'additionalProperties': False -} - -service_provider_update = { - 'type': 'object', - 'properties': _service_provider_properties, - # Make sure at least one property is being updated - 'minProperties': 1, - 'additionalProperties': False -} diff --git a/keystone-moon/keystone/contrib/federation/utils.py b/keystone-moon/keystone/contrib/federation/utils.py deleted file mode 100644 index bde19cfd..00000000 --- a/keystone-moon/keystone/contrib/federation/utils.py +++ /dev/null @@ -1,776 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Utilities for Federation Extension.""" - -import ast -import re - -import jsonschema -from oslo_config import cfg -from oslo_log import log -from oslo_utils import timeutils -import six - -from keystone import exception -from keystone.i18n import _, _LW - - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - - -MAPPING_SCHEMA = { - "type": "object", - "required": ['rules'], - "properties": { - "rules": { - "minItems": 1, - "type": "array", - "items": { - "type": "object", - "required": ['local', 'remote'], - "additionalProperties": False, - "properties": { - "local": { - "type": "array" - }, - "remote": { - "minItems": 1, - "type": "array", - "items": { - "type": "object", - "oneOf": [ - {"$ref": "#/definitions/empty"}, - {"$ref": "#/definitions/any_one_of"}, - {"$ref": "#/definitions/not_any_of"}, - {"$ref": "#/definitions/blacklist"}, - {"$ref": "#/definitions/whitelist"} - ], - } - } - } - } - } - }, - "definitions": { - "empty": { - "type": "object", - "required": ['type'], - "properties": { - "type": { - "type": "string" - }, - }, - "additionalProperties": False, - }, - "any_one_of": { - "type": "object", - "additionalProperties": False, - "required": ['type', 'any_one_of'], - "properties": { - "type": { - "type": "string" - }, - "any_one_of": { - "type": "array" - }, - "regex": { - "type": "boolean" - } - } - }, - "not_any_of": { - "type": "object", - "additionalProperties": False, - "required": ['type', 'not_any_of'], - "properties": { - "type": { - "type": "string" - }, - "not_any_of": { - "type": "array" - }, - "regex": { - "type": "boolean" - } - } - }, - "blacklist": { - "type": "object", - "additionalProperties": False, - "required": ['type', 'blacklist'], - "properties": { - "type": { - "type": "string" - }, - "blacklist": { - "type": "array" - } - } - }, - "whitelist": { - "type": "object", - "additionalProperties": False, - "required": ['type', 'whitelist'], - "properties": { - "type": { - "type": "string" - }, - "whitelist": { - "type": "array" - } - } - } - } -} - - -class DirectMaps(object): - """An abstraction around the remote matches. - - Each match is treated internally as a list. - """ - - def __init__(self): - self._matches = [] - - def add(self, values): - """Adds a matched value to the list of matches. - - :param list value: the match to save - - """ - self._matches.append(values) - - def __getitem__(self, idx): - """Used by Python when executing ``''.format(*DirectMaps())``.""" - value = self._matches[idx] - if isinstance(value, list) and len(value) == 1: - return value[0] - else: - return value - - -def validate_mapping_structure(ref): - v = jsonschema.Draft4Validator(MAPPING_SCHEMA) - - messages = '' - for error in sorted(v.iter_errors(ref), key=str): - messages = messages + error.message + "\n" - - if messages: - raise exception.ValidationError(messages) - - -def validate_expiration(token_ref): - if timeutils.utcnow() > token_ref.expires: - raise exception.Unauthorized(_('Federation token is expired')) - - -def validate_groups_cardinality(group_ids, mapping_id): - """Check if groups list is non-empty. - - :param group_ids: list of group ids - :type group_ids: list of str - - :raises exception.MissingGroups: if ``group_ids`` cardinality is 0 - - """ - if not group_ids: - raise exception.MissingGroups(mapping_id=mapping_id) - - -def get_remote_id_parameter(protocol): - # NOTE(marco-fargetta): Since we support any protocol ID, we attempt to - # retrieve the remote_id_attribute of the protocol ID. If it's not - # registered in the config, then register the option and try again. - # This allows the user to register protocols other than oidc and saml2. - remote_id_parameter = None - try: - remote_id_parameter = CONF[protocol]['remote_id_attribute'] - except AttributeError: - CONF.register_opt(cfg.StrOpt('remote_id_attribute'), - group=protocol) - try: - remote_id_parameter = CONF[protocol]['remote_id_attribute'] - except AttributeError: - pass - if not remote_id_parameter: - LOG.debug('Cannot find "remote_id_attribute" in configuration ' - 'group %s. Trying default location in ' - 'group federation.', protocol) - remote_id_parameter = CONF.federation.remote_id_attribute - - return remote_id_parameter - - -def validate_idp(idp, protocol, assertion): - """Validate the IdP providing the assertion is registered for the mapping. - """ - - remote_id_parameter = get_remote_id_parameter(protocol) - if not remote_id_parameter or not idp['remote_ids']: - LOG.debug('Impossible to identify the IdP %s ', idp['id']) - # If nothing is defined, the administrator may want to - # allow the mapping of every IdP - return - try: - idp_remote_identifier = assertion[remote_id_parameter] - except KeyError: - msg = _('Could not find Identity Provider identifier in ' - 'environment') - raise exception.ValidationError(msg) - if idp_remote_identifier not in idp['remote_ids']: - msg = _('Incoming identity provider identifier not included ' - 'among the accepted identifiers.') - raise exception.Forbidden(msg) - - -def validate_groups_in_backend(group_ids, mapping_id, identity_api): - """Iterate over group ids and make sure they are present in the backend/ - - This call is not transactional. - :param group_ids: IDs of the groups to be checked - :type group_ids: list of str - - :param mapping_id: id of the mapping used for this operation - :type mapping_id: str - - :param identity_api: Identity Manager object used for communication with - backend - :type identity_api: identity.Manager - - :raises: exception.MappedGroupNotFound - - """ - for group_id in group_ids: - try: - identity_api.get_group(group_id) - except exception.GroupNotFound: - raise exception.MappedGroupNotFound( - group_id=group_id, mapping_id=mapping_id) - - -def validate_groups(group_ids, mapping_id, identity_api): - """Check group ids cardinality and check their existence in the backend. - - This call is not transactional. - :param group_ids: IDs of the groups to be checked - :type group_ids: list of str - - :param mapping_id: id of the mapping used for this operation - :type mapping_id: str - - :param identity_api: Identity Manager object used for communication with - backend - :type identity_api: identity.Manager - - :raises: exception.MappedGroupNotFound - :raises: exception.MissingGroups - - """ - validate_groups_cardinality(group_ids, mapping_id) - validate_groups_in_backend(group_ids, mapping_id, identity_api) - - -# TODO(marek-denis): Optimize this function, so the number of calls to the -# backend are minimized. -def transform_to_group_ids(group_names, mapping_id, - identity_api, resource_api): - """Transform groups identitified by name/domain to their ids - - Function accepts list of groups identified by a name and domain giving - a list of group ids in return. - - Example of group_names parameter:: - - [ - { - "name": "group_name", - "domain": { - "id": "domain_id" - }, - }, - { - "name": "group_name_2", - "domain": { - "name": "domain_name" - } - } - ] - - :param group_names: list of group identified by name and its domain. - :type group_names: list - - :param mapping_id: id of the mapping used for mapping assertion into - local credentials - :type mapping_id: str - - :param identity_api: identity_api object - :param resource_api: resource manager object - - :returns: generator object with group ids - - :raises: excepton.MappedGroupNotFound: in case asked group doesn't - exist in the backend. - - """ - - def resolve_domain(domain): - """Return domain id. - - Input is a dictionary with a domain identified either by a ``id`` or a - ``name``. In the latter case system will attempt to fetch domain object - from the backend. - - :returns: domain's id - :rtype: str - - """ - domain_id = (domain.get('id') or - resource_api.get_domain_by_name( - domain.get('name')).get('id')) - return domain_id - - for group in group_names: - try: - group_dict = identity_api.get_group_by_name( - group['name'], resolve_domain(group['domain'])) - yield group_dict['id'] - except exception.GroupNotFound: - LOG.debug('Skip mapping group %s; has no entry in the backend', - group['name']) - - -def get_assertion_params_from_env(context): - LOG.debug('Environment variables: %s', context['environment']) - prefix = CONF.federation.assertion_prefix - for k, v in list(context['environment'].items()): - if k.startswith(prefix): - yield (k, v) - - -class UserType(object): - """User mapping type.""" - EPHEMERAL = 'ephemeral' - LOCAL = 'local' - - -class RuleProcessor(object): - """A class to process assertions and mapping rules.""" - - class _EvalType(object): - """Mapping rule evaluation types.""" - ANY_ONE_OF = 'any_one_of' - NOT_ANY_OF = 'not_any_of' - BLACKLIST = 'blacklist' - WHITELIST = 'whitelist' - - def __init__(self, rules): - """Initialize RuleProcessor. - - Example rules can be found at: - :class:`keystone.tests.mapping_fixtures` - - :param rules: rules from a mapping - :type rules: dict - - """ - - self.rules = rules - - def process(self, assertion_data): - """Transform assertion to a dictionary of user name and group ids - based on mapping rules. - - This function will iterate through the mapping rules to find - assertions that are valid. - - :param assertion_data: an assertion containing values from an IdP - :type assertion_data: dict - - Example assertion_data:: - - { - 'Email': 'testacct@example.com', - 'UserName': 'testacct', - 'FirstName': 'Test', - 'LastName': 'Account', - 'orgPersonType': 'Tester' - } - - :returns: dictionary with user and group_ids - - The expected return structure is:: - - { - 'name': 'foobar', - 'group_ids': ['abc123', 'def456'], - 'group_names': [ - { - 'name': 'group_name_1', - 'domain': { - 'name': 'domain1' - } - }, - { - 'name': 'group_name_1_1', - 'domain': { - 'name': 'domain1' - } - }, - { - 'name': 'group_name_2', - 'domain': { - 'id': 'xyz132' - } - } - ] - } - - """ - - # Assertions will come in as string key-value pairs, and will use a - # semi-colon to indicate multiple values, i.e. groups. - # This will create a new dictionary where the values are arrays, and - # any multiple values are stored in the arrays. - LOG.debug('assertion data: %s', assertion_data) - assertion = {n: v.split(';') for n, v in assertion_data.items() - if isinstance(v, six.string_types)} - LOG.debug('assertion: %s', assertion) - identity_values = [] - - LOG.debug('rules: %s', self.rules) - for rule in self.rules: - direct_maps = self._verify_all_requirements(rule['remote'], - assertion) - - # If the compare comes back as None, then the rule did not apply - # to the assertion data, go on to the next rule - if direct_maps is None: - continue - - # If there are no direct mappings, then add the local mapping - # directly to the array of saved values. However, if there is - # a direct mapping, then perform variable replacement. - if not direct_maps: - identity_values += rule['local'] - else: - for local in rule['local']: - new_local = self._update_local_mapping(local, direct_maps) - identity_values.append(new_local) - - LOG.debug('identity_values: %s', identity_values) - mapped_properties = self._transform(identity_values) - LOG.debug('mapped_properties: %s', mapped_properties) - return mapped_properties - - def _transform(self, identity_values): - """Transform local mappings, to an easier to understand format. - - Transform the incoming array to generate the return value for - the process function. Generating content for Keystone tokens will - be easier if some pre-processing is done at this level. - - :param identity_values: local mapping from valid evaluations - :type identity_values: array of dict - - Example identity_values:: - - [ - { - 'group': {'id': '0cd5e9'}, - 'user': { - 'email': 'bob@example.com' - }, - }, - { - 'groups': ['member', 'admin', tester'], - 'domain': { - 'name': 'default_domain' - } - } - ] - - :returns: dictionary with user name, group_ids and group_names. - :rtype: dict - - """ - - def extract_groups(groups_by_domain): - for groups in list(groups_by_domain.values()): - for group in list({g['name']: g for g in groups}.values()): - yield group - - def normalize_user(user): - """Parse and validate user mapping.""" - - user_type = user.get('type') - - if user_type and user_type not in (UserType.EPHEMERAL, - UserType.LOCAL): - msg = _("User type %s not supported") % user_type - raise exception.ValidationError(msg) - - if user_type is None: - user_type = user['type'] = UserType.EPHEMERAL - - if user_type == UserType.EPHEMERAL: - user['domain'] = { - 'id': CONF.federation.federated_domain_name - } - - # initialize the group_ids as a set to eliminate duplicates - user = {} - group_ids = set() - group_names = list() - groups_by_domain = dict() - - for identity_value in identity_values: - if 'user' in identity_value: - # if a mapping outputs more than one user name, log it - if user: - LOG.warning(_LW('Ignoring user name')) - else: - user = identity_value.get('user') - if 'group' in identity_value: - group = identity_value['group'] - if 'id' in group: - group_ids.add(group['id']) - elif 'name' in group: - domain = (group['domain'].get('name') or - group['domain'].get('id')) - groups_by_domain.setdefault(domain, list()).append(group) - group_names.extend(extract_groups(groups_by_domain)) - if 'groups' in identity_value: - if 'domain' not in identity_value: - msg = _("Invalid rule: %(identity_value)s. Both 'groups' " - "and 'domain' keywords must be specified.") - msg = msg % {'identity_value': identity_value} - raise exception.ValidationError(msg) - # In this case, identity_value['groups'] is a string - # representation of a list, and we want a real list. This is - # due to the way we do direct mapping substitutions today (see - # function _update_local_mapping() ) - try: - group_names_list = ast.literal_eval( - identity_value['groups']) - except ValueError: - group_names_list = [identity_value['groups']] - domain = identity_value['domain'] - group_dicts = [{'name': name, 'domain': domain} for name in - group_names_list] - - group_names.extend(group_dicts) - - normalize_user(user) - - return {'user': user, - 'group_ids': list(group_ids), - 'group_names': group_names} - - def _update_local_mapping(self, local, direct_maps): - """Replace any {0}, {1} ... values with data from the assertion. - - :param local: local mapping reference that needs to be updated - :type local: dict - :param direct_maps: identity values used to update local - :type direct_maps: keystone.contrib.federation.utils.DirectMaps - - Example local:: - - {'user': {'name': '{0} {1}', 'email': '{2}'}} - - Example direct_maps:: - - ['Bob', 'Thompson', 'bob@example.com'] - - :returns: new local mapping reference with replaced values. - - The expected return structure is:: - - {'user': {'name': 'Bob Thompson', 'email': 'bob@example.org'}} - - """ - - LOG.debug('direct_maps: %s', direct_maps) - LOG.debug('local: %s', local) - new = {} - for k, v in local.items(): - if isinstance(v, dict): - new_value = self._update_local_mapping(v, direct_maps) - else: - new_value = v.format(*direct_maps) - new[k] = new_value - return new - - def _verify_all_requirements(self, requirements, assertion): - """Go through the remote requirements of a rule, and compare against - the assertion. - - If a value of ``None`` is returned, the rule with this assertion - doesn't apply. - If an array of zero length is returned, then there are no direct - mappings to be performed, but the rule is valid. - Otherwise, then it will first attempt to filter the values according - to blacklist or whitelist rules and finally return the values in - order, to be directly mapped. - - :param requirements: list of remote requirements from rules - :type requirements: list - - Example requirements:: - - [ - { - "type": "UserName" - }, - { - "type": "orgPersonType", - "any_one_of": [ - "Customer" - ] - }, - { - "type": "ADFS_GROUPS", - "whitelist": [ - "g1", "g2", "g3", "g4" - ] - } - ] - - :param assertion: dict of attributes from an IdP - :type assertion: dict - - Example assertion:: - - { - 'UserName': ['testacct'], - 'LastName': ['Account'], - 'orgPersonType': ['Tester'], - 'Email': ['testacct@example.com'], - 'FirstName': ['Test'], - 'ADFS_GROUPS': ['g1', 'g2'] - } - - :returns: identity values used to update local - :rtype: keystone.contrib.federation.utils.DirectMaps or None - - """ - - direct_maps = DirectMaps() - - for requirement in requirements: - requirement_type = requirement['type'] - direct_map_values = assertion.get(requirement_type) - regex = requirement.get('regex', False) - - if not direct_map_values: - return None - - any_one_values = requirement.get(self._EvalType.ANY_ONE_OF) - if any_one_values is not None: - if self._evaluate_requirement(any_one_values, - direct_map_values, - self._EvalType.ANY_ONE_OF, - regex): - continue - else: - return None - - not_any_values = requirement.get(self._EvalType.NOT_ANY_OF) - if not_any_values is not None: - if self._evaluate_requirement(not_any_values, - direct_map_values, - self._EvalType.NOT_ANY_OF, - regex): - continue - else: - return None - - # If 'any_one_of' or 'not_any_of' are not found, then values are - # within 'type'. Attempt to find that 'type' within the assertion, - # and filter these values if 'whitelist' or 'blacklist' is set. - blacklisted_values = requirement.get(self._EvalType.BLACKLIST) - whitelisted_values = requirement.get(self._EvalType.WHITELIST) - - # If a blacklist or whitelist is used, we want to map to the - # whole list instead of just its values separately. - if blacklisted_values is not None: - direct_map_values = [v for v in direct_map_values - if v not in blacklisted_values] - elif whitelisted_values is not None: - direct_map_values = [v for v in direct_map_values - if v in whitelisted_values] - - direct_maps.add(direct_map_values) - - LOG.debug('updating a direct mapping: %s', direct_map_values) - - return direct_maps - - def _evaluate_values_by_regex(self, values, assertion_values): - for value in values: - for assertion_value in assertion_values: - if re.search(value, assertion_value): - return True - return False - - def _evaluate_requirement(self, values, assertion_values, - eval_type, regex): - """Evaluate the incoming requirement and assertion. - - If the requirement type does not exist in the assertion data, then - return False. If regex is specified, then compare the values and - assertion values. Otherwise, grab the intersection of the values - and use that to compare against the evaluation type. - - :param values: list of allowed values, defined in the requirement - :type values: list - :param assertion_values: The values from the assertion to evaluate - :type assertion_values: list/string - :param eval_type: determine how to evaluate requirements - :type eval_type: string - :param regex: perform evaluation with regex - :type regex: boolean - - :returns: boolean, whether requirement is valid or not. - - """ - if regex: - any_match = self._evaluate_values_by_regex(values, - assertion_values) - else: - any_match = bool(set(values).intersection(set(assertion_values))) - if any_match and eval_type == self._EvalType.ANY_ONE_OF: - return True - if not any_match and eval_type == self._EvalType.NOT_ANY_OF: - return True - - return False - - -def assert_enabled_identity_provider(federation_api, idp_id): - identity_provider = federation_api.get_idp(idp_id) - if identity_provider.get('enabled') is not True: - msg = _('Identity Provider %(idp)s is disabled') % {'idp': idp_id} - LOG.debug(msg) - raise exception.Forbidden(msg) - - -def assert_enabled_service_provider_object(service_provider): - if service_provider.get('enabled') is not True: - sp_id = service_provider['id'] - msg = _('Service Provider %(sp)s is disabled') % {'sp': sp_id} - LOG.debug(msg) - raise exception.Forbidden(msg) diff --git a/keystone-moon/keystone/contrib/moon/__init__.py b/keystone-moon/keystone/contrib/moon/__init__.py deleted file mode 100644 index 6a96782e..00000000 --- a/keystone-moon/keystone/contrib/moon/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from keystone.contrib.moon.core import * # noqa -from keystone.contrib.moon import controllers # noqa -from keystone.contrib.moon import routers # noqa
\ No newline at end of file diff --git a/keystone-moon/keystone/contrib/moon/algorithms.py b/keystone-moon/keystone/contrib/moon/algorithms.py deleted file mode 100644 index 2f997efc..00000000 --- a/keystone-moon/keystone/contrib/moon/algorithms.py +++ /dev/null @@ -1,78 +0,0 @@ -import itertools -from oslo_log import log -LOG = log.getLogger(__name__) - - -""" an example of authz_buffer, sub_meta_rule_dict, rule_dict -authz_buffer = { - 'subject_uuid': xxx, - 'object_uuid': yyy, - 'action_uuid': zzz, - 'subject_attributes': { - 'subject_category1': [], - 'subject_category2': [], - ... - 'subject_categoryn': [] - }, - 'object_attributes': {}, - 'action_attributes': {}, -} - -sub_meta_rule_dict = { - "subject_categories": ["subject_security_level", "aaa"], - "action_categories": ["computing_action"], - "object_categories": ["object_security_level"], -} - -rule_dict = [ - ["high", "vm_admin", "medium", True], - ["high", "vm_admin", "low", True], - ["medium", "vm_admin", "low", True], - ["high", "vm_access", "high", True], - ["high", "vm_access", "medium", True], - ["high", "vm_access", "low", True], - ["medium", "vm_access", "medium", True], - ["medium", "vm_access", "low", True], - ["low", "vm_access", "low", True] -] -""" - - -def inclusion(authz_buffer, sub_meta_rule_dict, rule_list): - _cat = [] - for subject_cat in sub_meta_rule_dict['subject_categories']: - if subject_cat in authz_buffer['subject_assignments']: - _cat.append(authz_buffer['subject_assignments'][subject_cat]) - for action_cat in sub_meta_rule_dict['action_categories']: - if action_cat in authz_buffer['action_assignments']: - _cat.append(authz_buffer['action_assignments'][action_cat]) - for object_cat in sub_meta_rule_dict['object_categories']: - if object_cat in authz_buffer['object_assignments']: - _cat.append(authz_buffer['object_assignments'][object_cat]) - - for _element in itertools.product(*_cat): - # Add the boolean at the end - _element = list(_element) - _element.append(True) - if _element in rule_list: - return True - - return False - - -def comparison(authz_buffer, sub_meta_rule_dict, rule_list): - return - - -def all_true(decision_buffer): - for _rule in decision_buffer: - if decision_buffer[_rule] == False: - return False - return True - - -def one_true(decision_buffer): - for _rule in decision_buffer: - if decision_buffer[_rule] == True: - return True - return False diff --git a/keystone-moon/keystone/contrib/moon/backends/__init__.py b/keystone-moon/keystone/contrib/moon/backends/__init__.py deleted file mode 100644 index 237bdc3e..00000000 --- a/keystone-moon/keystone/contrib/moon/backends/__init__.py +++ /dev/null @@ -1,97 +0,0 @@ - -""" -intra_extensions = { - intra_extension_id1: { - name: xxx, - model: yyy, - description: zzz}, - intra_extension_id2: {...}, - ... -} - -tenants = { - tenant_id1: { - name: xxx, - description: yyy, - intra_authz_extension_id: zzz, - intra_admin_extension_id: zzz, - }, - tenant_id2: {...}, - ... -} - ---------------- for each intra-extension ----------------- - -subject_categories = { - subject_category_id1: { - name: xxx, - description: yyy}, - subject_category_id2: {...}, - ... -} - -subjects = { - subject_id1: { - name: xxx, - description: yyy, - ...}, - subject_id2: {...}, - ... -} - -subject_scopes = { - subject_category_id1: { - subject_scope_id1: { - name: xxx, - description: aaa}, - subject_scope_id2: { - name: yyy, - description: bbb}, - ...}, - subject_scope_id3: { - ...} - subject_category_id2: {...}, - ... -} - -subject_assignments = { - subject_id1: { - subject_category_id1: [subject_scope_id1, subject_scope_id2, ...], - subject_category_id2: [subject_scope_id3, subject_scope_id4, ...], - ... - }, - subject_id2: { - subject_category_id1: [subject_scope_id1, subject_scope_id2, ...], - subject_category_id2: [subject_scope_id3, subject_scope_id4, ...], - ... - }, - ... -} - -aggregation_algorithm = { - aggregation_algorithm_id: { - name: xxx, - description: yyy - } - } - -sub_meta_rules = { - sub_meta_rule_id_1: { - "name": xxx, - "algorithm": yyy, - "subject_categories": [subject_category_id1, subject_category_id2,...], - "object_categories": [object_category_id1, object_category_id2,...], - "action_categories": [action_category_id1, action_category_id2,...] - sub_meta_rule_id_2: {...}, - ... -} - -rules = { - sub_meta_rule_id1: { - rule_id1: [subject_scope1, subject_scope2, ..., action_scope1, ..., object_scope1, ... ], - rule_id2: [subject_scope3, subject_scope4, ..., action_scope3, ..., object_scope3, ... ], - rule_id3: [thomas, write, admin.subjects] - ...}, - sub_meta_rule_id2: { }, - ...} -"""
\ No newline at end of file diff --git a/keystone-moon/keystone/contrib/moon/backends/flat.py b/keystone-moon/keystone/contrib/moon/backends/flat.py deleted file mode 100644 index 05c1850b..00000000 --- a/keystone-moon/keystone/contrib/moon/backends/flat.py +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from uuid import uuid4 -import os -import logging -import re -import time -from keystone import config -from oslo_log import log -# from keystone.contrib.moon.core import SuperExtensionDriver -from keystone.contrib.moon.core import LogDriver - - -CONF = config.CONF - - -class LogConnector(LogDriver): - - AUTHZ_FILE = '/var/log/moon/authz.log' - SYS_FILE = '/var/log/moon/system.log' - TIME_FORMAT = '%Y-%m-%d-%H:%M:%S' - - def __init__(self): - # Fixme (dthom): when logging from an other class, the %appname% in the event - # is always keystone.contrib.moon.backends.flat - super(LogConnector, self).__init__() - - self.SYS_LOG = logging.getLogger(__name__) - if not len(self.SYS_LOG.handlers): - fh = logging.FileHandler(self.SYS_FILE) - fh.setLevel(logging.DEBUG) - formatter = logging.Formatter('%(asctime)s ------ %(message)s', self.TIME_FORMAT) - fh.setFormatter(formatter) - self.SYS_LOG.addHandler(fh) - - self.AUTHZ_LOG = logging.getLogger("authz") - if not len(self.AUTHZ_LOG.handlers): - fh = logging.FileHandler(self.AUTHZ_FILE) - fh.setLevel(logging.WARNING) - formatter = logging.Formatter('%(asctime)s ------ %(message)s', self.TIME_FORMAT) - fh.setFormatter(formatter) - self.AUTHZ_LOG.addHandler(fh) - - def authz(self, message): - self.AUTHZ_LOG.warn(message) - - def debug(self, message): - self.SYS_LOG.debug(message) - - def info(self, message): - self.SYS_LOG.info(message) - - def warning(self, message): - self.SYS_LOG.warning(message) - - def error(self, message): - self.SYS_LOG.error(message) - - def critical(self, message): - self.SYS_LOG.critical(message) - - def get_logs(self, logger="authz", event_number=None, time_from=None, time_to=None, filter_str=None): - if logger == "authz": - _logs = open(self.AUTHZ_FILE).readlines() - else: - _logs = open(self.SYS_FILE).readlines() - if filter_str: - _logs = filter(lambda x: filter_str in x, _logs) - if time_from: - if isinstance(time_from, basestring): - time_from = time.strptime(time_from.split(" ")[0], self.TIME_FORMAT) - try: - __logs = [] - for log in _logs: - _log = time.strptime(log.split(" ")[0], self.TIME_FORMAT) - if time_from <= _log: - __logs.append(log) - _logs = __logs - except ValueError: - self.error("Time format error") - if time_to: - try: - if isinstance(time_to, basestring): - time_to = time.strptime(time_to.split(" ")[0], self.TIME_FORMAT) - __logs = [] - for log in _logs: - _log = time.strptime(log.split(" ")[0], self.TIME_FORMAT) - if time_to >= _log: - __logs.append(log) - _logs = __logs - except ValueError: - self.error("Time format error") - if event_number: - _logs = _logs[-event_number:] - return list(_logs) - - -# class SuperExtensionConnector(SuperExtensionDriver): -# -# def __init__(self): -# super(SuperExtensionConnector, self).__init__() -# # Super_Extension is loaded every time the server is started -# self.__uuid = uuid4().hex -# # self.__super_extension = Extension() -# _policy_abs_dir = os.path.join(CONF.moon.super_extension_directory, 'policy') -# # self.__super_extension.load_from_json(_policy_abs_dir) -# -# def get_super_extensions(self): -# return None -# -# def admin(self, sub, obj, act): -# # return self.__super_extension.authz(sub, obj, act) -# return True diff --git a/keystone-moon/keystone/contrib/moon/backends/memory.py b/keystone-moon/keystone/contrib/moon/backends/memory.py deleted file mode 100644 index b9fbb622..00000000 --- a/keystone-moon/keystone/contrib/moon/backends/memory.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from uuid import uuid4 -from glob import glob -import os -import json -from keystone import config -from keystone.contrib.moon.core import ConfigurationDriver -from oslo_log import log -import hashlib - -CONF = config.CONF -LOG = log.getLogger(__name__) - - -class ConfigurationConnector(ConfigurationDriver): - - def __init__(self): - super(ConfigurationConnector, self).__init__() - self.aggregation_algorithms_dict = dict() - self.aggregation_algorithms_dict[hashlib.sha224("all_true").hexdigest()[:32]] = \ - {'name': 'all_true', 'description': 'all rules must match'} - self.aggregation_algorithms_dict[hashlib.sha224("one_true").hexdigest()[:32]] = \ - {'name': 'one_true', 'description': 'only one rule has to match'} - self.sub_meta_rule_algorithms_dict = dict() - self.sub_meta_rule_algorithms_dict[hashlib.sha224("inclusion").hexdigest()[:32]] = \ - {'name': 'inclusion', 'description': 'inclusion'} - self.sub_meta_rule_algorithms_dict[hashlib.sha224("comparison").hexdigest()[:32]] = \ - {'name': 'comparison', 'description': 'comparison'} - - def get_policy_templates_dict(self): - """ - :return: { - template_id1: {name: template_name, description: template_description}, - template_id2: {name: template_name, description: template_description}, - ... - } - """ - nodes = glob(os.path.join(CONF.moon.policy_directory, "*")) - templates = dict() - for node in nodes: - try: - metadata = json.load(open(os.path.join(node, "metadata.json"))) - except IOError: - # Note (asteroide): it's not a true policy directory, so we forgive it - continue - templates[os.path.basename(node)] = dict() - templates[os.path.basename(node)]["name"] = metadata["name"] - templates[os.path.basename(node)]["description"] = metadata["description"] - return templates - - def get_aggregation_algorithms_dict(self): - return self.aggregation_algorithms_dict - - def get_sub_meta_rule_algorithms_dict(self): - return self.sub_meta_rule_algorithms_dict diff --git a/keystone-moon/keystone/contrib/moon/backends/sql.py b/keystone-moon/keystone/contrib/moon/backends/sql.py deleted file mode 100644 index 1ddb474e..00000000 --- a/keystone-moon/keystone/contrib/moon/backends/sql.py +++ /dev/null @@ -1,1105 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -import six -from uuid import uuid4 -import copy - -from keystone import config -from oslo_log import log -from keystone.common import sql -from keystone import exception -from keystone.contrib.moon.exception import * -from oslo_serialization import jsonutils -from keystone.contrib.moon import IntraExtensionDriver -from keystone.contrib.moon import TenantDriver - -from sqlalchemy.orm.exc import UnmappedInstanceError -# from keystone.contrib.moon import InterExtensionDriver - -CONF = config.CONF -LOG = log.getLogger(__name__) - - -class IntraExtension(sql.ModelBase, sql.DictBase): - __tablename__ = 'intra_extensions' - attributes = ['id', 'intra_extension'] - id = sql.Column(sql.String(64), primary_key=True) - intra_extension = sql.Column(sql.JsonBlob(), nullable=True) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class Tenant(sql.ModelBase, sql.DictBase): - __tablename__ = 'tenants' - attributes = ['id', 'tenant'] - id = sql.Column(sql.String(64), primary_key=True, nullable=False) - tenant = sql.Column(sql.JsonBlob(), nullable=True) - - @classmethod - def from_dict(cls, d): - """Override parent from_dict() method with a different implementation. - """ - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - """ - """ - return dict(six.iteritems(self)) - - -class SubjectCategory(sql.ModelBase, sql.DictBase): - __tablename__ = 'subject_categories' - attributes = ['id', 'subject_category', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - subject_category = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class ObjectCategory(sql.ModelBase, sql.DictBase): - __tablename__ = 'object_categories' - attributes = ['id', 'object_category', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - object_category = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class ActionCategory(sql.ModelBase, sql.DictBase): - __tablename__ = 'action_categories' - attributes = ['id', 'action_category', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - action_category = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class Subject(sql.ModelBase, sql.DictBase): - __tablename__ = 'subjects' - attributes = ['id', 'subject', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - subject = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class Object(sql.ModelBase, sql.DictBase): - __tablename__ = 'objects' - attributes = ['id', 'object', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - object = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class Action(sql.ModelBase, sql.DictBase): - __tablename__ = 'actions' - attributes = ['id', 'action', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - action = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class SubjectScope(sql.ModelBase, sql.DictBase): - __tablename__ = 'subject_scopes' - attributes = ['id', 'subject_scope', 'intra_extension_id', 'subject_category_id'] - id = sql.Column(sql.String(64), primary_key=True) - subject_scope = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - subject_category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class ObjectScope(sql.ModelBase, sql.DictBase): - __tablename__ = 'object_scopes' - attributes = ['id', 'object_scope', 'intra_extension_id', 'object_category_id'] - id = sql.Column(sql.String(64), primary_key=True) - object_scope = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - object_category_id = sql.Column(sql.ForeignKey("object_categories.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class ActionScope(sql.ModelBase, sql.DictBase): - __tablename__ = 'action_scopes' - attributes = ['id', 'action_scope', 'intra_extension_id', 'action_category'] - id = sql.Column(sql.String(64), primary_key=True) - action_scope = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - action_category_id = sql.Column(sql.ForeignKey("action_categories.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class SubjectAssignment(sql.ModelBase, sql.DictBase): - __tablename__ = 'subject_assignments' - attributes = ['id', 'subject_assignment', 'intra_extension_id', 'subject_id', 'subject_category_id'] - id = sql.Column(sql.String(64), primary_key=True) - subject_assignment = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - subject_id = sql.Column(sql.ForeignKey("subjects.id"), nullable=False) - subject_category_id = sql.Column(sql.ForeignKey("subject_categories.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class ObjectAssignment(sql.ModelBase, sql.DictBase): - __tablename__ = 'object_assignments' - attributes = ['id', 'object_assignment', 'intra_extension_id', 'object_id', 'object_category_id'] - id = sql.Column(sql.String(64), primary_key=True) - object_assignment = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - object_id = sql.Column(sql.ForeignKey("objects.id"), nullable=False) - object_category_id = sql.Column(sql.ForeignKey("object_categories.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class ActionAssignment(sql.ModelBase, sql.DictBase): - __tablename__ = 'action_assignments' - attributes = ['id', 'action_assignment', 'intra_extension_id', 'action_id', 'action_category_id'] - id = sql.Column(sql.String(64), primary_key=True) - action_assignment = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - action_id = sql.Column(sql.ForeignKey("actions.id"), nullable=False) - action_category_id = sql.Column(sql.ForeignKey("action_categories.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class SubMetaRule(sql.ModelBase, sql.DictBase): - __tablename__ = 'sub_meta_rules' - attributes = ['id', 'sub_meta_rule', 'intra_extension_id'] - id = sql.Column(sql.String(64), primary_key=True) - sub_meta_rule = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -class Rule(sql.ModelBase, sql.DictBase): - __tablename__ = 'rules' - attributes = ['id', 'rule', 'intra_extension_id', 'sub_meta_rule_id'] - id = sql.Column(sql.String(64), primary_key=True) - rule = sql.Column(sql.JsonBlob(), nullable=True) - intra_extension_id = sql.Column(sql.ForeignKey("intra_extensions.id"), nullable=False) - sub_meta_rule_id = sql.Column(sql.ForeignKey("sub_meta_rules.id"), nullable=False) - - @classmethod - def from_dict(cls, d): - new_d = d.copy() - return cls(**new_d) - - def to_dict(self): - return dict(six.iteritems(self)) - - -__all_objects__ = ( - SubjectScope, - ObjectScope, - ActionScope, - SubjectAssignment, - ObjectAssignment, - ActionAssignment, - SubMetaRule, - SubjectCategory, - ObjectCategory, - ActionCategory, - Subject, - Object, - Action, - Rule, -) - - -class TenantConnector(TenantDriver): - - @staticmethod - def __update_dict(base, update): - """Update a dict only if values are not None - - :param base: dict to update - :param update: updates for the base dict - :return: None - """ - for key in update: - if type(update[key]) is not None: - base[key] = update[key] - - def get_tenants_dict(self): - with sql.session_for_read() as session: - query = session.query(Tenant) - tenants = query.all() - return {tenant.id: tenant.tenant for tenant in tenants} - - def add_tenant_dict(self, tenant_id, tenant_dict): - with sql.session_for_write() as session: - new_ref = Tenant.from_dict( - { - "id": tenant_id, - 'tenant': tenant_dict - } - ) - session.add(new_ref) - return {new_ref.id: new_ref.tenant} - - def del_tenant(self, tenant_id): - with sql.session_for_write() as session: - query = session.query(Tenant) - query = query.filter_by(id=tenant_id) - tenant = query.first() - session.delete(tenant) - - def set_tenant_dict(self, tenant_id, tenant_dict): - with sql.session_for_write() as session: - query = session.query(Tenant) - query = query.filter_by(id=tenant_id) - ref = query.first() - tenant_dict_orig = dict(ref.tenant) - self.__update_dict(tenant_dict_orig, tenant_dict) - setattr(ref, "tenant", tenant_dict_orig) - return {ref.id: tenant_dict_orig} - - -class IntraExtensionConnector(IntraExtensionDriver): - - # IntraExtension functions - - def get_intra_extensions_dict(self): - with sql.session_for_read() as session: - query = session.query(IntraExtension) - ref_list = query.all() - return {_ref.id: _ref.intra_extension for _ref in ref_list} - - def del_intra_extension(self, intra_extension_id): - with sql.session_for_write() as session: - ref = session.query(IntraExtension).get(intra_extension_id) - # Must delete all references to that IntraExtension - for _object in __all_objects__: - query = session.query(_object) - query = query.filter_by(intra_extension_id=intra_extension_id) - _refs = query.all() - for _ref in _refs: - session.delete(_ref) - # session.flush() - session.delete(ref) - - def set_intra_extension_dict(self, intra_extension_id, intra_extension_dict): - with sql.session_for_write() as session: - query = session.query(IntraExtension) - query = query.filter_by(id=intra_extension_id) - ref = query.first() - new_intra_extension = IntraExtension.from_dict( - { - "id": intra_extension_id, - 'intra_extension': intra_extension_dict, - } - ) - if not ref: - session.add(new_intra_extension) - ref = new_intra_extension - else: - for attr in IntraExtension.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_intra_extension, attr)) - # session.flush() - return IntraExtension.to_dict(ref) - - # Getter and Setter for subject_category - - def get_subject_categories_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(SubjectCategory) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.subject_category for _ref in ref_list} - - def set_subject_category_dict(self, intra_extension_id, subject_category_id, subject_category_dict): - with sql.session_for_write() as session: - query = session.query(SubjectCategory) - query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_category_id) - ref = query.first() - new_ref = SubjectCategory.from_dict( - { - "id": subject_category_id, - 'subject_category': subject_category_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in SubjectCategory.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # # session.flush() - return {subject_category_id: SubjectCategory.to_dict(ref)['subject_category']} - - def del_subject_category(self, intra_extension_id, subject_category_id): - with sql.session_for_write() as session: - query = session.query(SubjectCategory) - query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_category_id) - ref = query.first() - self.del_subject_assignment(intra_extension_id, None, None, None) - session.delete(ref) - - # Getter and Setter for object_category - - def get_object_categories_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(ObjectCategory) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.object_category for _ref in ref_list} - - def set_object_category_dict(self, intra_extension_id, object_category_id, object_category_dict): - with sql.session_for_write() as session: - query = session.query(ObjectCategory) - query = query.filter_by(intra_extension_id=intra_extension_id, id=object_category_id) - ref = query.first() - new_ref = ObjectCategory.from_dict( - { - "id": object_category_id, - 'object_category': object_category_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in ObjectCategory.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {object_category_id: ObjectCategory.to_dict(ref)['object_category']} - - def del_object_category(self, intra_extension_id, object_category_id): - with sql.session_for_write() as session: - query = session.query(ObjectCategory) - query = query.filter_by(intra_extension_id=intra_extension_id, id=object_category_id) - ref = query.first() - self.del_object_assignment(intra_extension_id, None, None, None) - session.delete(ref) - - # Getter and Setter for action_category - - def get_action_categories_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(ActionCategory) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.action_category for _ref in ref_list} - - def set_action_category_dict(self, intra_extension_id, action_category_id, action_category_dict): - with sql.session_for_write() as session: - query = session.query(ActionCategory) - query = query.filter_by(intra_extension_id=intra_extension_id, id=action_category_id) - ref = query.first() - new_ref = ActionCategory.from_dict( - { - "id": action_category_id, - 'action_category': action_category_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in ActionCategory.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {action_category_id: ActionCategory.to_dict(ref)['action_category']} - - def del_action_category(self, intra_extension_id, action_category_id): - with sql.session_for_write() as session: - query = session.query(ActionCategory) - query = query.filter_by(intra_extension_id=intra_extension_id, id=action_category_id) - ref = query.first() - self.del_action_assignment(intra_extension_id, None, None, None) - session.delete(ref) - - # Perimeter - - def get_subjects_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(Subject) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.subject for _ref in ref_list} - - def set_subject_dict(self, intra_extension_id, subject_id, subject_dict): - with sql.session_for_write() as session: - query = session.query(Subject) - query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_id) - ref = query.first() - # if 'id' in subject_dict: - # subject_dict['id'] = subject_id - new_ref = Subject.from_dict( - { - "id": subject_id, - 'subject': subject_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Subject.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {subject_id: Subject.to_dict(ref)['subject']} - - def del_subject(self, intra_extension_id, subject_id): - with sql.session_for_write() as session: - query = session.query(Subject) - query = query.filter_by(intra_extension_id=intra_extension_id, id=subject_id) - ref = query.first() - session.delete(ref) - - def get_objects_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(Object) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.object for _ref in ref_list} - - def set_object_dict(self, intra_extension_id, object_id, object_dict): - with sql.session_for_write() as session: - query = session.query(Object) - query = query.filter_by(intra_extension_id=intra_extension_id, id=object_id) - ref = query.first() - new_ref = Object.from_dict( - { - "id": object_id, - 'object': object_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Object.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {object_id: Object.to_dict(ref)['object']} - - def del_object(self, intra_extension_id, object_id): - with sql.session_for_write() as session: - query = session.query(Object) - query = query.filter_by(intra_extension_id=intra_extension_id, id=object_id) - ref = query.first() - session.delete(ref) - - def get_actions_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(Action) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.action for _ref in ref_list} - - def set_action_dict(self, intra_extension_id, action_id, action_dict): - with sql.session_for_write() as session: - query = session.query(Action) - query = query.filter_by(intra_extension_id=intra_extension_id, id=action_id) - ref = query.first() - new_ref = Action.from_dict( - { - "id": action_id, - 'action': action_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Action.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {action_id: Action.to_dict(ref)['action']} - - def del_action(self, intra_extension_id, action_id): - with sql.session_for_write() as session: - query = session.query(Action) - query = query.filter_by(intra_extension_id=intra_extension_id, id=action_id) - ref = query.first() - session.delete(ref) - - # Getter and Setter for subject_scope - - def get_subject_scopes_dict(self, intra_extension_id, subject_category_id): - with sql.session_for_read() as session: - query = session.query(SubjectScope) - query = query.filter_by(intra_extension_id=intra_extension_id, subject_category_id=subject_category_id) - ref_list = query.all() - return {_ref.id: _ref.subject_scope for _ref in ref_list} - - def set_subject_scope_dict(self, intra_extension_id, subject_category_id, subject_scope_id, subject_scope_dict): - with sql.session_for_write() as session: - query = session.query(SubjectScope) - query = query.filter_by(intra_extension_id=intra_extension_id, subject_category_id=subject_category_id, id=subject_scope_id) - ref = query.first() - new_ref = SubjectScope.from_dict( - { - "id": subject_scope_id, - 'subject_scope': subject_scope_dict, - 'intra_extension_id': intra_extension_id, - 'subject_category_id': subject_category_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Subject.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {subject_scope_id: SubjectScope.to_dict(ref)['subject_scope']} - - def del_subject_scope(self, intra_extension_id, subject_category_id, subject_scope_id): - with sql.session_for_write() as session: - query = session.query(SubjectScope) - if not subject_category_id or not subject_scope_id: - query = query.filter_by(intra_extension_id=intra_extension_id) - for ref in query.all(): - session.delete(ref) - else: - query = query.filter_by(intra_extension_id=intra_extension_id, subject_category_id=subject_category_id, id=subject_scope_id) - ref = query.first() - session.delete(ref) - - # Getter and Setter for object_category_scope - - def get_object_scopes_dict(self, intra_extension_id, object_category_id): - with sql.session_for_read() as session: - query = session.query(ObjectScope) - query = query.filter_by(intra_extension_id=intra_extension_id, object_category_id=object_category_id) - ref_list = query.all() - return {_ref.id: _ref.object_scope for _ref in ref_list} - - def set_object_scope_dict(self, intra_extension_id, object_category_id, object_scope_id, object_scope_dict): - with sql.session_for_write() as session: - query = session.query(ObjectScope) - query = query.filter_by(intra_extension_id=intra_extension_id, object_category_id=object_category_id, id=object_scope_id) - ref = query.first() - new_ref = ObjectScope.from_dict( - { - "id": object_scope_id, - 'object_scope': object_scope_dict, - 'intra_extension_id': intra_extension_id, - 'object_category_id': object_category_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Object.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {object_scope_id: ObjectScope.to_dict(ref)['object_scope']} - - def del_object_scope(self, intra_extension_id, object_category_id, object_scope_id): - with sql.session_for_write() as session: - query = session.query(ObjectScope) - if not object_category_id or not object_scope_id: - query = query.filter_by(intra_extension_id=intra_extension_id) - for ref in query.all(): - session.delete(ref) - else: - query = query.filter_by(intra_extension_id=intra_extension_id, object_category_id=object_category_id, id=object_scope_id) - ref = query.first() - session.delete(ref) - - # Getter and Setter for action_scope - - def get_action_scopes_dict(self, intra_extension_id, action_category_id): - with sql.session_for_read() as session: - query = session.query(ActionScope) - query = query.filter_by(intra_extension_id=intra_extension_id, action_category_id=action_category_id) - ref_list = query.all() - return {_ref.id: _ref.action_scope for _ref in ref_list} - - def set_action_scope_dict(self, intra_extension_id, action_category_id, action_scope_id, action_scope_dict): - with sql.session_for_write() as session: - query = session.query(ActionScope) - query = query.filter_by(intra_extension_id=intra_extension_id, action_category_id=action_category_id, id=action_scope_id) - ref = query.first() - new_ref = ActionScope.from_dict( - { - "id": action_scope_id, - 'action_scope': action_scope_dict, - 'intra_extension_id': intra_extension_id, - 'action_category_id': action_category_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Action.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {action_scope_id: ActionScope.to_dict(ref)['action_scope']} - - def del_action_scope(self, intra_extension_id, action_category_id, action_scope_id): - with sql.session_for_write() as session: - query = session.query(ActionScope) - if not action_category_id or not action_scope_id: - query = query.filter_by(intra_extension_id=intra_extension_id) - for ref in query.all(): - session.delete(ref) - else: - query = query.filter_by(intra_extension_id=intra_extension_id, action_category_id=action_category_id, id=action_scope_id) - ref = query.first() - session.delete(ref) - - # Getter and Setter for subject_category_assignment - - def get_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id): - with sql.session_for_read() as session: - query = session.query(SubjectAssignment) - if not subject_id or not subject_category_id or not subject_category_id: - query = query.filter_by(intra_extension_id=intra_extension_id) - ref = query.all() - return ref - else: - query = query.filter_by(intra_extension_id=intra_extension_id, subject_id=subject_id, subject_category_id=subject_category_id) - ref = query.first() - if not ref: - return list() - return list(ref.subject_assignment) - - def set_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id, subject_assignment_list=[]): - with sql.session_for_write() as session: - query = session.query(SubjectAssignment) - query = query.filter_by(intra_extension_id=intra_extension_id, subject_id=subject_id, subject_category_id=subject_category_id) - ref = query.first() - new_ref = SubjectAssignment.from_dict( - { - "id": uuid4().hex, - 'subject_assignment': subject_assignment_list, - 'intra_extension_id': intra_extension_id, - 'subject_id': subject_id, - 'subject_category_id': subject_category_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in SubjectAssignment.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return subject_assignment_list - - def add_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - new_subject_assignment_list = self.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id) - if subject_scope_id not in new_subject_assignment_list: - new_subject_assignment_list.append(subject_scope_id) - return self.set_subject_assignment_list(intra_extension_id, subject_id, subject_category_id, new_subject_assignment_list) - - def del_subject_assignment(self, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - if not subject_id or not subject_category_id or not subject_category_id: - with sql.session_for_write() as session: - for ref in self.get_subject_assignment_list(intra_extension_id, None, None): - session.delete(ref) - session.flush() - return - new_subject_assignment_list = self.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id) - new_subject_assignment_list.remove(subject_scope_id) - return self.set_subject_assignment_list(intra_extension_id, subject_id, subject_category_id, new_subject_assignment_list) - - # Getter and Setter for object_category_assignment - - def get_object_assignment_list(self, intra_extension_id, object_id, object_category_id): - with sql.session_for_read() as session: - query = session.query(ObjectAssignment) - if not object_id or not object_category_id or not object_category_id: - query = query.filter_by(intra_extension_id=intra_extension_id) - ref = query.all() - return ref - else: - query = query.filter_by(intra_extension_id=intra_extension_id, object_id=object_id, object_category_id=object_category_id) - ref = query.first() - if not ref: - return list() - return list(ref.object_assignment) - - def set_object_assignment_list(self, intra_extension_id, object_id, object_category_id, object_assignment_list=[]): - with sql.session_for_write() as session: - query = session.query(ObjectAssignment) - query = query.filter_by(intra_extension_id=intra_extension_id, object_id=object_id, object_category_id=object_category_id) - ref = query.first() - new_ref = ObjectAssignment.from_dict( - { - "id": uuid4().hex, - 'object_assignment': object_assignment_list, - 'intra_extension_id': intra_extension_id, - 'object_id': object_id, - 'object_category_id': object_category_id - } - ) - if not ref: - session.add(new_ref) - else: - for attr in ObjectAssignment.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return self.get_object_assignment_list(intra_extension_id, object_id, object_category_id) - - def add_object_assignment_list(self, intra_extension_id, object_id, object_category_id, object_scope_id): - new_object_assignment_list = self.get_object_assignment_list(intra_extension_id, object_id, object_category_id) - if object_scope_id not in new_object_assignment_list: - new_object_assignment_list.append(object_scope_id) - return self.set_object_assignment_list(intra_extension_id, object_id, object_category_id, new_object_assignment_list) - - def del_object_assignment(self, intra_extension_id, object_id, object_category_id, object_scope_id): - if not object_id or not object_category_id or not object_category_id: - with sql.session_for_write() as session: - for ref in self.get_object_assignment_list(intra_extension_id, None, None): - session.delete(ref) - session.flush() - return - new_object_assignment_list = self.get_object_assignment_list(intra_extension_id, object_id, object_category_id) - new_object_assignment_list.remove(object_scope_id) - return self.set_object_assignment_list(intra_extension_id, object_id, object_category_id, new_object_assignment_list) - - # Getter and Setter for action_category_assignment - - def get_action_assignment_list(self, intra_extension_id, action_id, action_category_id): - with sql.session_for_read() as session: - query = session.query(ActionAssignment) - if not action_id or not action_category_id or not action_category_id: - query = query.filter_by(intra_extension_id=intra_extension_id) - ref = query.all() - return ref - else: - query = query.filter_by(intra_extension_id=intra_extension_id, action_id=action_id, action_category_id=action_category_id) - ref = query.first() - if not ref: - return list() - return list(ref.action_assignment) - - def set_action_assignment_list(self, intra_extension_id, action_id, action_category_id, action_assignment_list=[]): - with sql.session_for_write() as session: - query = session.query(ActionAssignment) - query = query.filter_by(intra_extension_id=intra_extension_id, action_id=action_id, action_category_id=action_category_id) - ref = query.first() - new_ref = ActionAssignment.from_dict( - { - "id": uuid4().hex, - 'action_assignment': action_assignment_list, - 'intra_extension_id': intra_extension_id, - 'action_id': action_id, - 'action_category_id': action_category_id - } - ) - if not ref: - session.add(new_ref) - else: - for attr in ActionAssignment.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return self.get_action_assignment_list(intra_extension_id, action_id, action_category_id) - - def add_action_assignment_list(self, intra_extension_id, action_id, action_category_id, action_scope_id): - new_action_assignment_list = self.get_action_assignment_list(intra_extension_id, action_id, action_category_id) - if action_scope_id not in new_action_assignment_list: - new_action_assignment_list.append(action_scope_id) - return self.set_action_assignment_list(intra_extension_id, action_id, action_category_id, new_action_assignment_list) - - def del_action_assignment(self, intra_extension_id, action_id, action_category_id, action_scope_id): - if not action_id or not action_category_id or not action_category_id: - with sql.session_for_write() as session: - for ref in self.get_action_assignment_list(intra_extension_id, None, None): - session.delete(ref) - session.flush() - return - new_action_assignment_list = self.get_action_assignment_list(intra_extension_id, action_id, action_category_id) - new_action_assignment_list.remove(action_scope_id) - return self.set_action_assignment_list(intra_extension_id, action_id, action_category_id, new_action_assignment_list) - - # Getter and Setter for sub_meta_rule - - def get_aggregation_algorithm_id(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(IntraExtension) - query = query.filter_by(id=intra_extension_id) - ref = query.first() - try: - return {"aggregation_algorithm": ref.intra_extension["aggregation_algorithm"]} - except KeyError: - return "" - - def set_aggregation_algorithm_id(self, intra_extension_id, aggregation_algorithm_id): - with sql.session_for_write() as session: - query = session.query(IntraExtension) - query = query.filter_by(id=intra_extension_id) - ref = query.first() - intra_extension_dict = dict(ref.intra_extension) - intra_extension_dict["aggregation_algorithm"] = aggregation_algorithm_id - setattr(ref, "intra_extension", intra_extension_dict) - # session.flush() - return {"aggregation_algorithm": ref.intra_extension["aggregation_algorithm"]} - - def del_aggregation_algorithm(self, intra_extension_id): - with sql.session_for_write() as session: - query = session.query(IntraExtension) - query = query.filter_by(id=intra_extension_id) - ref = query.first() - intra_extension_dict = dict(ref.intra_extension) - intra_extension_dict["aggregation_algorithm"] = "" - setattr(ref, "intra_extension", intra_extension_dict) - return self.get_aggregation_algorithm_id(intra_extension_id) - - # Getter and Setter for sub_meta_rule - - def get_sub_meta_rules_dict(self, intra_extension_id): - with sql.session_for_read() as session: - query = session.query(SubMetaRule) - query = query.filter_by(intra_extension_id=intra_extension_id) - ref_list = query.all() - return {_ref.id: _ref.sub_meta_rule for _ref in ref_list} - - def set_sub_meta_rule_dict(self, intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict): - with sql.session_for_write() as session: - query = session.query(SubMetaRule) - query = query.filter_by(intra_extension_id=intra_extension_id, id=sub_meta_rule_id) - ref = query.first() - new_ref = SubMetaRule.from_dict( - { - "id": sub_meta_rule_id, - 'sub_meta_rule': sub_meta_rule_dict, - 'intra_extension_id': intra_extension_id - } - ) - if not ref: - session.add(new_ref) - else: - _sub_meta_rule_dict = dict(ref.sub_meta_rule) - _sub_meta_rule_dict.update(sub_meta_rule_dict) - setattr(new_ref, "sub_meta_rule", _sub_meta_rule_dict) - for attr in SubMetaRule.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return self.get_sub_meta_rules_dict(intra_extension_id) - - def del_sub_meta_rule(self, intra_extension_id, sub_meta_rule_id): - with sql.session_for_write() as session: - query = session.query(SubMetaRule) - query = query.filter_by(intra_extension_id=intra_extension_id, id=sub_meta_rule_id) - ref = query.first() - session.delete(ref) - - # Getter and Setter for rules - - def get_rules_dict(self, intra_extension_id, sub_meta_rule_id): - with sql.session_for_read() as session: - query = session.query(Rule) - query = query.filter_by(intra_extension_id=intra_extension_id, sub_meta_rule_id=sub_meta_rule_id) - ref_list = query.all() - return {_ref.id: _ref.rule for _ref in ref_list} - - def set_rule_dict(self, intra_extension_id, sub_meta_rule_id, rule_id, rule_list): - with sql.session_for_write() as session: - query = session.query(Rule) - query = query.filter_by(intra_extension_id=intra_extension_id, sub_meta_rule_id=sub_meta_rule_id, id=rule_id) - ref = query.first() - new_ref = Rule.from_dict( - { - "id": rule_id, - 'rule': rule_list, - 'intra_extension_id': intra_extension_id, - 'sub_meta_rule_id': sub_meta_rule_id - } - ) - if not ref: - session.add(new_ref) - ref = new_ref - else: - for attr in Rule.attributes: - if attr != 'id': - setattr(ref, attr, getattr(new_ref, attr)) - # session.flush() - return {rule_id: ref.rule} - - def del_rule(self, intra_extension_id, sub_meta_rule_id, rule_id): - with sql.session_for_write() as session: - query = session.query(Rule) - query = query.filter_by(intra_extension_id=intra_extension_id, sub_meta_rule_id=sub_meta_rule_id, id=rule_id) - ref = query.first() - session.delete(ref) - - -# class InterExtension(sql.ModelBase, sql.DictBase): -# __tablename__ = 'inter_extension' -# attributes = [ -# 'id', -# 'requesting_intra_extension_id', -# 'requested_intra_extension_id', -# 'virtual_entity_uuid', -# 'genre', -# 'description', -# ] -# id = sql.Column(sql.String(64), primary_key=True) -# requesting_intra_extension_id = sql.Column(sql.String(64)) -# requested_intra_extension_id = sql.Column(sql.String(64)) -# virtual_entity_uuid = sql.Column(sql.String(64)) -# genre = sql.Column(sql.String(64)) -# description = sql.Column(sql.Text()) -# -# @classmethod -# def from_dict(cls, d): -# """Override parent from_dict() method with a simpler implementation. -# """ -# new_d = d.copy() -# return cls(**new_d) -# -# def to_dict(self): -# """Override parent to_dict() method with a simpler implementation. -# """ -# return dict(six.iteritems(self)) -# -# -# class InterExtensionConnector(InterExtensionDriver): -# -# def get_inter_extensions(self): -# with sql.session_for_read() as session: -# query = session.query(InterExtension.id) -# interextensions = query.all() -# return [interextension.id for interextension in interextensions] -# -# def create_inter_extensions(self, inter_id, inter_extension): -# with sql.session_for_read() as session: -# ie_ref = InterExtension.from_dict(inter_extension) -# session.add(ie_ref) -# return InterExtension.to_dict(ie_ref) -# -# def get_inter_extension(self, uuid): -# with sql.session_for_read() as session: -# query = session.query(InterExtension) -# query = query.filter_by(id=uuid) -# ref = query.first() -# if not ref: -# raise exception.NotFound -# return ref.to_dict() -# -# def delete_inter_extensions(self, inter_extension_id): -# with sql.session_for_read() as session: -# ref = session.query(InterExtension).get(inter_extension_id) -# session.delete(ref) - diff --git a/keystone-moon/keystone/contrib/moon/controllers.py b/keystone-moon/keystone/contrib/moon/controllers.py deleted file mode 100644 index d3f1bfad..00000000 --- a/keystone-moon/keystone/contrib/moon/controllers.py +++ /dev/null @@ -1,917 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from keystone.common import controller -from keystone import config -from keystone import exception -from keystone.models import token_model -from keystone.contrib.moon.exception import * -from oslo_log import log -from uuid import uuid4 -import requests - - -CONF = config.CONF -LOG = log.getLogger(__name__) - - -@dependency.requires('configuration_api') -class Configuration(controller.V3Controller): - collection_name = 'configurations' - member_name = 'configuration' - - def __init__(self): - super(Configuration, self).__init__() - - def _get_user_id_from_token(self, token_id): - response = self.token_provider_api.validate_token(token_id) - token_ref = token_model.KeystoneToken(token_id=token_id, token_data=response) - return token_ref.get('user') - - @controller.protected() - def get_policy_templates(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - return self.configuration_api.get_policy_templates_dict(user_id) - - @controller.protected() - def get_aggregation_algorithms(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - return self.configuration_api.get_aggregation_algorithms_dict(user_id) - - @controller.protected() - def get_sub_meta_rule_algorithms(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - return self.configuration_api.get_sub_meta_rule_algorithms_dict(user_id) - - -@dependency.requires('tenant_api', 'resource_api') -class Tenants(controller.V3Controller): - - def __init__(self): - super(Tenants, self).__init__() - - def _get_user_id_from_token(self, token_id): - response = self.token_provider_api.validate_token(token_id) - token_ref = token_model.KeystoneToken(token_id=token_id, token_data=response) - return token_ref.get('user') - - @controller.protected() - def get_tenants(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - return self.tenant_api.get_tenants_dict(user_id) - - def __get_keystone_tenant_dict(self, tenant_id="", tenant_name="", tenant_description="", domain="default"): - tenants = self.resource_api.list_projects() - for tenant in tenants: - if tenant_id and tenant_id == tenant['id']: - return tenant - if tenant_name and tenant_name == tenant['name']: - return tenant - if not tenant_id: - tenant_id = uuid4().hex - if not tenant_name: - tenant_name = tenant_id - tenant = { - "id": tenant_id, - "name": tenant_name, - "description": tenant_description, - "enabled": True, - "domain_id": domain - } - keystone_tenant = self.resource_api.create_project(tenant["id"], tenant) - return keystone_tenant - - @controller.protected() - def add_tenant(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - k_tenant_dict = self.__get_keystone_tenant_dict( - tenant_name=kw.get('tenant_name'), - tenant_description=kw.get('tenant_description', kw.get('tenant_name')), - domain=kw.get('tenant_domain', "default"), - - ) - tenant_dict = dict() - tenant_dict['id'] = k_tenant_dict['id'] - tenant_dict['name'] = kw.get('tenant_name', None) - tenant_dict['description'] = kw.get('tenant_description', None) - tenant_dict['intra_authz_extension_id'] = kw.get('tenant_intra_authz_extension_id', None) - tenant_dict['intra_admin_extension_id'] = kw.get('tenant_intra_admin_extension_id', None) - return self.tenant_api.add_tenant_dict(user_id, tenant_dict['id'], tenant_dict) - - @controller.protected() - def get_tenant(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - tenant_id = kw.get('tenant_id', None) - return self.tenant_api.get_tenant_dict(user_id, tenant_id) - - @controller.protected() - def del_tenant(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - tenant_id = kw.get('tenant_id', None) - return self.tenant_api.del_tenant(user_id, tenant_id) - - @controller.protected() - def set_tenant(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - # Next line will raise an error if tenant doesn't exist - k_tenant_dict = self.resource_api.get_project(kw.get('tenant_id', None)) - tenant_id = kw.get('tenant_id', None) - tenant_dict = dict() - tenant_dict['name'] = k_tenant_dict.get('name', None) - if 'tenant_description' in kw: - tenant_dict['description'] = kw.get('tenant_description', None) - if 'tenant_intra_authz_extension_id' in kw: - tenant_dict['intra_authz_extension_id'] = kw.get('tenant_intra_authz_extension_id', None) - if 'tenant_intra_admin_extension_id' in kw: - tenant_dict['intra_admin_extension_id'] = kw.get('tenant_intra_admin_extension_id', None) - self.tenant_api.set_tenant_dict(user_id, tenant_id, tenant_dict) - - -def callback(self, context, prep_info, *args, **kwargs): - token_ref = "" - if context.get('token_id') is not None: - token_ref = token_model.KeystoneToken( - token_id=context['token_id'], - token_data=self.token_provider_api.validate_token( - context['token_id'])) - if not token_ref: - raise exception.Unauthorized - - -@dependency.requires('authz_api') -class Authz_v3(controller.V3Controller): - - def __init__(self): - super(Authz_v3, self).__init__() - - @controller.protected(callback) - def get_authz(self, context, tenant_id, subject_k_id, object_name, action_name): - try: - return self.authz_api.authz(tenant_id, subject_k_id, object_name, action_name) - except Exception as e: - return {'authz': False, 'comment': unicode(e)} - - -@dependency.requires('admin_api', 'root_api') -class IntraExtensions(controller.V3Controller): - collection_name = 'intra_extensions' - member_name = 'intra_extension' - - def __init__(self): - super(IntraExtensions, self).__init__() - - def _get_user_id_from_token(self, token_id): - response = self.token_provider_api.validate_token(token_id) - token_ref = token_model.KeystoneToken(token_id=token_id, token_data=response) - return token_ref.get('user')['id'] - - # IntraExtension functions - @controller.protected() - def get_intra_extensions(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - return self.admin_api.get_intra_extensions_dict(user_id) - - @controller.protected() - def add_intra_extension(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_dict = dict() - intra_extension_dict['name'] = kw.get('intra_extension_name', None) - intra_extension_dict['model'] = kw.get('intra_extension_model', None) - intra_extension_dict['genre'] = kw.get('intra_extension_genre', None) - intra_extension_dict['description'] = kw.get('intra_extension_description', None) - intra_extension_dict['subject_categories'] = kw.get('intra_extension_subject_categories', dict()) - intra_extension_dict['object_categories'] = kw.get('intra_extension_object_categories', dict()) - intra_extension_dict['action_categories'] = kw.get('intra_extension_action_categories', dict()) - intra_extension_dict['subjects'] = kw.get('intra_extension_subjects', dict()) - intra_extension_dict['objects'] = kw.get('intra_extension_objects', dict()) - intra_extension_dict['actions'] = kw.get('intra_extension_actions', dict()) - intra_extension_dict['subject_scopes'] = kw.get('intra_extension_subject_scopes', dict()) - intra_extension_dict['object_scopes'] = kw.get('intra_extension_object_scopes', dict()) - intra_extension_dict['action_scopes'] = kw.get('intra_extension_action_scopes', dict()) - intra_extension_dict['subject_assignments'] = kw.get('intra_extension_subject_assignments', dict()) - intra_extension_dict['object_assignments'] = kw.get('intra_extension_object_assignments', dict()) - intra_extension_dict['action_assignments'] = kw.get('intra_extension_action_assignments', dict()) - intra_extension_dict['aggregation_algorithm'] = kw.get('intra_extension_aggregation_algorithm', dict()) - intra_extension_dict['sub_meta_rules'] = kw.get('intra_extension_sub_meta_rules', dict()) - intra_extension_dict['rules'] = kw.get('intra_extension_rules', dict()) - ref = self.admin_api.load_intra_extension_dict(user_id, intra_extension_dict=intra_extension_dict) - return self.admin_api.populate_default_data(ref) - - @controller.protected() - def get_intra_extension(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_intra_extension_dict(user_id, intra_extension_id) - - @controller.protected() - def del_intra_extension(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - self.admin_api.del_intra_extension(user_id, intra_extension_id) - - @controller.protected() - def set_intra_extension(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - intra_extension_dict = dict() - intra_extension_dict['name'] = kw.get('intra_extension_name', None) - intra_extension_dict['model'] = kw.get('intra_extension_model', None) - intra_extension_dict['genre'] = kw.get('intra_extension_genre', None) - intra_extension_dict['description'] = kw.get('intra_extension_description', None) - return self.admin_api.set_intra_extension_dict(user_id, intra_extension_id, intra_extension_dict) - - @controller.protected() - def load_root_intra_extension(self, context, **kw): - self.root_api.load_root_intra_extension_dict() - - # Metadata functions - @controller.protected() - def get_subject_categories(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_subject_categories_dict(user_id, intra_extension_id) - - @controller.protected() - def add_subject_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_dict = dict() - subject_category_dict['name'] = kw.get('subject_category_name', None) - subject_category_dict['description'] = kw.get('subject_category_description', None) - return self.admin_api.add_subject_category_dict(user_id, intra_extension_id, subject_category_dict) - - @controller.protected() - def get_subject_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - return self.admin_api.get_subject_category_dict(user_id, intra_extension_id, subject_category_id) - - @controller.protected() - def del_subject_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - self.admin_api.del_subject_category(user_id, intra_extension_id, subject_category_id) - - @controller.protected() - def set_subject_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_category_dict = dict() - subject_category_dict['name'] = kw.get('subject_category_name', None) - subject_category_dict['description'] = kw.get('subject_category_description', None) - return self.admin_api.set_subject_category_dict(user_id, intra_extension_id, subject_category_id, subject_category_dict) - - @controller.protected() - def get_object_categories(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_object_categories_dict(user_id, intra_extension_id) - - @controller.protected() - def add_object_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_dict = dict() - object_category_dict['name'] = kw.get('object_category_name', None) - object_category_dict['description'] = kw.get('object_category_description', None) - return self.admin_api.add_object_category_dict(user_id, intra_extension_id, object_category_dict) - - @controller.protected() - def get_object_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - return self.admin_api.get_object_categories_dict(user_id, intra_extension_id, object_category_id) - - @controller.protected() - def del_object_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - self.admin_api.del_object_category(user_id, intra_extension_id, object_category_id) - - @controller.protected() - def set_object_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - object_category_dict = dict() - object_category_dict['name'] = kw.get('object_category_name', None) - object_category_dict['description'] = kw.get('object_category_description', None) - return self.admin_api.set_object_category_dict(user_id, intra_extension_id, object_category_id, object_category_dict) - - @controller.protected() - def get_action_categories(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_action_categories_dict(user_id, intra_extension_id) - - @controller.protected() - def add_action_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_dict = dict() - action_category_dict['name'] = kw.get('action_category_name', None) - action_category_dict['description'] = kw.get('action_category_description', None) - return self.admin_api.add_action_category_dict(user_id, intra_extension_id, action_category_dict) - - @controller.protected() - def get_action_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - return self.admin_api.get_action_categories_dict(user_id, intra_extension_id, action_category_id) - - @controller.protected() - def del_action_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - self.admin_api.del_action_category(user_id, intra_extension_id, action_category_id) - - @controller.protected() - def set_action_category(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - action_category_dict = dict() - action_category_dict['name'] = kw.get('action_category_name', None) - action_category_dict['description'] = kw.get('action_category_description', None) - return self.admin_api.set_action_category_dict(user_id, intra_extension_id, action_category_id, action_category_dict) - - # Perimeter functions - @controller.protected() - def get_subjects(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_subjects_dict(user_id, intra_extension_id) - - @controller.protected() - def add_subject(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_dict = dict() - subject_dict['name'] = kw.get('subject_name', None) - subject_dict['description'] = kw.get('subject_description', None) - subject_dict['password'] = kw.get('subject_password', None) - subject_dict['email'] = kw.get('subject_email', None) - return self.admin_api.add_subject_dict(user_id, intra_extension_id, subject_dict) - - @controller.protected() - def get_subject(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_id = kw.get('subject_id', None) - return self.admin_api.get_subject_dict(user_id, intra_extension_id, subject_id) - - @controller.protected() - def del_subject(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_id = kw.get('subject_id', None) - self.admin_api.del_subject(user_id, intra_extension_id, subject_id) - - @controller.protected() - def set_subject(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_id = kw.get('subject_id', None) - subject_dict = dict() - subject_dict['name'] = kw.get('subject_name', None) - subject_dict['description'] = kw.get('subject_description', None) - return self.admin_api.set_subject_dict(user_id, intra_extension_id, subject_id, subject_dict) - - @controller.protected() - def get_objects(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_objects_dict(user_id, intra_extension_id) - - @controller.protected() - def add_object(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_dict = dict() - object_dict['name'] = kw.get('object_name', None) - object_dict['description'] = kw.get('object_description', None) - return self.admin_api.add_object_dict(user_id, intra_extension_id, object_dict) - - @controller.protected() - def get_object(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_id = kw.get('object_id', None) - return self.admin_api.get_object_dict(user_id, intra_extension_id, object_id) - - @controller.protected() - def del_object(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_id = kw.get('object_id', None) - self.admin_api.del_object(user_id, intra_extension_id, object_id) - - @controller.protected() - def set_object(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_id = kw.get('object_id', None) - object_dict = dict() - object_dict['name'] = kw.get('object_name', None) - object_dict['description'] = kw.get('object_description', None) - return self.admin_api.set_object_dict(user_id, intra_extension_id, object_id, object_dict) - - @controller.protected() - def get_actions(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_actions_dict(user_id, intra_extension_id) - - @controller.protected() - def add_action(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_dict = dict() - action_dict['name'] = kw.get('action_name', None) - action_dict['description'] = kw.get('action_description', None) - return self.admin_api.add_action_dict(user_id, intra_extension_id, action_dict) - - @controller.protected() - def get_action(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_id = kw.get('action_id', None) - return self.admin_api.get_action_dict(user_id, intra_extension_id, action_id) - - @controller.protected() - def del_action(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_id = kw.get('action_id', None) - self.admin_api.del_action(user_id, intra_extension_id, action_id) - - @controller.protected() - def set_action(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_id = kw.get('action_id', None) - action_dict = dict() - action_dict['name'] = kw.get('action_name', None) - action_dict['description'] = kw.get('action_description', None) - return self.admin_api.set_action_dict(user_id, intra_extension_id, action_id, action_dict) - - # Scope functions - @controller.protected() - def get_subject_scopes(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - return self.admin_api.get_subject_scopes_dict(user_id, intra_extension_id, subject_category_id) - - @controller.protected() - def add_subject_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_scope_dict = dict() - subject_scope_dict['name'] = kw.get('subject_scope_name', None) - subject_scope_dict['description'] = kw.get('subject_scope_description', None) - return self.admin_api.add_subject_scope_dict(user_id, intra_extension_id, subject_category_id, subject_scope_dict) - - @controller.protected() - def get_subject_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_scope_id = kw.get('subject_scope_id', None) - return self.admin_api.get_subject_scope_dict(user_id, intra_extension_id, subject_category_id, subject_scope_id) - - @controller.protected() - def del_subject_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_scope_id = kw.get('subject_scope_id', None) - self.admin_api.del_subject_scope(user_id, intra_extension_id, subject_category_id, subject_scope_id) - - @controller.protected() - def set_subject_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_scope_id = kw.get('subject_scope_id', None) - subject_scope_dict = dict() - subject_scope_dict['name'] = kw.get('subject_scope_name', None) - subject_scope_dict['description'] = kw.get('subject_scope_description', None) - return self.admin_api.set_subject_scope_dict(user_id, intra_extension_id, subject_category_id, subject_scope_id, subject_scope_dict) - - @controller.protected() - def get_object_scopes(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - return self.admin_api.get_object_scopes_dict(user_id, intra_extension_id, object_category_id) - - @controller.protected() - def add_object_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - object_scope_dict = dict() - object_scope_dict['name'] = kw.get('object_scope_name', None) - object_scope_dict['description'] = kw.get('object_scope_description', None) - return self.admin_api.add_object_scope_dict(user_id, intra_extension_id, object_category_id, object_scope_dict) - - @controller.protected() - def get_object_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - object_scope_id = kw.get('object_scope_id', None) - return self.admin_api.get_object_scope_dict(user_id, intra_extension_id, object_category_id, object_scope_id) - - @controller.protected() - def del_object_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - object_scope_id = kw.get('object_scope_id', None) - self.admin_api.del_object_scope(user_id, intra_extension_id, object_category_id, object_scope_id) - - @controller.protected() - def set_object_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_category_id = kw.get('object_category_id', None) - object_scope_id = kw.get('object_scope_id', None) - object_scope_dict = dict() - object_scope_dict['name'] = kw.get('object_scope_name', None) - object_scope_dict['description'] = kw.get('object_scope_description', None) - return self.admin_api.set_object_scope_dict(user_id, intra_extension_id, object_category_id, object_scope_id, object_scope_dict) - - @controller.protected() - def get_action_scopes(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - return self.admin_api.get_action_scopes_dict(user_id, intra_extension_id, action_category_id) - - @controller.protected() - def add_action_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - action_scope_dict = dict() - action_scope_dict['name'] = kw.get('action_scope_name', None) - action_scope_dict['description'] = kw.get('action_scope_description', None) - return self.admin_api.add_action_scope_dict(user_id, intra_extension_id, action_category_id, action_scope_dict) - - @controller.protected() - def get_action_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - action_scope_id = kw.get('action_scope_id', None) - return self.admin_api.get_action_scope_dict(user_id, intra_extension_id, action_category_id, action_scope_id) - - @controller.protected() - def del_action_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - action_scope_id = kw.get('action_scope_id', None) - self.admin_api.del_action_scope(user_id, intra_extension_id, action_category_id, action_scope_id) - - @controller.protected() - def set_action_scope(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_category_id = kw.get('action_category_id', None) - action_scope_id = kw.get('action_scope_id', None) - action_scope_dict = dict() - action_scope_dict['name'] = kw.get('action_scope_name', None) - action_scope_dict['description'] = kw.get('action_scope_description', None) - return self.admin_api.set_action_scope_dict(user_id, intra_extension_id, action_category_id, action_scope_id, action_scope_dict) - - # Assignment functions - - @controller.protected() - def add_subject_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_id = kw.get('subject_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_scope_id = kw.get('subject_scope_id', None) - return self.admin_api.add_subject_assignment_list(user_id, intra_extension_id, subject_id, subject_category_id, subject_scope_id) - - @controller.protected() - def get_subject_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_id = kw.get('subject_id', None) - subject_category_id = kw.get('subject_category_id', None) - return self.admin_api.get_subject_assignment_list(user_id, intra_extension_id, subject_id, subject_category_id) - - @controller.protected() - def del_subject_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - subject_id = kw.get('subject_id', None) - subject_category_id = kw.get('subject_category_id', None) - subject_scope_id = kw.get('subject_scope_id', None) - self.admin_api.del_subject_assignment(user_id, intra_extension_id, subject_id, subject_category_id, subject_scope_id) - - @controller.protected() - def add_object_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_id = kw.get('object_id', None) - object_category_id = kw.get('object_category_id', None) - object_scope_id = kw.get('object_scope_id', None) - return self.admin_api.add_object_assignment_list(user_id, intra_extension_id, object_id, object_category_id, object_scope_id) - - @controller.protected() - def get_object_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_id = kw.get('object_id', None) - object_category_id = kw.get('object_category_id', None) - return self.admin_api.get_object_assignment_list(user_id, intra_extension_id, object_id, object_category_id) - - @controller.protected() - def del_object_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - object_id = kw.get('object_id', None) - object_category_id = kw.get('object_category_id', None) - object_scope_id = kw.get('object_scope_id', None) - self.admin_api.del_object_assignment(user_id, intra_extension_id, object_id, object_category_id, object_scope_id) - - @controller.protected() - def add_action_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_id = kw.get('action_id', None) - action_category_id = kw.get('action_category_id', None) - action_scope_id = kw.get('action_scope_id', None) - return self.admin_api.add_action_assignment_list(user_id, intra_extension_id, action_id, action_category_id, action_scope_id) - - @controller.protected() - def get_action_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_id = kw.get('action_id', None) - action_category_id = kw.get('action_category_id', None) - return self.admin_api.get_action_assignment_list(user_id, intra_extension_id, action_id, action_category_id) - - @controller.protected() - def del_action_assignment(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - action_id = kw.get('action_id', None) - action_category_id = kw.get('action_category_id', None) - action_scope_id = kw.get('action_scope_id', None) - self.admin_api.del_action_assignment(user_id, intra_extension_id, action_id, action_category_id, action_scope_id) - - # Metarule functions - - @controller.protected() - def get_aggregation_algorithm(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_aggregation_algorithm_id(user_id, intra_extension_id) - - @controller.protected() - def set_aggregation_algorithm(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - aggregation_algorithm_id = kw.get('aggregation_algorithm_id', None) - return self.admin_api.set_aggregation_algorithm_id(user_id, intra_extension_id, aggregation_algorithm_id) - - @controller.protected() - def get_sub_meta_rules(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - return self.admin_api.get_sub_meta_rules_dict(user_id, intra_extension_id) - - @controller.protected() - def add_sub_meta_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_dict = dict() - sub_meta_rule_dict['name'] = kw.get('sub_meta_rule_name', None) - sub_meta_rule_dict['algorithm'] = kw.get('sub_meta_rule_algorithm', None) - sub_meta_rule_dict['subject_categories'] = kw.get('sub_meta_rule_subject_categories', None) - sub_meta_rule_dict['object_categories'] = kw.get('sub_meta_rule_object_categories', None) - sub_meta_rule_dict['action_categories'] = kw.get('sub_meta_rule_action_categories', None) - return self.admin_api.add_sub_meta_rule_dict(user_id, intra_extension_id, sub_meta_rule_dict) - - @controller.protected() - def get_sub_meta_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - return self.admin_api.get_sub_meta_rule_dict(user_id, intra_extension_id, sub_meta_rule_id) - - @controller.protected() - def del_sub_meta_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - self.admin_api.del_sub_meta_rule(user_id, intra_extension_id, sub_meta_rule_id) - - @controller.protected() - def set_sub_meta_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - sub_meta_rule_dict = dict() - sub_meta_rule_dict['name'] = kw.get('sub_meta_rule_name', None) - sub_meta_rule_dict['algorithm'] = kw.get('sub_meta_rule_algorithm', None) - sub_meta_rule_dict['subject_categories'] = kw.get('sub_meta_rule_subject_categories', None) - sub_meta_rule_dict['object_categories'] = kw.get('sub_meta_rule_object_categories', None) - sub_meta_rule_dict['action_categories'] = kw.get('sub_meta_rule_action_categories', None) - return self.admin_api.set_sub_meta_rule_dict(user_id, intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict) - - # Rules functions - @controller.protected() - def get_rules(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - return self.admin_api.get_rules_dict(user_id, intra_extension_id, sub_meta_rule_id) - - @controller.protected() - def add_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - subject_category_list = kw.get('subject_categories', []) - object_category_list = kw.get('object_categories', []) - action_category_list = kw.get('action_categories', []) - enabled_bool = kw.get('enabled', True) - rule_list = subject_category_list + action_category_list + object_category_list + [enabled_bool, ] - return self.admin_api.add_rule_dict(user_id, intra_extension_id, sub_meta_rule_id, rule_list) - - @controller.protected() - def get_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - rule_id = kw.get('rule_id', None) - return self.admin_api.get_rule_dict(user_id, intra_extension_id, sub_meta_rule_id, rule_id) - - @controller.protected() - def del_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - rule_id = kw.get('rule_id', None) - self.admin_api.del_rule(user_id, intra_extension_id, sub_meta_rule_id, rule_id) - - @controller.protected() - def set_rule(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - intra_extension_id = kw.get('intra_extension_id', None) - sub_meta_rule_id = kw.get('sub_meta_rule_id', None) - rule_id = kw.get('rule_id', None) - rule_list = list() - subject_category_list = kw.get('subject_categories', []) - object_category_list = kw.get('object_categories', []) - action_category_list = kw.get('action_categories', []) - rule_list = subject_category_list + action_category_list + object_category_list - return self.admin_api.set_rule_dict(user_id, intra_extension_id, sub_meta_rule_id, rule_id, rule_list) - - -@dependency.requires('authz_api') -class InterExtensions(controller.V3Controller): - - def __init__(self): - super(InterExtensions, self).__init__() - - def _get_user_from_token(self, token_id): - response = self.token_provider_api.validate_token(token_id) - token_ref = token_model.KeystoneToken(token_id=token_id, token_data=response) - return token_ref['user'] - - # @controller.protected() - # def get_inter_extensions(self, context, **kw): - # user = self._get_user_from_token(context.get('token_id')) - # return { - # 'inter_extensions': - # self.interextension_api.get_inter_extensions() - # } - - # @controller.protected() - # def get_inter_extension(self, context, **kw): - # user = self._get_user_from_token(context.get('token_id')) - # return { - # 'inter_extensions': - # self.interextension_api.get_inter_extension(uuid=kw['inter_extension_id']) - # } - - # @controller.protected() - # def create_inter_extension(self, context, **kw): - # user = self._get_user_from_token(context.get('token_id')) - # return self.interextension_api.create_inter_extension(kw) - - # @controller.protected() - # def delete_inter_extension(self, context, **kw): - # user = self._get_user_from_token(context.get('token_id')) - # if 'inter_extension_id' not in kw: - # raise exception.Error - # return self.interextension_api.delete_inter_extension(kw['inter_extension_id']) - - -@dependency.requires('moonlog_api', 'authz_api') -class Logs(controller.V3Controller): - - def __init__(self): - super(Logs, self).__init__() - - def _get_user_id_from_token(self, token_id): - response = self.token_provider_api.validate_token(token_id) - token_ref = token_model.KeystoneToken(token_id=token_id, token_data=response) - return token_ref['user'] - - @controller.protected() - def get_logs(self, context, **kw): - user_id = self._get_user_id_from_token(context.get('token_id')) - options = kw.get('options', '') - return self.moonlog_api.get_logs(user_id, options) - - -@dependency.requires('identity_api', "token_provider_api", "resource_api") -class MoonAuth(controller.V3Controller): - - def __init__(self): - super(MoonAuth, self).__init__() - - def _get_project(self, uuid="", name=""): - projects = self.resource_api.list_projects() - for project in projects: - if uuid and uuid == project['id']: - return project - elif name and name == project['name']: - return project - - def get_token(self, context, **kw): - master_url = CONF.moon.master - data_auth = { - "auth": { - "identity": { - "methods": [ - "password" - ], - "password": { - "user": { - "domain": { - "id": "Default" - }, - "name": kw['username'], - "password": kw['password'] - } - } - } - } - } - - message = {} - if "project" in kw: - project = self._get_project(name=kw['project']) - if project: - data_auth["auth"]["scope"] = dict() - data_auth["auth"]["scope"]['project'] = dict() - data_auth["auth"]["scope"]['project']['id'] = project['id'] - else: - message = { - "error": { - "message": "Unable to find project {}".format(kw['project']), - "code": 200, - "title": "UnScopedToken" - }} - - req = requests.post("{}/v3/auth/tokens".format(master_url), - json=data_auth, - headers={"Content-Type": "application/json"} - ) - if req.status_code not in (200, 201): - LOG.error(req.text) - else: - _token = req.headers['X-Subject-Token'] - _data = req.json() - _result = { - "token": _token, - 'message': message - } - try: - _result["roles"] = map(lambda x: x['name'], _data["token"]["roles"]) - except KeyError: - pass - return _result - return {"token": None, 'message': req.json()} - diff --git a/keystone-moon/keystone/contrib/moon/core.py b/keystone-moon/keystone/contrib/moon/core.py deleted file mode 100644 index 943b8e78..00000000 --- a/keystone-moon/keystone/contrib/moon/core.py +++ /dev/null @@ -1,2990 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from uuid import uuid4 -import os -import json -import copy -import re -import six -import time -import types -import requests - -from keystone.common import manager -from keystone.exception import UserNotFound -from oslo_log import log -from keystone.common import dependency -from keystone import exception -from oslo_config import cfg -from keystone.i18n import _ -from keystone.common import extension - -from keystone.contrib.moon.exception import * -from keystone.contrib.moon.algorithms import * - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - -OPTS = [ - cfg.StrOpt('configuration_driver', - default='keystone.contrib.moon.backends.memory.ConfigurationConnector', - help='Configuration backend driver.'), - cfg.StrOpt('tenant_driver', - default='keystone.contrib.moon.backends.sql.TenantConnector', - help='Tenant backend driver.'), - cfg.StrOpt('authz_driver', - default='keystone.contrib.moon.backends.flat.SuperExtensionConnector', - help='Authorisation backend driver.'), - cfg.StrOpt('intraextension_driver', - default='keystone.contrib.moon.backends.sql.IntraExtensionConnector', - help='IntraExtension backend driver.'), - cfg.StrOpt('interextension_driver', - default='keystone.contrib.moon.backends.sql.InterExtensionConnector', - help='InterExtension backend driver.'), - cfg.StrOpt('log_driver', - default='keystone.contrib.moon.backends.flat.LogConnector', - help='Logs backend driver.'), - cfg.StrOpt('policy_directory', - default='/etc/keystone/policies', - help='Local directory where all policies are stored.'), - cfg.StrOpt('root_policy_directory', - default='policy_root', - help='Local directory where Root IntraExtension configuration is stored.'), - cfg.StrOpt('master', - default='http://localhost:35357/', - help='Address of the Moon master (if empty, the current Moon is the master).'), - cfg.StrOpt('master_login', - default='admin', - help='Login of the Moon master.'), - cfg.StrOpt('master_password', - default='nomoresecrete', - help='Password of the Moon master.'), -] - -for option in OPTS: - CONF.register_opt(option, group="moon") - - -def filter_input(func_or_str): - - def __filter(string): - if string and type(string) in (str, unicode): - return "".join(re.findall("[\w\- +]*", string)) - return string - - def __filter_dict(arg): - result = dict() - for key in arg.keys(): - if key == "email": - result["email"] = __filter_email(arg[key]) - elif key == "password": - result["password"] = arg['password'] - else: - result[key] = __filter(arg[key]) - return result - - def __filter_email(string): - if string and type(string) in (str, unicode): - return "".join(re.findall("[\w@\._\- +]*", string)) - return string - - def wrapped(*args, **kwargs): - _args = [] - for arg in args: - if isinstance(arg, str) or isinstance(arg, unicode): - arg = __filter(arg) - elif isinstance(arg, list): - arg = [__filter(item) for item in arg] - elif isinstance(arg, tuple): - arg = (__filter(item) for item in arg) - elif isinstance(arg, dict): - arg = __filter_dict(arg) - _args.append(arg) - for arg in kwargs: - if type(kwargs[arg]) in (unicode, str): - kwargs[arg] = __filter(kwargs[arg]) - if isinstance(kwargs[arg], str) or isinstance(kwargs[arg], unicode): - kwargs[arg] = __filter(kwargs[arg]) - elif isinstance(kwargs[arg], list): - kwargs[arg] = [__filter(item) for item in kwargs[arg]] - elif isinstance(kwargs[arg], tuple): - kwargs[arg] = (__filter(item) for item in kwargs[arg]) - elif isinstance(kwargs[arg], dict): - kwargs[arg] = __filter_dict(kwargs[arg]) - return func_or_str(*_args, **kwargs) - - if isinstance(func_or_str, str) or isinstance(func_or_str, unicode): - return __filter(func_or_str) - if isinstance(func_or_str, list): - return [__filter(item) for item in func_or_str] - if isinstance(func_or_str, tuple): - return (__filter(item) for item in func_or_str) - if isinstance(func_or_str, dict): - return __filter_dict(func_or_str) - if isinstance(func_or_str, types.FunctionType): - return wrapped - return None - - -def enforce(action_names, object_name, **extra): - - def wrap(func): - _action_name_list = action_names - _object_name = object_name - dependency.resolve_future_dependencies() - - def wrapped(*args, **kwargs): - root_api = dependency._REGISTRY["root_api"][0] - admin_api = dependency._REGISTRY["admin_api"][0] - moonlog_api = dependency._REGISTRY["moonlog_api"][0] - tenant_api = dependency._REGISTRY["tenant_api"][0] - returned_value_for_func = None - try: - user_id = args[1] - except IndexError: - user_id = kwargs['user_id'] - intra_extension_id = None - intra_admin_extension_id = None - - intra_root_extension_id = root_api.root_extension_id - try: - intra_extension_id = args[2] - except IndexError: - if 'intra_extension_id' in kwargs: - intra_extension_id = kwargs['intra_extension_id'] - else: - intra_extension_id = intra_root_extension_id - - tenants_dict = tenant_api.driver.get_tenants_dict() - if root_api.is_admin_subject(user_id): - # TODO: check if there is no security hole here - # moonlog_api.driver.info("Authorizing because it is the user admin of the root intra-extension") - returned_value_for_func = func(*args, **kwargs) - else: - intra_extensions_dict = admin_api.driver.get_intra_extensions_dict() - if intra_extension_id not in intra_extensions_dict: - # if id is not an intra_extension, maybe it is a tenant id - intra_extension_id = intra_root_extension_id - if intra_extension_id in tenants_dict: - # id is in fact a tenant id so, we must check against the Root intra_extension - intra_extension_id = intra_root_extension_id - LOG.warning("intra_extension_id is a tenant ID ({})".format(intra_extension_id)) - else: - # id is not a known tenant ID, so we must check against the Root intra_extension - intra_extension_id = intra_root_extension_id - LOG.warning("Cannot manage because the intra-extension is unknown (fallback to the root intraextension)") - for _tenant_id in tenants_dict: - if tenants_dict[_tenant_id]['intra_authz_extension_id'] == intra_extension_id or \ - tenants_dict[_tenant_id]['intra_admin_extension_id'] == intra_extension_id: - intra_admin_extension_id = tenants_dict[_tenant_id]['intra_admin_extension_id'] - break - if not intra_admin_extension_id: - moonlog_api.driver.warning("No Intra_Admin_Extension found, authorization granted by default.") - returned_value_for_func = func(*args, **kwargs) - else: - objects_dict = admin_api.driver.get_objects_dict(intra_admin_extension_id) - object_name = intra_extensions_dict[intra_extension_id]['genre'] + '.' + _object_name - object_id = None - for _object_id in objects_dict: - if objects_dict[_object_id]['name'] == object_name: - object_id = _object_id - break - if not object_id: - objects_dict = admin_api.driver.get_objects_dict(intra_root_extension_id) - object_name = object_name.split(".")[-1] - for _object_id in objects_dict: - if objects_dict[_object_id]['name'] == object_name: - object_id = _object_id - break - if not object_id: - raise ObjectUnknown("enforce: Unknown object name: {}".format(object_name)) - # if we found the object in intra_root_extension_id, so we change the intra_admin_extension_id - # into intra_root_extension_id and we modify the ID of the subject - subjects_dict = admin_api.driver.get_subjects_dict(intra_admin_extension_id) - try: - subject_name = subjects_dict[user_id]["name"] - except KeyError: - subject_name = None - # Try if user_id is a Keystone ID - try: - for _subject_id in subjects_dict: - if subjects_dict[_subject_id]["keystone_id"] == user_id: - subject_name = subjects_dict[_subject_id]["name"] - except KeyError: - raise SubjectUnknown() - intra_admin_extension_id = intra_root_extension_id - subjects_dict = admin_api.driver.get_subjects_dict(intra_admin_extension_id) - user_id = None - for _subject_id in subjects_dict: - if subjects_dict[_subject_id]["name"] == subject_name: - user_id = _subject_id - if not user_id: - raise SubjectUnknown("Subject {} Unknown for Root IntraExtension...".format(subject_name)) - if type(_action_name_list) in (str, unicode): - action_name_list = (_action_name_list, ) - else: - action_name_list = _action_name_list - actions_dict = admin_api.driver.get_actions_dict(intra_admin_extension_id) - action_id_list = list() - for _action_name in action_name_list: - for _action_id in actions_dict: - if actions_dict[_action_id]['name'] == _action_name: - action_id_list.append(_action_id) - break - - authz_result = False - action_id = "" - for action_id in action_id_list: - res = admin_api.authz(intra_admin_extension_id, user_id, object_id, action_id) - moonlog_api.info("res={}".format(res)) - if res: - authz_result = True - else: - moonlog_api.authz("No authorization for ({} {}-{}-{})".format( - intra_admin_extension_id, - user_id, - object_name, - actions_dict[action_id]['name'])) - authz_result = False - break - if authz_result: - returned_value_for_func = func(*args, **kwargs) - else: - raise AuthzException("No authorization for ({} {}-{}-{})".format( - intra_admin_extension_id, - user_id, - object_name, - actions_dict[action_id]['name'])) - return returned_value_for_func - return wrapped - return wrap - - -@dependency.provider('configuration_api') -class ConfigurationManager(manager.Manager): - - driver_namespace = 'keystone.moon.configuration' - - def __init__(self): - super(ConfigurationManager, self).__init__(CONF.moon.configuration_driver) - - @enforce("read", "templates") - def get_policy_templates_dict(self, user_id): - """ - Return a dictionary of all policy templates - :return: { - template_id1: {name: template_name, description: template_description}, - template_id2: {name: template_name, description: template_description}, - ... - } - """ - return self.driver.get_policy_templates_dict() - - @enforce("read", "templates") - def get_policy_template_id_from_name(self, user_id, policy_template_name): - policy_templates_dict = self.driver.get_policy_templates_dict() - for policy_template_id in policy_templates_dict: - if policy_templates_dict[policy_template_id]['name'] == policy_template_name: - return policy_template_id - return None - - @enforce("read", "aggregation_algorithms") - def get_aggregation_algorithms_dict(self, user_id): - """ - Return a dictionary of all aggregation algorithms - :return: { - aggre_algo_id1: {name: aggre_name, description: aggre_algo_description}, - aggre_algo_id2: {name: aggre_name, description: aggre_algo_description}, - ... - } - """ - return self.driver.get_aggregation_algorithms_dict() - - @enforce("read", "aggregation_algorithms") - def get_aggregation_algorithm_id_from_name(self, user_id, aggregation_algorithm_name): - aggregation_algorithms_dict = self.driver.get_aggregation_algorithms_dict() - for aggregation_algorithm_id in aggregation_algorithms_dict: - if aggregation_algorithms_dict[aggregation_algorithm_id]['name'] == aggregation_algorithm_name: - return aggregation_algorithm_id - return None - - @enforce("read", "sub_meta_rule_algorithms") - def get_sub_meta_rule_algorithms_dict(self, user_id): - """ - Return a dictionary of sub_meta_rule algorithm - :return: { - sub_meta_rule_id1: {name: sub_meta_rule_name, description: sub_meta_rule_description}, - sub_meta_rule_id2: {name: sub_meta_rule_name, description: sub_meta_rule_description}, - ... - } - """ - return self.driver.get_sub_meta_rule_algorithms_dict() - - @enforce("read", "sub_meta_rule_algorithms") - def get_sub_meta_rule_algorithm_id_from_name(self, sub_meta_rule_algorithm_name): - sub_meta_rule_algorithms_dict = self.configuration_api.get_sub_meta_rule_algorithms_dict() - for sub_meta_rule_algorithm_id in sub_meta_rule_algorithms_dict: - if sub_meta_rule_algorithms_dict[sub_meta_rule_algorithm_id]['name'] == sub_meta_rule_algorithm_name: - return sub_meta_rule_algorithm_id - return None - - -@dependency.provider('tenant_api') -@dependency.requires('moonlog_api', 'admin_api', 'root_api', 'resource_api', 'admin_api') -class TenantManager(manager.Manager): - - driver_namespace = 'keystone.moon.tenant' - - def __init__(self): - super(TenantManager, self).__init__(CONF.moon.tenant_driver) - - @filter_input - @enforce("read", "tenants") - def get_tenants_dict(self, user_id): - """ - Return a dictionary with all tenants - :return: { - tenant_id1: { - name: xxx, - description: yyy, - intra_authz_extension_id: zzz, - intra_admin_extension_id: zzz, - }, - tenant_id2: {...}, - ... - } - """ - return self.driver.get_tenants_dict() - - def __get_keystone_tenant_dict(self, tenant_id="", tenant_name=""): - tenants = self.resource_api.list_projects() - for tenant in tenants: - if tenant_id and tenant_id == tenant['id']: - return tenant - if tenant_name and tenant_name == tenant['name']: - return tenant - if not tenant_id: - tenant_id = uuid4().hex - if not tenant_name: - tenant_name = tenant_id - tenant = { - "id": tenant_id, - "name": tenant_name, - "description": "Auto generated tenant from Moon platform", - "enabled": True, - "domain_id": "default" - } - keystone_tenant = self.resource_api.create_project(tenant["id"], tenant) - return keystone_tenant - - @filter_input - @enforce(("read", "write"), "tenants") - def add_tenant_dict(self, user_id, tenant_id, tenant_dict): - tenants_dict = self.driver.get_tenants_dict() - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]['name'] == tenant_dict['name']: - raise TenantAddedNameExisting() - - # Check (and eventually sync) Keystone tenant - if 'id' not in tenant_dict: - tenant_dict['id'] = None - keystone_tenant = self.__get_keystone_tenant_dict(tenant_dict['id'], tenant_dict['name']) - for att in keystone_tenant: - if keystone_tenant[att]: - tenant_dict[att] = keystone_tenant[att] - # Sync users between intra_authz_extension and intra_admin_extension - self.moonlog_api.debug("add_tenant_dict {}".format(tenant_dict)) - if 'intra_admin_extension_id' in tenant_dict and tenant_dict['intra_admin_extension_id']: - if 'intra_authz_extension_id' in tenant_dict and tenant_dict['intra_authz_extension_id']: - authz_subjects_dict = self.admin_api.get_subjects_dict(self.root_api.root_admin_id, tenant_dict['intra_authz_extension_id']) - authz_subject_names_list = [authz_subjects_dict[subject_id]["name"] for subject_id in authz_subjects_dict] - admin_subjects_dict = self.admin_api.get_subjects_dict(self.root_api.root_admin_id, tenant_dict['intra_admin_extension_id']) - admin_subject_names_list = [admin_subjects_dict[subject_id]["name"] for subject_id in admin_subjects_dict] - for _subject_id in authz_subjects_dict: - if authz_subjects_dict[_subject_id]["name"] not in admin_subject_names_list: - self.admin_api.add_subject_dict(self.root_api.root_admin_id, tenant_dict['intra_admin_extension_id'], authz_subjects_dict[_subject_id]) - for _subject_id in admin_subjects_dict: - if admin_subjects_dict[_subject_id]["name"] not in authz_subject_names_list: - self.admin_api.add_subject_dict(self.root_api.root_admin_id, tenant_dict['intra_authz_extension_id'], admin_subjects_dict[_subject_id]) - - return self.driver.add_tenant_dict(tenant_dict['id'], tenant_dict) - - @filter_input - @enforce("read", "tenants") - def get_tenant_dict(self, user_id, tenant_id): - tenants_dict = self.driver.get_tenants_dict() - if tenant_id not in tenants_dict: - raise TenantUnknown() - return tenants_dict[tenant_id] - - @filter_input - @enforce(("read", "write"), "tenants") - def del_tenant(self, user_id, tenant_id): - if tenant_id not in self.driver.get_tenants_dict(): - raise TenantUnknown() - self.driver.del_tenant(tenant_id) - - @filter_input - @enforce(("read", "write"), "tenants") - def set_tenant_dict(self, user_id, tenant_id, tenant_dict): - tenants_dict = self.driver.get_tenants_dict() - if tenant_id not in tenants_dict: - raise TenantUnknown() - - # Sync users between intra_authz_extension and intra_admin_extension - if 'intra_admin_extension_id' in tenant_dict: - if 'intra_authz_extension_id' in tenant_dict: - authz_subjects_dict = self.admin_api.get_subjects_dict(self.root_api.root_admin_id, tenant_dict['intra_authz_extension_id']) - authz_subject_names_list = [authz_subjects_dict[subject_id]["name"] for subject_id in authz_subjects_dict] - admin_subjects_dict = self.admin_api.get_subjects_dict(self.root_api.root_admin_id, tenant_dict['intra_admin_extension_id']) - admin_subject_names_list = [admin_subjects_dict[subject_id]["name"] for subject_id in admin_subjects_dict] - for _subject_id in authz_subjects_dict: - if authz_subjects_dict[_subject_id]["name"] not in admin_subject_names_list: - self.admin_api.add_subject_dict(self.root_api.root_admin_id, tenant_dict['intra_admin_extension_id'], authz_subjects_dict[_subject_id]) - for _subject_id in admin_subjects_dict: - if admin_subjects_dict[_subject_id]["name"] not in authz_subject_names_list: - self.admin_api.add_subject_dict(self.root_api.root_admin_id, tenant_dict['intra_authz_extension_id'], admin_subjects_dict[_subject_id]) - - return self.driver.set_tenant_dict(tenant_id, tenant_dict) - - -@dependency.requires('identity_api', 'tenant_api', 'configuration_api', 'moonlog_api') -class IntraExtensionManager(manager.Manager): - - driver_namespace = 'keystone.moon.intraextension' - - def __init__(self): - super(IntraExtensionManager, self).__init__(CONF.moon.intraextension_driver) - self._root_admin_id = None - self._root_extension_id = None - - def __init_root(self, root_extension_id=None): - if root_extension_id: - self._root_extension_id = root_extension_id - else: - try: - self._root_extension_id = self.get_root_extension_id() - self.aggregation_algorithm_dict = self.configuration_api.driver.get_aggregation_algorithms_dict() - except AttributeError as e: - LOG.warning("Error on root intraextension initialization ({})".format(e)) - self._root_extension_id = None - self.aggregation_algorithm_dict = {} - if self._root_extension_id: - for subject_id, subject_dict in self.driver.get_subjects_dict(self.root_extension_id).iteritems(): - if subject_dict["name"] == "admin": - self._root_admin_id = subject_id - return - raise RootExtensionNotInitialized() - - @property - def root_extension_id(self): - if not self._root_extension_id: - self.__init_root() - return self._root_extension_id - - @root_extension_id.setter - def root_extension_id(self, value): - self._root_extension_id = value - LOG.info("set root_extension_id={}".format(self._root_extension_id)) - - @property - def root_admin_id(self): - if not self._root_admin_id: - self.__init_root() - return self._root_admin_id - - def get_root_extension_dict(self): - """ - - :return: {id: {"name": "xxx"}} - """ - return {self.root_extension_id: self.driver.get_intra_extensions_dict()[self.root_extension_id]} - - def get_root_extension_id(self): - extensions = self.driver.get_intra_extensions_dict() - for extension_id, extension_dict in extensions.iteritems(): - if extension_dict["name"] == CONF.moon.root_policy_directory: - return extension_id - else: - extension = self.load_root_intra_extension_dict(CONF.moon.root_policy_directory) - if not extension: - raise IntraExtensionCreationError("The root extension is not created.") - return extension['id'] - - def __get_authz_buffer(self, intra_extension_id, subject_id, object_id, action_id): - """ - :param intra_extension_id: - :param subject_id: - :param object_id: - :param action_id: - :return: authz_buffer = { - 'subject_id': xxx, - 'object_id': yyy, - 'action_id': zzz, - 'subject_assignments': { - 'subject_category1': [], - 'subject_category2': [], - ... - }, - 'object_assignments': {}, - 'action_assignments': {}, - } - """ - authz_buffer = dict() - # Sometimes it is not the subject ID but the User Keystone ID, so, we have to check - subjects_dict = self.driver.get_subjects_dict(intra_extension_id) - if subject_id not in subjects_dict.keys(): - for _subject_id in subjects_dict: - if subjects_dict[_subject_id]['keystone_id']: - subject_id = _subject_id - break - authz_buffer['subject_id'] = subject_id - authz_buffer['object_id'] = object_id - authz_buffer['action_id'] = action_id - meta_data_dict = dict() - meta_data_dict["subject_categories"] = self.driver.get_subject_categories_dict(intra_extension_id) - meta_data_dict["object_categories"] = self.driver.get_object_categories_dict(intra_extension_id) - meta_data_dict["action_categories"] = self.driver.get_action_categories_dict(intra_extension_id) - subject_assignment_dict = dict() - for category in meta_data_dict["subject_categories"]: - subject_assignment_dict[category] = self.driver.get_subject_assignment_list( - intra_extension_id, subject_id, category) - object_assignment_dict = dict() - for category in meta_data_dict["object_categories"]: - object_assignment_dict[category] = self.driver.get_object_assignment_list( - intra_extension_id, object_id, category) - action_assignment_dict = dict() - for category in meta_data_dict["action_categories"]: - action_assignment_dict[category] = self.driver.get_action_assignment_list( - intra_extension_id, action_id, category) - authz_buffer['subject_assignments'] = dict() - authz_buffer['object_assignments'] = dict() - authz_buffer['action_assignments'] = dict() - - for _subject_category in meta_data_dict['subject_categories']: - authz_buffer['subject_assignments'][_subject_category] = list(subject_assignment_dict[_subject_category]) - for _object_category in meta_data_dict['object_categories']: - authz_buffer['object_assignments'][_object_category] = list(object_assignment_dict[_object_category]) - for _action_category in meta_data_dict['action_categories']: - authz_buffer['action_assignments'][_action_category] = list(action_assignment_dict[_action_category]) - return authz_buffer - - def __authz(self, intra_extension_id, subject_id, object_id, action_id): - """Check authorization for a particular action. - - :param intra_extension_id: UUID of an IntraExtension - :param subject_id: subject UUID of the request - :param object_id: object UUID of the request - :param action_id: action UUID of the request - :return: True or False or raise an exception - :raises: - """ - authz_buffer = self.__get_authz_buffer(intra_extension_id, subject_id, object_id, action_id) - decision_buffer = dict() - decision = False - - meta_rule_dict = self.driver.get_sub_meta_rules_dict(intra_extension_id) - - for sub_meta_rule_id in meta_rule_dict: - if meta_rule_dict[sub_meta_rule_id]['algorithm'] == 'inclusion': - decision_buffer[sub_meta_rule_id] = inclusion( - authz_buffer, - meta_rule_dict[sub_meta_rule_id], - self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id).values()) - elif meta_rule_dict[sub_meta_rule_id]['algorithm'] == 'comparison': - decision_buffer[sub_meta_rule_id] = comparison( - authz_buffer, - meta_rule_dict[sub_meta_rule_id], - self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id).values()) - - try: - aggregation_algorithm_id = self.driver.get_aggregation_algorithm_id(intra_extension_id)['aggregation_algorithm'] - except TypeError: - return { - 'authz': False, - 'comment': "Aggregation algorithm not set" - } - if self.aggregation_algorithm_dict[aggregation_algorithm_id]['name'] == 'all_true': - decision = all_true(decision_buffer) - elif self.aggregation_algorithm_dict[aggregation_algorithm_id]['name'] == 'one_true': - decision = one_true(decision_buffer) - if not decision: - raise AuthzException("{} {}-{}-{}".format(intra_extension_id, subject_id, action_id, object_id)) - return { - 'authz': decision, - 'comment': "{} {}-{}-{}".format(intra_extension_id, subject_id, action_id, object_id) - } - - def authz(self, intra_extension_id, subject_id, object_id, action_id): - decision_dict = dict() - try: - decision_dict = self.__authz(intra_extension_id, subject_id, object_id, action_id) - except (SubjectUnknown, ObjectUnknown, ActionUnknown) as e: - # maybe we need to synchronize with the master - if CONF.moon.master: - self.get_data_from_master() - decision_dict = self.__authz(intra_extension_id, subject_id, object_id, action_id) - if not decision_dict["authz"]: - raise AuthzException(decision_dict["comment"]) - return {'authz': decision_dict["authz"], 'comment': ''} - - def get_data_from_master(self, subject=None, object=None, action=None): - LOG.info("Synchronising with master") - master_url = CONF.moon.master - master_login = CONF.moon.master_login - master_password = CONF.moon.master_password - headers = { - 'content-type': 'application/json', - 'Accept': 'text/plain,text/html,application/xhtml+xml,application/xml' - } - post = { - 'auth': { - 'scope': { - 'project': { - 'domain': {'id': 'Default'}, - 'name': 'demo'} - }, - 'identity': { - 'password': { - 'user': { - 'domain': {'id': 'Default'}, - 'password': 'nomoresecrete', - 'name': 'admin'} - }, - 'methods': ['password'] - } - } - } - post["auth"]["identity"]["password"]["user"]["name"] = master_login - post["auth"]["identity"]["password"]["user"]["password"] = master_password - req = requests.post('{}/v3/auth/tokens'.format(master_url), data=json.dumps(post), headers=headers) - if req.status_code not in (200, 201): - raise IntraExtensionException("Cannot connect to the Master.") - headers["X-Auth-Token"] = req.headers["x-subject-token"] - # get all intra-extensions - req = requests.get('{}/moon/intra_extensions/'.format(master_url), headers=headers) - extensions = req.json() - for intra_extension_id, intra_extension_value in extensions.iteritems(): - if intra_extension_value["model"] == "policy_root": - continue - - # add the intra-extension - intra_extension_dict = dict() - # Force the id of the intra-extension - intra_extension_dict['id'] = intra_extension_id - intra_extension_dict['name'] = intra_extension_value["name"] - intra_extension_dict['model'] = intra_extension_value["model"] - intra_extension_dict['genre'] = intra_extension_value["genre"] - intra_extension_dict['description'] = intra_extension_value["description"] - try: - ref = self.load_intra_extension_dict(self.root_admin_id, intra_extension_dict=intra_extension_dict) - except Exception as e: - LOG.error("(load_intra_extension_dict) Got an unhandled exception: {}".format(e)) - import traceback, sys - traceback.print_exc(file=sys.stdout) - - # Note (asteroide): we use the driver API to bypass authorizations of the internal API - # but in we force overwriting data every time - - # get all categories from master - _url = '{}/moon/intra_extensions/{}/subject_categories'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - cat = req.json() - _categories_name = map(lambda x: x["name"], - self.driver.get_subject_categories_dict(intra_extension_id).values()) - for _cat_key, _cat_value in cat.iteritems(): - if _cat_value['name'] in _categories_name: - continue - self.driver.set_subject_category_dict(intra_extension_id, _cat_key, _cat_value) - _url = '{}/moon/intra_extensions/{}/object_categories'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - cat = req.json() - _categories_name = map(lambda x: x["name"], - self.driver.get_object_categories_dict(intra_extension_id).values()) - for _cat_key, _cat_value in cat.iteritems(): - if _cat_value['name'] in _categories_name: - continue - self.driver.set_object_category_dict(intra_extension_id, _cat_key, _cat_value) - _url = '{}/moon/intra_extensions/{}/action_categories'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - cat = req.json() - _categories_name = map(lambda x: x["name"], - self.driver.get_action_categories_dict(intra_extension_id).values()) - for _cat_key, _cat_value in cat.iteritems(): - if _cat_value['name'] in _categories_name: - continue - self.driver.set_action_category_dict(intra_extension_id, _cat_key, _cat_value) - - # get part of subjects, objects, actions from master - _url = '{}/moon/intra_extensions/{}/subjects'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - sub = req.json() - _subjects_name = map(lambda x: x["name"], self.driver.get_subjects_dict(intra_extension_id).values()) - for _sub_key, _sub_value in sub.iteritems(): - if _sub_value['name'] in _subjects_name: - continue - keystone_user = self.identity_api.get_user_by_name(_sub_value['keystone_name'], "default") - _sub_value['keystone_id'] = keystone_user['id'] - self.driver.set_subject_dict(intra_extension_id, _sub_key, _sub_value) - _url = '{}/moon/intra_extensions/{}/objects'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - obj = req.json() - _objects_name = map(lambda x: x["name"], self.driver.get_objects_dict(intra_extension_id).values()) - for _obj_key, _obj_value in obj.iteritems(): - if _obj_value['name'] in _objects_name: - continue - _obj_value['id'] = _obj_key - self.driver.set_object_dict(intra_extension_id, _obj_key, _obj_value) - _url = '{}/moon/intra_extensions/{}/actions'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - act = req.json() - _actions_name = map(lambda x: x["name"], self.driver.get_actions_dict(intra_extension_id).values()) - for _act_key, _act_value in act.iteritems(): - if _act_value['name'] in _actions_name: - continue - self.driver.set_action_dict(intra_extension_id, _act_key, _act_value) - - # get all scopes from master - for s_cat, _value in self.driver.get_subject_categories_dict(intra_extension_id).iteritems(): - _url = '{}/moon/intra_extensions/{}/subject_scopes/{}'.format(master_url, intra_extension_id, s_cat) - req = requests.get(_url, headers=headers) - scopes = req.json() - _scopes_name = map(lambda x: x["name"], - self.driver.get_subject_scopes_dict(intra_extension_id, s_cat).values()) - if not _scopes_name: - continue - for _scope_key, _scope_value in scopes.iteritems(): - if _scope_value['name'] in _scopes_name: - continue - self.driver.set_subject_scope_dict(intra_extension_id, s_cat, _scope_key, _scope_value) - for o_cat in self.driver.get_subject_categories_dict(intra_extension_id): - _url = '{}/moon/intra_extensions/{}/object_scopes/{}'.format(master_url, intra_extension_id, o_cat) - req = requests.get(_url, headers=headers) - scopes = req.json() - _scopes_name = map(lambda x: x["name"], - self.driver.get_object_scopes_dict(intra_extension_id, o_cat).values()) - if not _scopes_name: - continue - for _scope_key, _scope_value in scopes.iteritems(): - if _scope_value['name'] in _scopes_name: - continue - self.driver.set_object_scope_dict(intra_extension_id, o_cat, _scope_key, _scope_value) - for a_cat in self.driver.get_subject_categories_dict(intra_extension_id): - _url = '{}/moon/intra_extensions/{}/action_scopes/{}'.format(master_url, intra_extension_id, a_cat) - req = requests.get(_url, headers=headers) - scopes = req.json() - _scopes_name = map(lambda x: x["name"], - self.driver.get_action_scopes_dict(intra_extension_id, a_cat ).values()) - if not _scopes_name: - continue - for _scope_key, _scope_value in scopes.iteritems(): - if _scope_value['name'] in _scopes_name: - continue - self.add_action_scope_dict(intra_extension_id, a_cat, _scope_key, _scope_value) - - # get aggregation algorithm from master - _url = '{}/moon/intra_extensions/{}/aggregation_algorithm'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - algo = req.json() - self.driver.set_aggregation_algorithm_id(intra_extension_id, algo['aggregation_algorithm']) - - # get meta-rule from master - _url = '{}/moon/intra_extensions/{}/sub_meta_rules'.format(master_url, intra_extension_id) - req = requests.get(_url, headers=headers) - sub_meta_rules = req.json() - _sub_meta_rules_name = map(lambda x: x["name"], self.driver.get_sub_meta_rules_dict(intra_extension_id).values()) - for _sub_meta_rules_key, _sub_meta_rules_value in sub_meta_rules.iteritems(): - if _sub_meta_rules_value['name'] in _sub_meta_rules_name: - continue - self.driver.set_sub_meta_rule_dict(intra_extension_id, _sub_meta_rules_key, _sub_meta_rules_value) - - # get all rules from master - _sub_meta_rules_ids = self.driver.get_sub_meta_rules_dict(intra_extension_id).keys() - for _sub_meta_rules_id in _sub_meta_rules_ids: - _url = '{}/moon/intra_extensions/{}/rule/{}'.format(master_url, intra_extension_id, _sub_meta_rules_id) - req = requests.get(_url, headers=headers) - rules = req.json() - _rules = self.driver.get_rules_dict(intra_extension_id, _sub_meta_rules_id).values() - for _rules_key, _rules_value in rules.iteritems(): - if _rules_value in _rules: - continue - self.driver.set_rule_dict(intra_extension_id, _sub_meta_rules_id, _rules_key, _rules_value) - - # get part of assignments from master - _subject_ids = self.driver.get_subjects_dict(intra_extension_id).keys() - _subject_category_ids = self.driver.get_subject_categories_dict(intra_extension_id).keys() - - for _subject_id in _subject_ids: - for _subject_category_id in _subject_category_ids: - _url = '{}/moon/intra_extensions/{}/subject_assignments/{}/{}'.format( - master_url, - intra_extension_id, - _subject_id, - _subject_category_id - ) - req = requests.get(_url, headers=headers) - subject_assignments = req.json() - _assignments = self.driver.get_subject_assignment_list( - intra_extension_id, - _subject_id, - _subject_category_id - ) - for _assignment in subject_assignments: - if _assignment in _assignments: - continue - self.driver.add_subject_assignment_list( - intra_extension_id, - _subject_id, - _subject_category_id, - _assignment - ) - - _object_ids = self.driver.get_objects_dict(intra_extension_id).keys() - _object_category_ids = self.driver.get_object_categories_dict(intra_extension_id).keys() - - for _object_id in _object_ids: - for _object_category_id in _object_category_ids: - _url = '{}/moon/intra_extensions/{}/object_assignments/{}/{}'.format( - master_url, - intra_extension_id, - _object_id, - _object_category_id - ) - req = requests.get(_url, headers=headers) - object_assignments = req.json() - _assignments = self.driver.get_object_assignment_list( - intra_extension_id, - _object_id, - _object_category_id - ) - for _assignment in object_assignments: - if _assignment in _assignments: - continue - self.driver.add_object_assignment_list( - intra_extension_id, - _object_id, - _object_category_id, - _assignment - ) - - _action_ids = self.driver.get_actions_dict(intra_extension_id).keys() - _action_category_ids = self.driver.get_action_categories_dict(intra_extension_id).keys() - - for _action_id in _action_ids: - for _action_category_id in _action_category_ids: - _url = '{}/moon/intra_extensions/{}/action_assignments/{}/{}'.format( - master_url, - intra_extension_id, - _action_id, - _action_category_id - ) - req = requests.get(_url, headers=headers) - action_assignments = req.json() - _assignments = self.driver.get_action_assignment_list( - intra_extension_id, - _action_id, - _action_category_id - ) - for _assignment in action_assignments: - if _assignment in _assignments: - continue - self.driver.add_action_assignment_list( - intra_extension_id, - _action_id, - _action_category_id, - _assignment - ) - - @enforce("read", "intra_extensions") - def get_intra_extensions_dict(self, user_id): - """ - :param user_id: - :return: { - intra_extension_id1: { - name: xxx, - model: yyy, - genre, authz, - description: zzz} - }, - intra_extension_id2: {...}, - ...} - """ - return self.driver.get_intra_extensions_dict() - - # load policy from policy directory - - def __load_metadata_file(self, intra_extension_dict, policy_dir): - - metadata_path = os.path.join(policy_dir, 'metadata.json') - f = open(metadata_path) - json_perimeter = json.load(f) - - subject_categories = map(lambda x: x["name"], - self.driver.get_subject_categories_dict(intra_extension_dict["id"]).values()) - for _cat in json_perimeter['subject_categories']: - if _cat not in subject_categories: - self.driver.set_subject_category_dict(intra_extension_dict["id"], uuid4().hex, - {"name": _cat, "description": _cat}) - object_categories = map(lambda x: x["name"], - self.driver.get_object_categories_dict(intra_extension_dict["id"]).values()) - for _cat in json_perimeter['object_categories']: - if _cat not in object_categories: - self.driver.set_object_category_dict(intra_extension_dict["id"], uuid4().hex, - {"name": _cat, "description": _cat}) - action_categories = map(lambda x: x["name"], - self.driver.get_action_categories_dict(intra_extension_dict["id"]).values()) - for _cat in json_perimeter['action_categories']: - if _cat not in action_categories: - self.driver.set_action_category_dict(intra_extension_dict["id"], uuid4().hex, - {"name": _cat, "description": _cat}) - - def __load_perimeter_file(self, intra_extension_dict, policy_dir): - - perimeter_path = os.path.join(policy_dir, 'perimeter.json') - f = open(perimeter_path) - json_perimeter = json.load(f) - - subjects_name_list = map(lambda x: x["name"], self.driver.get_subjects_dict(intra_extension_dict["id"]).values()) - subject_dict = dict() - # We suppose that all subjects can be mapped to a true user in Keystone - for _subject in json_perimeter['subjects']: - if _subject in subjects_name_list: - continue - try: - keystone_user = self.identity_api.get_user_by_name(_subject, "default") - except exception.UserNotFound: - # TODO (asteroide): must add a configuration option to allow that exception - # maybe a debug option for unittest - keystone_user = {'id': uuid4().hex, 'name': _subject} - self.moonlog_api.error("Keystone user not found ({})".format(_subject)) - subject_id = uuid4().hex - subject_dict[subject_id] = keystone_user - subject_dict[subject_id]['keystone_id'] = keystone_user["id"] - subject_dict[subject_id]['keystone_name'] = keystone_user["name"] - self.driver.set_subject_dict(intra_extension_dict["id"], subject_id, subject_dict[subject_id]) - intra_extension_dict["subjects"] = subject_dict - - # Copy all values for objects and actions - objects_name_list = map(lambda x: x["name"], self.driver.get_objects_dict(intra_extension_dict["id"]).values()) - object_dict = dict() - for _object in json_perimeter['objects']: - if _object in objects_name_list: - continue - _id = uuid4().hex - object_dict[_id] = {"name": _object, "description": _object} - self.driver.set_object_dict(intra_extension_dict["id"], _id, object_dict[_id]) - intra_extension_dict["objects"] = object_dict - - actions_name_list = map(lambda x: x["name"], self.driver.get_objects_dict(intra_extension_dict["id"]).values()) - action_dict = dict() - for _action in json_perimeter['actions']: - if _action in actions_name_list: - continue - _id = uuid4().hex - action_dict[_id] = {"name": _action, "description": _action} - self.driver.set_action_dict(intra_extension_dict["id"], _id, action_dict[_id]) - intra_extension_dict["actions"] = action_dict - - def __load_scope_file(self, intra_extension_dict, policy_dir): - - metadata_path = os.path.join(policy_dir, 'scope.json') - f = open(metadata_path) - json_perimeter = json.load(f) - - intra_extension_dict['subject_scopes'] = dict() - for category, scope in json_perimeter["subject_scopes"].iteritems(): - category_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], category, self.driver.SUBJECT_CATEGORY) - _scope_dict = dict() - for _scope in scope: - _id = uuid4().hex - _scope_dict[_id] = {"name": _scope, "description": _scope} - self.driver.set_subject_scope_dict(intra_extension_dict["id"], category_id, _id, _scope_dict[_id]) - intra_extension_dict['subject_scopes'][category] = _scope_dict - - intra_extension_dict['object_scopes'] = dict() - for category, scope in json_perimeter["object_scopes"].iteritems(): - category_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], category, self.driver.OBJECT_CATEGORY) - _scope_dict = dict() - for _scope in scope: - _id = uuid4().hex - _scope_dict[_id] = {"name": _scope, "description": _scope} - self.driver.set_object_scope_dict(intra_extension_dict["id"], category_id, _id, _scope_dict[_id]) - intra_extension_dict['object_scopes'][category] = _scope_dict - - intra_extension_dict['action_scopes'] = dict() - for category, scope in json_perimeter["action_scopes"].iteritems(): - category_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], category, self.driver.ACTION_CATEGORY) - _scope_dict = dict() - for _scope in scope: - _id = uuid4().hex - _scope_dict[_id] = {"name": _scope, "description": _scope} - self.driver.set_action_scope_dict(intra_extension_dict["id"], category_id, _id, _scope_dict[_id]) - intra_extension_dict['action_scopes'][category] = _scope_dict - - def __load_assignment_file(self, intra_extension_dict, policy_dir): - - f = open(os.path.join(policy_dir, 'assignment.json')) - json_assignments = json.load(f) - - subject_assignments = dict() - for category_name, value in json_assignments['subject_assignments'].iteritems(): - category_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], category_name, self.driver.SUBJECT_CATEGORY) - for user_name in value: - subject_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], user_name, self.driver.SUBJECT) - if subject_id not in subject_assignments: - subject_assignments[subject_id] = dict() - if category_id not in subject_assignments[subject_id]: - subject_assignments[subject_id][category_id] = \ - map(lambda x: self.driver.get_uuid_from_name(intra_extension_dict["id"], x, self.driver.SUBJECT_SCOPE, category_name), - value[user_name]) - else: - subject_assignments[subject_id][category_id].extend( - map(lambda x: self.driver.get_uuid_from_name(intra_extension_dict["id"], x, self.driver.SUBJECT_SCOPE, category_name), - value[user_name]) - ) - self.driver.set_subject_assignment_list(intra_extension_dict["id"], subject_id, category_id, - subject_assignments[subject_id][category_id]) - - object_assignments = dict() - for category_name, value in json_assignments["object_assignments"].iteritems(): - category_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], category_name, self.driver.OBJECT_CATEGORY) - for object_name in value: - object_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], object_name, self.driver.OBJECT) - if object_name not in object_assignments: - object_assignments[object_id] = dict() - if category_id not in object_assignments[object_id]: - object_assignments[object_id][category_id] = \ - map(lambda x: self.driver.get_uuid_from_name(intra_extension_dict["id"], x, self.driver.OBJECT_SCOPE, category_name), - value[object_name]) - else: - object_assignments[object_id][category_id].extend( - map(lambda x: self.driver.get_uuid_from_name(intra_extension_dict["id"], x, self.driver.OBJECT_SCOPE, category_name), - value[object_name]) - ) - self.driver.set_object_assignment_list(intra_extension_dict["id"], object_id, category_id, - object_assignments[object_id][category_id]) - - action_assignments = dict() - for category_name, value in json_assignments["action_assignments"].iteritems(): - category_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], category_name, self.driver.ACTION_CATEGORY) - for action_name in value: - action_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], action_name, self.driver.ACTION) - if action_name not in action_assignments: - action_assignments[action_id] = dict() - if category_id not in action_assignments[action_id]: - action_assignments[action_id][category_id] = \ - map(lambda x: self.driver.get_uuid_from_name(intra_extension_dict["id"], x, self.driver.ACTION_SCOPE, category_name), - value[action_name]) - else: - action_assignments[action_id][category_id].extend( - map(lambda x: self.driver.get_uuid_from_name(intra_extension_dict["id"], x, self.driver.ACTION_SCOPE, category_name), - value[action_name]) - ) - self.driver.set_action_assignment_list(intra_extension_dict["id"], action_id, category_id, - action_assignments[action_id][category_id]) - - def __load_metarule_file(self, intra_extension_dict, policy_dir): - - metadata_path = os.path.join(policy_dir, 'metarule.json') - f = open(metadata_path) - json_metarule = json.load(f) - metarule = dict() - categories = { - "subject_categories": self.driver.SUBJECT_CATEGORY, - "object_categories": self.driver.OBJECT_CATEGORY, - "action_categories": self.driver.ACTION_CATEGORY - } - # Translate value from JSON file to UUID for Database - for metarule_name in json_metarule["sub_meta_rules"]: - _id = uuid4().hex - metarule[_id] = dict() - metarule[_id]["name"] = metarule_name - for item in ("subject_categories", "object_categories", "action_categories"): - metarule[_id][item] = list() - for element in json_metarule["sub_meta_rules"][metarule_name][item]: - metarule[_id][item].append(self.driver.get_uuid_from_name(intra_extension_dict["id"], element, categories[item])) - metarule[_id]["algorithm"] = json_metarule["sub_meta_rules"][metarule_name]["algorithm"] - self.driver.set_sub_meta_rule_dict(intra_extension_dict["id"], _id, metarule[_id]) - submetarules = { - "aggregation": json_metarule["aggregation"], - "sub_meta_rules": metarule - } - for _id, _value in self.configuration_api.driver.get_aggregation_algorithms_dict().iteritems(): - if _value["name"] == json_metarule["aggregation"]: - self.driver.set_aggregation_algorithm_id(intra_extension_dict["id"], _id) - break - else: - LOG.warning("No aggregation_algorithm found for '{}'".format(json_metarule["aggregation"])) - - def __load_rule_file(self, intra_extension_dict, policy_dir): - - metadata_path = os.path.join(policy_dir, 'rule.json') - f = open(metadata_path) - json_rules = json.load(f) - intra_extension_dict["rule"] = {"rule": copy.deepcopy(json_rules)} - # Translate value from JSON file to UUID for Database - rules = dict() - sub_meta_rules = self.driver.get_sub_meta_rules_dict(intra_extension_dict["id"]) - for sub_rule_name in json_rules: - sub_rule_id = self.driver.get_uuid_from_name(intra_extension_dict["id"], - sub_rule_name, - self.driver.SUB_META_RULE) - rules[sub_rule_id] = list() - for rule in json_rules[sub_rule_name]: - subrule = list() - _rule = list(rule) - for category_uuid in sub_meta_rules[sub_rule_id]["subject_categories"]: - scope_name = _rule.pop(0) - scope_uuid = self.driver.get_uuid_from_name(intra_extension_dict["id"], - scope_name, - self.driver.SUBJECT_SCOPE, - category_uuid=category_uuid) - subrule.append(scope_uuid) - for category_uuid in sub_meta_rules[sub_rule_id]["action_categories"]: - scope_name = _rule.pop(0) - scope_uuid = self.driver.get_uuid_from_name(intra_extension_dict["id"], - scope_name, - self.driver.ACTION_SCOPE, - category_uuid=category_uuid) - subrule.append(scope_uuid) - for category_uuid in sub_meta_rules[sub_rule_id]["object_categories"]: - scope_name = _rule.pop(0) - scope_uuid = self.driver.get_uuid_from_name(intra_extension_dict["id"], - scope_name, - self.driver.OBJECT_SCOPE, - category_uuid=category_uuid) - subrule.append(scope_uuid) - # if a positive/negative value exists, all item of rule have not be consumed - if len(rule) >= 1 and isinstance(rule[0], bool): - subrule.append(rule[0]) - else: - # if value doesn't exist add a default value - subrule.append(True) - self.driver.set_rule_dict(intra_extension_dict["id"], sub_rule_id, uuid4().hex, subrule) - - @enforce(("read", "write"), "intra_extensions") - def load_intra_extension_dict(self, user_id, intra_extension_dict): - ie_dict = dict() - if "id" in intra_extension_dict: - ie_dict['id'] = filter_input(intra_extension_dict["id"]) - else: - ie_dict['id'] = uuid4().hex - - intraextensions = self.get_intra_extensions_dict(user_id) - - ie_dict["name"] = filter_input(intra_extension_dict["name"]) - ie_dict["model"] = filter_input(intra_extension_dict["model"]) - ie_dict["genre"] = filter_input(intra_extension_dict["genre"]) - if not ie_dict["genre"]: - if "admin" in ie_dict["model"] or "root" in ie_dict["model"]: - ie_dict["genre"] = "admin" - else: - ie_dict["genre"] = "authz" - ie_dict["description"] = filter_input(intra_extension_dict["description"]) - ref = self.driver.set_intra_extension_dict(ie_dict['id'], ie_dict) - - # if ie_dict['id'] in intraextensions: - # # note (dthom): if id was in intraextensions, it implies that the intraextension was already there - # # so we don't have to populate with default values - return ref - - def populate_default_data(self, ref): - self.moonlog_api.debug("Creation of IE: {}".format(ref)) - # read the template given by "model" and populate default variables - template_dir = os.path.join(CONF.moon.policy_directory, ref['intra_extension']["model"]) - self.__load_metadata_file(ref['intra_extension'], template_dir) - self.__load_perimeter_file(ref['intra_extension'], template_dir) - self.__load_scope_file(ref['intra_extension'], template_dir) - self.__load_assignment_file(ref['intra_extension'], template_dir) - self.__load_metarule_file(ref['intra_extension'], template_dir) - self.__load_rule_file(ref['intra_extension'], template_dir) - return ref - - def load_root_intra_extension_dict(self, policy_template=CONF.moon.root_policy_directory): - # Note (asteroide): Only one root Extension is authorized - # and this extension is created at the very beginning of the server - # so we don't need to use enforce here - extensions = self.driver.get_intra_extensions_dict() - for extension_id, extension_dict in extensions.iteritems(): - if extension_dict["name"] == CONF.moon.root_policy_directory: - return {'id': extension_id} - ie_dict = dict() - ie_dict['id'] = uuid4().hex - ie_dict["name"] = "policy_root" - ie_dict["model"] = filter_input(policy_template) - ie_dict["genre"] = "admin" - ie_dict["description"] = "policy_root" - ref = self.driver.set_intra_extension_dict(ie_dict['id'], ie_dict) - logging.debug("Creation of root IE: {}".format(ref)) - self.moonlog_api.debug("Creation of root IE: {}".format(ref)) - - # read the template given by "model" and populate default variables - template_dir = os.path.join(CONF.moon.policy_directory, ie_dict["model"]) - self.__load_metadata_file(ie_dict, template_dir) - self.__load_perimeter_file(ie_dict, template_dir) - self.__load_scope_file(ie_dict, template_dir) - self.__load_assignment_file(ie_dict, template_dir) - self.__load_metarule_file(ie_dict, template_dir) - self.__load_rule_file(ie_dict, template_dir) - self.__init_root(root_extension_id=ie_dict['id']) - if CONF.moon.master: - LOG.info("Master address: {}".format(CONF.moon.master)) - self.get_data_from_master() - return ref - - @enforce("read", "intra_extensions") - def get_intra_extension_dict(self, user_id, intra_extension_id): - """ - :param user_id: - :return: { - intra_extension_id: { - name: xxx, - model: yyy, - genre: authz, - description: xxx} - } - """ - intra_extensions_dict = self.driver.get_intra_extensions_dict() - if intra_extension_id not in intra_extensions_dict: - raise IntraExtensionUnknown() - return intra_extensions_dict[intra_extension_id] - - @enforce(("read", "write"), "intra_extensions") - def del_intra_extension(self, user_id, intra_extension_id): - if intra_extension_id not in self.driver.get_intra_extensions_dict(): - raise IntraExtensionUnknown() - for sub_meta_rule_id in self.driver.get_sub_meta_rules_dict(intra_extension_id): - for rule_id in self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id): - self.driver.del_rule(intra_extension_id, sub_meta_rule_id, rule_id) - self.driver.del_sub_meta_rule(intra_extension_id, sub_meta_rule_id) - self.driver.del_aggregation_algorithm(intra_extension_id) - for subject_id in self.driver.get_subjects_dict(intra_extension_id): - for subject_category_id in self.driver.get_subject_categories_dict(intra_extension_id): - self.driver.del_subject_scope(intra_extension_id, None, None) - self.driver.del_subject_assignment(intra_extension_id, None, None, None) - self.driver.del_subject_category(intra_extension_id, subject_category_id) - for object_id in self.driver.get_objects_dict(intra_extension_id): - for object_category_id in self.driver.get_object_categories_dict(intra_extension_id): - self.driver.del_object_scope(intra_extension_id, None, None) - self.driver.del_object_assignment(intra_extension_id, None, None, None) - self.driver.del_object_category(intra_extension_id, object_category_id) - for action_id in self.driver.get_actions_dict(intra_extension_id): - for action_category_id in self.driver.get_action_categories_dict(intra_extension_id): - self.driver.del_action_scope(intra_extension_id, None, None) - self.driver.del_action_assignment(intra_extension_id, None, None, None) - self.driver.del_action_category(intra_extension_id, action_category_id) - for subject_id in self.driver.get_subjects_dict(intra_extension_id): - self.driver.del_subject(intra_extension_id, subject_id) - for object_id in self.driver.get_objects_dict(intra_extension_id): - self.driver.del_object(intra_extension_id, object_id) - for action_id in self.driver.get_actions_dict(intra_extension_id): - self.driver.del_action(intra_extension_id, action_id) - return self.driver.del_intra_extension(intra_extension_id) - - @enforce(("read", "write"), "intra_extensions") - def set_intra_extension_dict(self, user_id, intra_extension_id, intra_extension_dict): - if intra_extension_id not in self.driver.get_intra_extensions_dict(): - raise IntraExtensionUnknown() - return self.driver.set_intra_extension_dict(intra_extension_id, intra_extension_dict) - - # Metadata functions - - @filter_input - @enforce("read", "subject_categories") - def get_subject_categories_dict(self, user_id, intra_extension_id): - """ - :param user_id: - :param intra_extension_id: - :return: { - subject_category_id1: { - name: xxx, - description: yyy}, - subject_category_id2: {...}, - ...} - """ - return self.driver.get_subject_categories_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "subject_categories") - def add_subject_category_dict(self, user_id, intra_extension_id, subject_category_dict): - subject_categories_dict = self.driver.get_subject_categories_dict(intra_extension_id) - for subject_category_id in subject_categories_dict: - if subject_categories_dict[subject_category_id]['name'] == subject_category_dict['name']: - raise SubjectCategoryNameExisting("Subject category {} already exists!".format(subject_category_dict['name'])) - _id = subject_category_dict.get('id', uuid4().hex) - return self.driver.set_subject_category_dict(intra_extension_id, _id, subject_category_dict) - - @filter_input - @enforce("read", "subject_categories") - def get_subject_category_dict(self, user_id, intra_extension_id, subject_category_id): - subject_categories_dict = self.driver.get_subject_categories_dict(intra_extension_id) - if subject_category_id not in subject_categories_dict: - raise SubjectCategoryUnknown() - return subject_categories_dict[subject_category_id] - - @filter_input - @enforce(("read", "write"), "subject_categories") - @enforce(("read", "write"), "subject_scopes") - @enforce(("read", "write"), "subject_assignments") - def del_subject_category(self, user_id, intra_extension_id, subject_category_id): - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - # Destroy scopes related to this category - for scope in self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id): - self.del_subject_scope(intra_extension_id, subject_category_id, scope) - # Destroy assignments related to this category - for subject_id in self.driver.get_subjects_dict(intra_extension_id): - for assignment_id in self.driver.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id): - self.driver.del_subject_assignment(intra_extension_id, subject_id, subject_category_id, assignment_id) - self.driver.del_subject_category(intra_extension_id, subject_category_id) - - @filter_input - @enforce(("read", "write"), "subject_categories") - def set_subject_category_dict(self, user_id, intra_extension_id, subject_category_id, subject_category_dict): - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - return self.driver.set_subject_category_dict(intra_extension_id, subject_category_id, subject_category_dict) - - @filter_input - @enforce("read", "object_categories") - def get_object_categories_dict(self, user_id, intra_extension_id): - return self.driver.get_object_categories_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "object_categories") - @enforce(("read", "write"), "object_scopes") - def add_object_category_dict(self, user_id, intra_extension_id, object_category_dict): - object_categories_dict = self.driver.get_object_categories_dict(intra_extension_id) - for object_category_id in object_categories_dict: - if object_categories_dict[object_category_id]["name"] == object_category_dict['name']: - raise ObjectCategoryNameExisting() - _id = object_category_dict.get('id', uuid4().hex) - return self.driver.set_object_category_dict(intra_extension_id, _id, object_category_dict) - - @filter_input - @enforce("read", "object_categories") - def get_object_category_dict(self, user_id, intra_extension_id, object_category_id): - object_categories_dict = self.driver.get_object_categories_dict(intra_extension_id) - if object_category_id not in object_categories_dict: - raise ObjectCategoryUnknown() - return object_categories_dict[object_category_id] - - @filter_input - @enforce(("read", "write"), "object_categories") - @enforce(("read", "write"), "object_scopes") - @enforce(("read", "write"), "object_assignments") - def del_object_category(self, user_id, intra_extension_id, object_category_id): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - # Destroy scopes related to this category - for scope in self.driver.get_object_scopes_dict(intra_extension_id, object_category_id): - self.del_object_scope(intra_extension_id, object_category_id, scope) - # Destroy assignments related to this category - for object_id in self.driver.get_objects_dict(intra_extension_id): - for assignment_id in self.driver.get_object_assignment_list(intra_extension_id, object_id, object_category_id): - self.driver.del_object_assignment(intra_extension_id, object_id, object_category_id, assignment_id) - self.driver.del_object_category(intra_extension_id, object_category_id) - - @filter_input - @enforce(("read", "write"), "object_categories") - def set_object_category_dict(self, user_id, intra_extension_id, object_category_id, object_category_dict): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - return self.driver.set_object_category_dict(intra_extension_id, object_category_id, object_category_dict) - - @filter_input - @enforce("read", "action_categories") - def get_action_categories_dict(self, user_id, intra_extension_id): - return self.driver.get_action_categories_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "action_categories") - @enforce(("read", "write"), "action_scopes") - def add_action_category_dict(self, user_id, intra_extension_id, action_category_dict): - action_categories_dict = self.driver.get_action_categories_dict(intra_extension_id) - for action_category_id in action_categories_dict: - if action_categories_dict[action_category_id]['name'] == action_category_dict['name']: - raise ActionCategoryNameExisting() - _id = action_category_dict.get('id', uuid4().hex) - return self.driver.set_action_category_dict(intra_extension_id, _id, action_category_dict) - - @filter_input - @enforce("read", "action_categories") - def get_action_category_dict(self, user_id, intra_extension_id, action_category_id): - action_categories_dict = self.driver.get_action_categories_dict(intra_extension_id) - if action_category_id not in action_categories_dict: - raise ActionCategoryUnknown() - return action_categories_dict[action_category_id] - - @filter_input - @enforce(("read", "write"), "action_categories") - @enforce(("read", "write"), "action_scopes") - def del_action_category(self, user_id, intra_extension_id, action_category_id): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - # Destroy scopes related to this category - for scope in self.driver.get_action_scopes_dict(intra_extension_id, action_category_id): - self.del_action_scope(intra_extension_id, action_category_id, scope) - # Destroy assignments related to this category - for action_id in self.driver.get_actions_dict(intra_extension_id): - for assignment_id in self.driver.get_action_assignment_list(intra_extension_id, action_id, action_category_id): - self.driver.del_action_assignment(intra_extension_id, action_id, action_category_id, assignment_id) - self.driver.del_action_category(intra_extension_id, action_category_id) - - @filter_input - @enforce(("read", "write"), "action_categories") - def set_action_category_dict(self, user_id, intra_extension_id, action_category_id, action_category_dict): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - return self.driver.set_action_category_dict(intra_extension_id, action_category_id, action_category_dict) - - # Perimeter functions - - @filter_input - @enforce("read", "subjects") - def get_subjects_dict(self, user_id, intra_extension_id): - return self.driver.get_subjects_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "subjects") - def add_subject_dict(self, user_id, intra_extension_id, subject_dict): - subjects_dict = self.driver.get_subjects_dict(intra_extension_id) - for subject_id in subjects_dict: - if subjects_dict[subject_id]["name"] == subject_dict['name']: - raise SubjectNameExisting("Subject {} already exists! [add_subject_dict]".format(subject_dict['name'])) - try: - subject_keystone_dict = self.identity_api.get_user_by_name(subject_dict['name'], "default") - except UserNotFound as e: - if 'domain_id' not in subject_dict: - subject_dict['domain_id'] = "default" - if 'project_id' not in subject_dict: - tenants = self.tenant_api.get_tenants_dict(user_id) - # Get the tenant ID for that intra_extension - for tenant_id, tenant_value in tenants.iteritems(): - if intra_extension_id == tenant_value['intra_admin_extension_id'] or \ - intra_extension_id == tenant_value['intra_authz_extension_id']: - subject_dict['project_id'] = tenant_value['id'] - break - else: - # If no tenant is found default to the admin tenant - for tenant_id, tenant_value in tenants.iteritems(): - if tenant_value['name'] == 'admin': - subject_dict['project_id'] = tenant_value['id'] - if 'email' not in subject_dict: - subject_dict['email'] = "" - if 'password' not in subject_dict: - # Default passord to the name of the new user - subject_dict['password'] = subject_dict['name'] - subject_keystone_dict = self.identity_api.create_user(subject_dict) - subject_dict["keystone_id"] = subject_keystone_dict["id"] - subject_dict["keystone_name"] = subject_keystone_dict["name"] - return self.driver.set_subject_dict(intra_extension_id, uuid4().hex, subject_dict) - - @filter_input - @enforce("read", "subjects") - def get_subject_dict(self, user_id, intra_extension_id, subject_id): - subjects_dict = self.driver.get_subjects_dict(intra_extension_id) - if subject_id not in subjects_dict: - raise SubjectUnknown() - return subjects_dict[subject_id] - - @filter_input - @enforce(("read", "write"), "subjects") - def del_subject(self, user_id, intra_extension_id, subject_id): - if subject_id not in self.driver.get_subjects_dict(intra_extension_id): - raise SubjectUnknown() - # Destroy assignments related to this category - for subject_category_id in self.driver.get_subject_categories_dict(intra_extension_id): - for _subject_id in self.driver.get_subjects_dict(intra_extension_id): - for assignment_id in self.driver.get_subject_assignment_list(intra_extension_id, _subject_id, subject_category_id): - self.driver.del_subject_assignment(intra_extension_id, _subject_id, subject_category_id, assignment_id) - self.driver.del_subject(intra_extension_id, subject_id) - - @filter_input - @enforce(("read", "write"), "subjects") - def set_subject_dict(self, user_id, intra_extension_id, subject_id, subject_dict): - subjects_dict = self.driver.get_subjects_dict(intra_extension_id) - for subject_id in subjects_dict: - if subjects_dict[subject_id]["name"] == subject_dict['name']: - raise SubjectNameExisting("Subject {} already exists!".format(subject_dict['name'])) - # Next line will raise an error if user is not present in Keystone database - subject_keystone_dict = self.identity_api.get_user_by_name(subject_dict['name'], "default") - subject_dict["keystone_id"] = subject_keystone_dict["id"] - subject_dict["keystone_name"] = subject_keystone_dict["name"] - return self.driver.set_subject_dict(intra_extension_id, subject_dict["id"], subject_dict) - - @filter_input - def get_subject_dict_from_keystone_id(self, tenant_id, intra_extension_id, keystone_id): - tenants_dict = self.tenant_api.driver.get_tenants_dict() - if tenant_id not in tenants_dict: - raise TenantUnknown() - if intra_extension_id not in (tenants_dict[tenant_id]['intra_authz_extension_id'], - tenants_dict[tenant_id]['intra_admin_extension_id'], ): - raise IntraExtensionUnknown() - # Note (asteroide): We used self.root_admin_id because the user requesting this information - # may only know his keystone_id and not the subject ID in the requested intra_extension. - subjects_dict = self.get_subjects_dict(self.root_admin_id, intra_extension_id) - for subject_id in subjects_dict: - if keystone_id == subjects_dict[subject_id]['keystone_id']: - return {subject_id: subjects_dict[subject_id]} - - @filter_input - def get_subject_dict_from_keystone_name(self, tenant_id, intra_extension_id, keystone_name): - tenants_dict = self.tenant_api.driver.get_tenants_dict() - if tenant_id not in tenants_dict: - raise TenantUnknown() - if intra_extension_id not in (tenants_dict[tenant_id]['intra_authz_extension_id'], - tenants_dict[tenant_id]['intra_admin_extension_id'], ): - raise IntraExtensionUnknown() - # Note (asteroide): We used self.root_admin_id because the user requesting this information - # may only know his keystone_name and not the subject ID in the requested intra_extension. - subjects_dict = self.get_subjects_dict(self.root_admin_id, intra_extension_id) - for subject_id in subjects_dict: - if keystone_name == subjects_dict[subject_id]['keystone_name']: - return {subject_id: subjects_dict[subject_id]} - - @filter_input - @enforce("read", "objects") - def get_objects_dict(self, user_id, intra_extension_id): - return self.driver.get_objects_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "objects") - def add_object_dict(self, user_id, intra_extension_id, object_dict): - objects_dict = self.driver.get_objects_dict(intra_extension_id) - object_id = uuid4().hex - if "id" in object_dict: - object_id = object_dict['id'] - for _object_id in objects_dict: - if objects_dict[_object_id]["name"] == object_dict['name']: - raise ObjectNameExisting("Object {} already exist!".format(object_dict['name'])) - return self.driver.set_object_dict(intra_extension_id, object_id, object_dict) - - @filter_input - @enforce("read", "objects") - def get_object_dict(self, user_id, intra_extension_id, object_id): - objects_dict = self.driver.get_objects_dict(intra_extension_id) - if object_id not in objects_dict: - raise ObjectUnknown("Unknown object id: {}".format(object_id)) - return objects_dict[object_id] - - @filter_input - @enforce(("read", "write"), "objects") - def del_object(self, user_id, intra_extension_id, object_id): - if object_id not in self.driver.get_objects_dict(intra_extension_id): - raise ObjectUnknown("Unknown object id: {}".format(object_id)) - # Destroy assignments related to this category - for object_category_id in self.driver.get_object_categories_dict(intra_extension_id): - for _object_id in self.driver.get_objects_dict(intra_extension_id): - for assignment_id in self.driver.get_object_assignment_list(intra_extension_id, _object_id, object_category_id): - self.driver.del_object_assignment(intra_extension_id, _object_id, object_category_id, assignment_id) - self.driver.del_object(intra_extension_id, object_id) - - @filter_input - @enforce(("read", "write"), "objects") - def set_object_dict(self, user_id, intra_extension_id, object_id, object_dict): - objects_dict = self.driver.get_objects_dict(intra_extension_id) - for object_id in objects_dict: - if objects_dict[object_id]["name"] == object_dict['name']: - raise ObjectNameExisting() - return self.driver.set_object_dict(intra_extension_id, object_id, object_dict) - - @filter_input - @enforce("read", "actions") - def get_actions_dict(self, user_id, intra_extension_id): - return self.driver.get_actions_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "actions") - def add_action_dict(self, user_id, intra_extension_id, action_dict): - actions_dict = self.driver.get_actions_dict(intra_extension_id) - for action_id in actions_dict: - if actions_dict[action_id]["name"] == action_dict['name']: - raise ActionNameExisting() - return self.driver.set_action_dict(intra_extension_id, uuid4().hex, action_dict) - - @filter_input - @enforce("read", "actions") - def get_action_dict(self, user_id, intra_extension_id, action_id): - actions_dict = self.driver.get_actions_dict(intra_extension_id) - if action_id not in actions_dict: - raise ActionUnknown() - return actions_dict[action_id] - - @filter_input - @enforce(("read", "write"), "actions") - def del_action(self, user_id, intra_extension_id, action_id): - if action_id not in self.driver.get_actions_dict(intra_extension_id): - raise ActionUnknown() - # Destroy assignments related to this category - for action_category_id in self.driver.get_action_categories_dict(intra_extension_id): - for _action_id in self.driver.get_actions_dict(intra_extension_id): - for assignment_id in self.driver.get_action_assignment_list(intra_extension_id, _action_id, action_category_id): - self.driver.del_action_assignment(intra_extension_id, _action_id, action_category_id, assignment_id) - return self.driver.del_action(intra_extension_id, action_id) - - @filter_input - @enforce(("read", "write"), "actions") - def set_action_dict(self, user_id, intra_extension_id, action_id, action_dict): - actions_dict = self.driver.get_actions_dict(intra_extension_id) - for action_id in actions_dict: - if actions_dict[action_id]["name"] == action_dict['name']: - raise ActionNameExisting() - return self.driver.set_action_dict(intra_extension_id, action_id, action_dict) - - # Scope functions - - @filter_input - @enforce("read", "subject_scopes") - @enforce("read", "subject_categories") - def get_subject_scopes_dict(self, user_id, intra_extension_id, subject_category_id): - """ - :param user_id: - :param intra_extension_id: - :param subject_category_id: - :return: { - subject_scope_id1: { - name: xxx, - des: aaa}, - subject_scope_id2: { - name: yyy, - des: bbb}, - ...} - """ - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - return self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id) - - @filter_input - @enforce(("read", "write"), "subject_scopes") - @enforce("read", "subject_categories") - def add_subject_scope_dict(self, user_id, intra_extension_id, subject_category_id, subject_scope_dict): - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - subject_scopes_dict = self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id) - for _subject_scope_id in subject_scopes_dict: - if subject_scope_dict['name'] == subject_scopes_dict[_subject_scope_id]['name']: - raise SubjectScopeNameExisting() - return self.driver.set_subject_scope_dict(intra_extension_id, subject_category_id, uuid4().hex, subject_scope_dict) - - @filter_input - @enforce("read", "subject_scopes") - @enforce("read", "subject_categories") - def get_subject_scope_dict(self, user_id, intra_extension_id, subject_category_id, subject_scope_id): - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - subject_scopes_dict = self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id) - if subject_scope_id not in subject_scopes_dict: - raise SubjectScopeUnknown() - return subject_scopes_dict[subject_scope_id] - - @filter_input - @enforce(("read", "write"), "subject_scopes") - @enforce("read", "subject_categories") - def del_subject_scope(self, user_id, intra_extension_id, subject_category_id, subject_scope_id): - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - if subject_scope_id not in self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id): - raise SubjectScopeUnknown() - # Destroy scope-related assignment - for subject_id in self.driver.get_subjects_dict(intra_extension_id): - for assignment_id in self.driver.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id): - self.driver.del_subject_assignment(intra_extension_id, subject_id, subject_category_id, assignment_id) - # Destroy scope-related rule - for sub_meta_rule_id in self.driver.get_sub_meta_rules_dict(intra_extension_id): - rules_dict = self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id) - for rule_id in rules_dict: - if subject_scope_id in rules_dict[rule_id]: - self.driver.del_rule(intra_extension_id, sub_meta_rule_id, rule_id) - self.driver.del_subject_scope(intra_extension_id, subject_category_id, subject_scope_id) - - @filter_input - @enforce(("read", "write"), "subject_scopes") - @enforce("read", "subject_categories") - def set_subject_scope_dict(self, user_id, intra_extension_id, subject_category_id, subject_scope_id, subject_scope_dict): - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - subject_scopes_dict = self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id) - for _subject_scope_id in subject_scopes_dict: - if subject_scopes_dict[_subject_scope_id]['name'] == subject_scope_dict['name']: - raise SubjectScopeNameExisting() - return self.driver.set_subject_scope_dict(intra_extension_id, subject_category_id, subject_scope_id, subject_scope_dict) - - @filter_input - @enforce("read", "object_scopes") - @enforce("read", "object_categories") - def get_object_scopes_dict(self, user_id, intra_extension_id, object_category_id): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - return self.driver.get_object_scopes_dict(intra_extension_id, object_category_id) - - @filter_input - @enforce(("read", "write"), "object_scopes") - @enforce("read", "object_categories") - def add_object_scope_dict(self, user_id, intra_extension_id, object_category_id, object_scope_dict): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - object_scopes_dict = self.driver.get_object_scopes_dict(intra_extension_id, object_category_id) - for _object_scope_id in object_scopes_dict: - if object_scopes_dict[_object_scope_id]['name'] == object_scope_dict['name']: - raise ObjectScopeNameExisting() - return self.driver.set_object_scope_dict(intra_extension_id, object_category_id, uuid4().hex, object_scope_dict) - - @filter_input - @enforce("read", "object_scopes") - @enforce("read", "object_categories") - def get_object_scope_dict(self, user_id, intra_extension_id, object_category_id, object_scope_id): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - object_scopes_dict = self.driver.get_object_scopes_dict(intra_extension_id, object_category_id) - if object_scope_id not in object_scopes_dict: - raise ObjectScopeUnknown() - return object_scopes_dict[object_scope_id] - - @filter_input - @enforce(("read", "write"), "object_scopes") - @enforce("read", "object_categories") - def del_object_scope(self, user_id, intra_extension_id, object_category_id, object_scope_id): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - if object_scope_id not in self.driver.get_object_scopes_dict(intra_extension_id, object_category_id): - raise ObjectScopeUnknown() - # Destroy scope-related assignment - for object_id in self.driver.get_objects_dict(intra_extension_id): - for assignment_id in self.driver.get_object_assignment_list(intra_extension_id, object_id, object_category_id): - self.driver.del_object_assignment(intra_extension_id, object_id, object_category_id, assignment_id) - # Destroy scope-related rule - for sub_meta_rule_id in self.driver.get_sub_meta_rules_dict(intra_extension_id): - rules_dict = self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id) - for rule_id in rules_dict: - if object_scope_id in rules_dict[rule_id]: - self.driver.del_rule(intra_extension_id, sub_meta_rule_id, rule_id) - self.driver.del_object_scope(intra_extension_id, object_category_id, object_scope_id) - - @filter_input - @enforce(("read", "write"), "object_scopes") - @enforce("read", "object_categories") - def set_object_scope_dict(self, user_id, intra_extension_id, object_category_id, object_scope_id, object_scope_dict): - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - object_scopes_dict = self.driver.get_object_scopes_dict(intra_extension_id, object_category_id) - for _object_scope_id in object_scopes_dict: - if object_scopes_dict[_object_scope_id]['name'] == object_scope_dict['name']: - raise ObjectScopeNameExisting() - return self.driver.set_object_scope_dict(intra_extension_id, object_category_id, object_scope_id, object_scope_dict) - - @filter_input - @enforce("read", "action_scopes") - @enforce("read", "action_categories") - def get_action_scopes_dict(self, user_id, intra_extension_id, action_category_id): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - return self.driver.get_action_scopes_dict(intra_extension_id, action_category_id) - - @filter_input - @enforce(("read", "write"), "action_scopes") - @enforce("read", "action_categories") - def add_action_scope_dict(self, user_id, intra_extension_id, action_category_id, action_scope_dict): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - action_scopes_dict = self.driver.get_action_scopes_dict(intra_extension_id, action_category_id) - for _action_scope_id in action_scopes_dict: - if action_scopes_dict[_action_scope_id]['name'] == action_scope_dict['name']: - raise ActionScopeNameExisting() - return self.driver.set_action_scope_dict(intra_extension_id, action_category_id, uuid4().hex, action_scope_dict) - - @filter_input - @enforce("read", "action_scopes") - @enforce("read", "action_categories") - def get_action_scope_dict(self, user_id, intra_extension_id, action_category_id, action_scope_id): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - action_scopes_dict = self.driver.get_action_scopes_dict(intra_extension_id, action_category_id) - if action_scope_id not in action_scopes_dict: - raise ActionScopeUnknown() - return action_scopes_dict[action_scope_id] - - @filter_input - @enforce(("read", "write"), "action_scopes") - @enforce("read", "action_categories") - def del_action_scope(self, user_id, intra_extension_id, action_category_id, action_scope_id): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - if action_scope_id not in self.driver.get_action_scopes_dict(intra_extension_id, action_category_id): - raise ActionScopeUnknown() - # Destroy scope-related assignment - for action_id in self.driver.get_actions_dict(intra_extension_id): - for assignment_id in self.driver.get_action_assignment_list(intra_extension_id, action_id, action_category_id): - self.driver.del_action_assignment(intra_extension_id, action_id, action_category_id, assignment_id) - # Destroy scope-related rule - for sub_meta_rule_id in self.driver.get_sub_meta_rules_dict(intra_extension_id): - rules_dict = self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id) - for rule_id in rules_dict: - if action_scope_id in rules_dict[rule_id]: - self.driver.del_rule(intra_extension_id, sub_meta_rule_id, rule_id) - self.driver.del_action_scope(intra_extension_id, action_category_id, action_scope_id) - - @filter_input - @enforce(("read", "write"), "action_scopes") - @enforce("read", "action_categories") - def set_action_scope_dict(self, user_id, intra_extension_id, action_category_id, action_scope_id, action_scope_dict): - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - action_scopes_dict = self.driver.get_action_scopes_dict(intra_extension_id, action_category_id) - for _action_scope_id in action_scopes_dict: - if action_scopes_dict[_action_scope_id]['name'] == action_scope_dict['name']: - raise ActionScopeNameExisting() - return self.driver.set_action_scope_dict(intra_extension_id, action_category_id, action_scope_id, action_scope_dict) - - # Assignment functions - - @filter_input - @enforce("read", "subject_assignments") - @enforce("read", "subjects") - @enforce("read", "subject_categories") - def get_subject_assignment_list(self, user_id, intra_extension_id, subject_id, subject_category_id): - """ - :param user_id: - :param intra_extension_id: - :param subject_id: - :param subject_category_id: - :return: [ - subject_scope_id1, ..., subject_scope_idn - ] - """ - if subject_id not in self.driver.get_subjects_dict(intra_extension_id): - raise SubjectUnknown() - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - return self.driver.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id) - - @filter_input - @enforce(("read", "write"), "subject_assignments") - @enforce("read", "subjects") - @enforce("read", "subject_categories") - @enforce("read", "subject_scopes") - def add_subject_assignment_list(self, user_id, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - if subject_id not in self.driver.get_subjects_dict(intra_extension_id): - raise SubjectUnknown() - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - if subject_scope_id not in self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id): - raise SubjectScopeUnknown() - elif subject_scope_id in self.driver.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id): - raise SubjectAssignmentExisting() - return self.driver.add_subject_assignment_list(intra_extension_id, subject_id, subject_category_id, subject_scope_id) - - @filter_input - @enforce(("read", "write"), "subject_assignments") - @enforce("read", "subjects") - @enforce("read", "subject_categories") - @enforce("read", "subject_scopes") - def del_subject_assignment(self, user_id, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - if subject_id not in self.driver.get_subjects_dict(intra_extension_id): - raise SubjectUnknown() - if subject_category_id not in self.driver.get_subject_categories_dict(intra_extension_id): - raise SubjectCategoryUnknown() - if subject_scope_id not in self.driver.get_subject_scopes_dict(intra_extension_id, subject_category_id): - raise SubjectScopeUnknown() - elif subject_scope_id not in self.driver.get_subject_assignment_list(intra_extension_id, subject_id, subject_category_id): - raise SubjectAssignmentUnknown() - self.driver.del_subject_assignment(intra_extension_id, subject_id, subject_category_id, subject_scope_id) - - @filter_input - @enforce("read", "object_assignments") - @enforce("read", "objects") - @enforce("read", "object_categories") - def get_object_assignment_list(self, user_id, intra_extension_id, object_id, object_category_id): - if object_id not in self.driver.get_objects_dict(intra_extension_id): - raise ObjectUnknown("Unknown object id: {}".format(object_id)) - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - return self.driver.get_object_assignment_list(intra_extension_id, object_id, object_category_id) - - @filter_input - @enforce(("read", "write"), "object_assignments") - @enforce("read", "objects") - @enforce("read", "object_categories") - def add_object_assignment_list(self, user_id, intra_extension_id, object_id, object_category_id, object_scope_id): - if object_id not in self.driver.get_objects_dict(intra_extension_id): - raise ObjectUnknown("Unknown object id: {}".format(object_id)) - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - if object_scope_id not in self.driver.get_object_scopes_dict(intra_extension_id, object_category_id): - raise ObjectScopeUnknown() - elif object_scope_id in self.driver.get_object_assignment_list(intra_extension_id, object_id, object_category_id): - raise ObjectAssignmentExisting() - return self.driver.add_object_assignment_list(intra_extension_id, object_id, object_category_id, object_scope_id) - - @filter_input - @enforce(("read", "write"), "object_assignments") - @enforce("read", "objects") - @enforce("read", "object_categories") - @enforce("read", "object_scopes") - def del_object_assignment(self, user_id, intra_extension_id, object_id, object_category_id, object_scope_id): - if object_id not in self.driver.get_objects_dict(intra_extension_id): - raise ObjectUnknown("Unknown object id: {}".format(object_id)) - if object_category_id not in self.driver.get_object_categories_dict(intra_extension_id): - raise ObjectCategoryUnknown() - if object_scope_id not in self.driver.get_object_scopes_dict(intra_extension_id, object_category_id): - raise ObjectScopeUnknown() - elif object_scope_id not in self.driver.get_object_assignment_list(intra_extension_id, object_id, object_category_id): - raise ObjectAssignmentUnknown() - self.driver.del_object_assignment(intra_extension_id, object_id, object_category_id, object_scope_id) - - @filter_input - @enforce("read", "action_assignments") - @enforce("read", "actions") - @enforce("read", "action_categories") - def get_action_assignment_list(self, user_id, intra_extension_id, action_id, action_category_id): - if action_id not in self.driver.get_actions_dict(intra_extension_id): - raise ActionUnknown() - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - return self.driver.get_action_assignment_list(intra_extension_id, action_id, action_category_id) - - @filter_input - @enforce(("read", "write"), "action_assignments") - @enforce("read", "actions") - @enforce("read", "action_categories") - def add_action_assignment_list(self, user_id, intra_extension_id, action_id, action_category_id, action_scope_id): - if action_id not in self.driver.get_actions_dict(intra_extension_id): - raise ActionUnknown() - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - if action_scope_id not in self.driver.get_action_scopes_dict(intra_extension_id, action_category_id): - raise ActionScopeUnknown() - elif action_scope_id in self.driver.get_action_assignment_list(intra_extension_id, action_id, action_category_id): - raise ObjectAssignmentExisting() - return self.driver.add_action_assignment_list(intra_extension_id, action_id, action_category_id, action_scope_id) - - @filter_input - @enforce(("read", "write"), "action_assignments") - @enforce("read", "actions") - @enforce("read", "action_categories") - @enforce("read", "action_scopes") - def del_action_assignment(self, user_id, intra_extension_id, action_id, action_category_id, action_scope_id): - if action_id not in self.driver.get_actions_dict(intra_extension_id): - raise ActionUnknown() - if action_category_id not in self.driver.get_action_categories_dict(intra_extension_id): - raise ActionCategoryUnknown() - if action_scope_id not in self.driver.get_action_scopes_dict(intra_extension_id, action_category_id): - raise ActionScopeUnknown() - elif action_scope_id not in self.driver.get_action_assignment_list(intra_extension_id, action_id, action_category_id): - raise ActionAssignmentUnknown() - self.driver.del_action_assignment(intra_extension_id, action_id, action_category_id, action_scope_id) - - # Metarule functions - - @filter_input - @enforce("read", "aggregation_algorithm") - def get_aggregation_algorithm_id(self, user_id, intra_extension_id): - """ - :param user_id: - :param intra_extension_id: - :return: { - aggregation_algorithm_id: {name: xxx, description: yyy} - } - """ - aggregation_algorithm_id = self.driver.get_aggregation_algorithm_id(intra_extension_id) - if not aggregation_algorithm_id: - raise AggregationAlgorithmNotExisting() - return aggregation_algorithm_id - - @filter_input - @enforce(("read", "write"), "aggregation_algorithm") - def set_aggregation_algorithm_id(self, user_id, intra_extension_id, aggregation_algorithm_id): - if aggregation_algorithm_id: - if aggregation_algorithm_id not in self.configuration_api.get_aggregation_algorithms_dict( - self.root_admin_id): - raise AggregationAlgorithmUnknown() - return self.driver.set_aggregation_algorithm_id(intra_extension_id, aggregation_algorithm_id) - - @filter_input - @enforce("read", "sub_meta_rules") - def get_sub_meta_rules_dict(self, user_id, intra_extension_id): - """ - :param user_id: - :param intra_extension_id: - :return: { - sub_meta_rule_id_1: { - "name": xxx, - "algorithm": yyy, - "subject_categories": [subject_category_id1, subject_category_id2,...], - "object_categories": [object_category_id1, object_category_id2,...], - "action_categories": [action_category_id1, action_category_id2,...] - sub_meta_rule_id_2: {...} - ... - } - """ - return self.driver.get_sub_meta_rules_dict(intra_extension_id) - - @filter_input - @enforce(("read", "write"), "sub_meta_rules") - @enforce("write", "rules") - def add_sub_meta_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_dict): - LOG.info("add_sub_meta_rule_dict = {}".format(self.driver.get_sub_meta_rules_dict(intra_extension_id))) - LOG.info("add_sub_meta_rule_dict = {}".format(sub_meta_rule_dict)) - sub_meta_rules_dict = self.driver.get_sub_meta_rules_dict(intra_extension_id) - for _sub_meta_rule_id in sub_meta_rules_dict: - if sub_meta_rule_dict['name'] == sub_meta_rules_dict[_sub_meta_rule_id]["name"]: - raise SubMetaRuleNameExisting() - if sub_meta_rule_dict['subject_categories'] == sub_meta_rules_dict[_sub_meta_rule_id]["subject_categories"] and \ - sub_meta_rule_dict['object_categories'] == sub_meta_rules_dict[_sub_meta_rule_id]["object_categories"] and \ - sub_meta_rule_dict['action_categories'] == sub_meta_rules_dict[_sub_meta_rule_id]["action_categories"] and \ - sub_meta_rule_dict['algorithm'] == sub_meta_rules_dict[_sub_meta_rule_id]["algorithm"]: - raise SubMetaRuleExisting() - algorithm_names = map(lambda x: x['name'], - self.configuration_api.get_sub_meta_rule_algorithms_dict(user_id).values()) - if sub_meta_rule_dict['algorithm'] not in algorithm_names: - raise SubMetaRuleAlgorithmNotExisting() - sub_meta_rule_id = uuid4().hex - # TODO (dthom): add new sub-meta-rule to rule dict - # self.driver.add_rule(intra_extension_id, sub_meta_rule_id, []) - return self.driver.set_sub_meta_rule_dict(intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict) - - @filter_input - @enforce(("read", "write"), "sub_meta_rules") - def get_sub_meta_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id): - sub_meta_rule_dict = self.driver.get_sub_meta_rules_dict(intra_extension_id) - if sub_meta_rule_id not in sub_meta_rule_dict: - raise SubMetaRuleUnknown() - return sub_meta_rule_dict[sub_meta_rule_id] - - @filter_input - @enforce(("read", "write"), "sub_meta_rules") - @enforce(("read", "write"), "rules") - def del_sub_meta_rule(self, user_id, intra_extension_id, sub_meta_rule_id): - if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): - raise SubMetaRuleUnknown() - for rule_id in self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id): - self.del_rule(intra_extension_id, sub_meta_rule_id, rule_id) - self.driver.del_sub_meta_rule(intra_extension_id, sub_meta_rule_id) - - @filter_input - @enforce(("read", "write"), "sub_meta_rules") - @enforce("write", "rules") - def set_sub_meta_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict): - LOG.info("set_sub_meta_rule_dict = {}".format(self.driver.get_sub_meta_rules_dict(intra_extension_id))) - LOG.info("set_sub_meta_rule_dict = {} {}".format(sub_meta_rule_id, sub_meta_rule_dict)) - if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): - raise SubMetaRuleUnknown() - for attribute in sub_meta_rule_dict.keys(): - if not sub_meta_rule_dict[attribute]: - sub_meta_rule_dict.pop(attribute) - return self.driver.set_sub_meta_rule_dict(intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict) - - # Rule functions - @filter_input - @enforce("read", "rules") - def get_rules_dict(self, user_id, intra_extension_id, sub_meta_rule_id): - """ - :param user_id: - :param intra_extension_id: - :param sub_meta_rule_id: - :return: { - rule_id1: [subject_scope1, subject_scope2, ..., action_scope1, ..., object_scope1, ... ], - rule_id2: [subject_scope3, subject_scope4, ..., action_scope3, ..., object_scope3, ... ], - ...} - """ - return self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id) - - @filter_input - @enforce("read", "sub_meta_rules") - @enforce(("read", "write"), "rules") - def add_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, rule_list): - if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): - raise SubMetaRuleUnknown() - if rule_list in self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id).values(): - raise RuleExisting() - return self.driver.set_rule_dict(intra_extension_id, sub_meta_rule_id, uuid4().hex, rule_list) - - @filter_input - @enforce("read", "sub_meta_rules") - @enforce("read", "rules") - def get_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, rule_id): - if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): - raise SubMetaRuleUnknown() - rules_dict = self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id) - if rule_id not in rules_dict: - raise RuleUnknown() - return rules_dict[rule_id] - - @filter_input - @enforce("read", "sub_meta_rules") - @enforce(("read", "write"), "rules") - def del_rule(self, user_id, intra_extension_id, sub_meta_rule_id, rule_id): - if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): - raise SubMetaRuleUnknown() - if rule_id not in self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id): - raise RuleUnknown() - self.driver.del_rule(intra_extension_id, sub_meta_rule_id, rule_id) - - @filter_input - @enforce("read", "sub_meta_rules") - @enforce(("read", "write"), "rules") - def set_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, rule_id, rule_list): - if sub_meta_rule_id not in self.driver.get_sub_meta_rules_dict(intra_extension_id): - raise SubMetaRuleUnknown() - if rule_id not in self.driver.get_rules_dict(intra_extension_id, sub_meta_rule_id): - raise RuleUnknown() - return self.driver.set_rule_dict(intra_extension_id, sub_meta_rule_id, rule_id, rule_list) - - -@dependency.provider('authz_api') -class IntraExtensionAuthzManager(IntraExtensionManager): - - def __init__(self): - super(IntraExtensionAuthzManager, self).__init__() - - def __authz(self, tenant_id, subject_k_id, object_name, action_name, genre="authz"): - """Check authorization for a particular action. - :return: True or False or raise an exception - """ - if genre == "authz": - genre = "intra_authz_extension_id" - elif genre == "admin": - genre = "intra_admin_extension_id" - - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - - if tenant_id not in tenants_dict: - # raise TenantUnknown("Cannot authz because Tenant is unknown {}".format(tenant_id)) - LOG.warning("Cannot authz because Tenant is not managed by Moon {}".format(tenant_id)) - return {'authz': True, 'comment': "Cannot authz because Tenant is not managed by Moon {}".format(tenant_id)} - intra_extension_id = tenants_dict[tenant_id][genre] - if not intra_extension_id: - raise TenantNoIntraExtension() - subjects_dict = self.driver.get_subjects_dict(intra_extension_id) - subject_id = None - for _subject_id in subjects_dict: - if subjects_dict[_subject_id]['keystone_id'] == subject_k_id: - subject_id = _subject_id - break - if not subject_id: - raise SubjectUnknown("Unknown subject id: {}".format(subject_k_id)) - objects_dict = self.driver.get_objects_dict(intra_extension_id) - object_id = None - for _object_id in objects_dict: - if objects_dict[_object_id]['name'] == object_name: - object_id = _object_id - break - if not object_id: - raise ObjectUnknown("Unknown object name: {}".format(object_name)) - - actions_dict = self.driver.get_actions_dict(intra_extension_id) - action_id = None - for _action_id in actions_dict: - if actions_dict[_action_id]['name'] == action_name: - action_id = _action_id - break - if not action_id: - raise ActionUnknown("Unknown action name: {}".format(action_name)) - return super(IntraExtensionAuthzManager, self).authz(intra_extension_id, subject_id, object_id, action_id) - - def authz(self, tenant_id, subject_k_id, object_name, action_name, genre="authz"): - try: - return self.__authz(tenant_id, subject_k_id, object_name, action_name, genre="authz") - except (SubjectUnknown, ObjectUnknown, ActionUnknown) as e: - # maybe we need to synchronize with the master - if CONF.moon.master: - self.get_data_from_master() - return self.__authz(tenant_id, subject_k_id, object_name, action_name, genre="authz") - raise e - except TenantNoIntraExtension: - return {'authz': True, 'comment': "Cannot authz because Tenant is not managed by Moon {}".format(tenant_id)} - - def add_subject_dict(self, user_id, intra_extension_id, subject_dict): - subject = super(IntraExtensionAuthzManager, self).add_subject_dict(user_id, intra_extension_id, subject_dict) - subject_id, subject_value = subject.iteritems().next() - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]["intra_admin_extension_id"] and \ - tenants_dict[tenant_id]["intra_authz_extension_id"] == intra_extension_id: - _subjects = self.driver.get_subjects_dict(tenants_dict[tenant_id]["intra_admin_extension_id"]) - if subject_value["name"] not in [_subjects[_id]["name"] for _id in _subjects]: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_admin_extension_id"], uuid4().hex, subject_value) - break - if tenants_dict[tenant_id]["intra_authz_extension_id"] and \ - tenants_dict[tenant_id]["intra_admin_extension_id"] == intra_extension_id: - _subjects = self.driver.get_subjects_dict(tenants_dict[tenant_id]["intra_authz_extension_id"]) - if subject_value["name"] not in [_subjects[_id]["name"] for _id in _subjects]: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_authz_extension_id"], uuid4().hex, subject_value) - break - return subject - - def del_subject(self, user_id, intra_extension_id, subject_id): - subject_name = self.driver.get_subjects_dict(intra_extension_id)[subject_id]["name"] - super(IntraExtensionAuthzManager, self).del_subject(user_id, intra_extension_id, subject_id) - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]["intra_authz_extension_id"] == intra_extension_id and \ - tenants_dict[tenant_id]["intra_admin_extension_id"]: - subject_id = self.driver.get_uuid_from_name(tenants_dict[tenant_id]["intra_admin_extension_id"], - subject_name, - self.driver.SUBJECT) - self.driver.del_subject(tenants_dict[tenant_id]["intra_admin_extension_id"], subject_id) - break - if tenants_dict[tenant_id]["intra_admin_extension_id"] == intra_extension_id and \ - tenants_dict[tenant_id]["intra_authz_extension_id"]: - subject_id = self.driver.get_uuid_from_name(tenants_dict[tenant_id]["intra_authz_extension_id"], - subject_name, - self.driver.SUBJECT) - self.driver.del_subject(tenants_dict[tenant_id]["intra_authz_extension_id"], subject_id) - break - - def set_subject_dict(self, user_id, intra_extension_id, subject_id, subject_dict): - subject = super(IntraExtensionAuthzManager, self).set_subject_dict(user_id, intra_extension_id, subject_dict) - subject_id, subject_value = subject.iteritems().next() - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]["intra_authz_extension_id"] == intra_extension_id: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_admin_extension_id"], uuid4().hex, subject_value) - break - if tenants_dict[tenant_id]["intra_admin_extension_id"] == intra_extension_id: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_authz_extension_id"], uuid4().hex, subject_value) - break - return subject - - def add_subject_category(self, user_id, intra_extension_id, subject_category_dict): - raise AuthzException("add_subject_category") - - def del_subject_category(self, user_id, intra_extension_id, subject_category_id): - raise AuthzException("del_subject_category") - - def set_subject_category(self, user_id, intra_extension_id, subject_category_id, subject_category_dict): - raise AuthzException("set_subject_category") - - def add_object_category(self, user_id, intra_extension_id, object_category_dict): - raise AuthzException("add_object_category") - - def del_object_category(self, user_id, intra_extension_id, object_category_id): - raise AuthzException("del_object_category") - - def add_action_category(self, user_id, intra_extension_id, action_category_name): - raise AuthzException("add_action_category") - - def del_action_category(self, user_id, intra_extension_id, action_category_id): - raise AuthzException("del_action_category") - - def add_object_dict(self, user_id, intra_extension_id, object_name): - raise AuthzException("add_object_dict") - - def set_object_dict(self, user_id, intra_extension_id, object_id, object_dict): - raise AuthzException("set_object_dict") - - def del_object(self, user_id, intra_extension_id, object_id): - raise AuthzException("del_object") - - def add_action_dict(self, user_id, intra_extension_id, action_name): - raise AuthzException("add_action_dict") - - def set_action_dict(self, user_id, intra_extension_id, action_id, action_dict): - raise AuthzException("set_action_dict") - - def del_action(self, user_id, intra_extension_id, action_id): - raise AuthzException("del_action") - - def add_subject_scope_dict(self, user_id, intra_extension_id, subject_category_id, subject_scope_dict): - raise AuthzException("add_subject_scope_dict") - - def del_subject_scope(self, user_id, intra_extension_id, subject_category_id, subject_scope_id): - raise AuthzException("del_subject_scope") - - def set_subject_scope_dict(self, user_id, intra_extension_id, subject_category_id, subject_scope_id, subject_scope_name): - raise AuthzException("set_subject_scope_dict") - - def add_object_scope_dict(self, user_id, intra_extension_id, object_category_id, object_scope_name): - raise AuthzException("add_object_scope_dict") - - def del_object_scope(self, user_id, intra_extension_id, object_category_id, object_scope_id): - raise AuthzException("del_object_scope") - - def set_object_scope_dict(self, user_id, intra_extension_id, object_category_id, object_scope_id, object_scope_name): - raise AuthzException("set_object_scope_dict") - - def add_action_scope_dict(self, user_id, intra_extension_id, action_category_id, action_scope_name): - raise AuthzException("add_action_scope_dict") - - def del_action_scope(self, user_id, intra_extension_id, action_category_id, action_scope_id): - raise AuthzException("del_action_scope") - - def add_subject_assignment_list(self, user_id, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - raise AuthzException("add_subject_assignment_list") - - def del_subject_assignment(self, user_id, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - raise AuthzException("del_subject_assignment") - - def add_object_assignment_list(self, user_id, intra_extension_id, object_id, object_category_id, object_scope_id): - raise AuthzException("add_object_assignment_list") - - def del_object_assignment(self, user_id, intra_extension_id, object_id, object_category_id, object_scope_id): - raise AuthzException("del_object_assignment") - - def add_action_assignment_list(self, user_id, intra_extension_id, action_id, action_category_id, action_scope_id): - raise AuthzException("add_action_assignment_list") - - def del_action_assignment(self, user_id, intra_extension_id, action_id, action_category_id, action_scope_id): - raise AuthzException("del_action_assignment") - - def set_aggregation_algorithm_id(self, user_id, intra_extension_id, aggregation_algorithm_id): - raise AuthzException("set_aggregation_algorithm_id") - - def del_aggregation_algorithm_(self, user_id, intra_extension_id): - raise AuthzException("del_aggregation_algorithm_") - - def add_sub_meta_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_dict): - raise AuthzException("add_sub_meta_rule_dict") - - def del_sub_meta_rule(self, user_id, intra_extension_id, sub_meta_rule_id): - raise AuthzException("del_sub_meta_rule") - - def set_sub_meta_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, sub_meta_rule_dict): - raise AuthzException("set_sub_meta_rule_dict") - - def add_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, rule_list): - raise AuthzException("add_rule_dict") - - def del_rule(self, user_id, intra_extension_id, sub_meta_rule_id, rule_id): - raise AuthzException("del_rule") - - def set_rule_dict(self, user_id, intra_extension_id, sub_meta_rule_id, rule_id, rule_list): - raise AuthzException("set_rule_dict") - - -@dependency.provider('admin_api') -class IntraExtensionAdminManager(IntraExtensionManager): - - def __init__(self): - super(IntraExtensionAdminManager, self).__init__() - - def add_subject_dict(self, user_id, intra_extension_id, subject_dict): - subject = super(IntraExtensionAdminManager, self).add_subject_dict(user_id, intra_extension_id, subject_dict) - subject_id, subject_value = subject.iteritems().next() - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]["intra_admin_extension_id"] and \ - tenants_dict[tenant_id]["intra_authz_extension_id"] == intra_extension_id: - _subjects = self.driver.get_subjects_dict(tenants_dict[tenant_id]["intra_admin_extension_id"]) - if subject_value["name"] not in [_subjects[_id]["name"] for _id in _subjects]: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_admin_extension_id"], uuid4().hex, subject_value) - break - if tenants_dict[tenant_id]["intra_authz_extension_id"] and \ - tenants_dict[tenant_id]["intra_admin_extension_id"] == intra_extension_id: - _subjects = self.driver.get_subjects_dict(tenants_dict[tenant_id]["intra_authz_extension_id"]) - if subject_value["name"] not in [_subjects[_id]["name"] for _id in _subjects]: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_authz_extension_id"], uuid4().hex, subject_value) - break - return subject - - def del_subject(self, user_id, intra_extension_id, subject_id): - subject_name = self.driver.get_subjects_dict(intra_extension_id)[subject_id]["name"] - super(IntraExtensionAdminManager, self).del_subject(user_id, intra_extension_id, subject_id) - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]["intra_authz_extension_id"] == intra_extension_id and \ - tenants_dict[tenant_id]["intra_admin_extension_id"]: - subject_id = self.driver.get_uuid_from_name(tenants_dict[tenant_id]["intra_admin_extension_id"], - subject_name, - self.driver.SUBJECT) - self.driver.del_subject(tenants_dict[tenant_id]["intra_admin_extension_id"], subject_id) - break - if tenants_dict[tenant_id]["intra_admin_extension_id"] == intra_extension_id and \ - tenants_dict[tenant_id]["intra_authz_extension_id"]: - subject_id = self.driver.get_uuid_from_name(tenants_dict[tenant_id]["intra_authz_extension_id"], - subject_name, - self.driver.SUBJECT) - self.driver.del_subject(tenants_dict[tenant_id]["intra_authz_extension_id"], subject_id) - break - - def set_subject_dict(self, user_id, intra_extension_id, subject_id, subject_dict): - subject = super(IntraExtensionAdminManager, self).set_subject_dict(user_id, intra_extension_id, subject_dict) - subject_id, subject_value = subject.iteritems().next() - tenants_dict = self.tenant_api.get_tenants_dict(self.root_admin_id) - for tenant_id in tenants_dict: - if tenants_dict[tenant_id]["intra_authz_extension_id"] == intra_extension_id: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_admin_extension_id"], uuid4().hex, subject_value) - break - if tenants_dict[tenant_id]["intra_admin_extension_id"] == intra_extension_id: - self.driver.set_subject_dict(tenants_dict[tenant_id]["intra_authz_extension_id"], uuid4().hex, subject_value) - break - return subject - - def add_object_dict(self, user_id, intra_extension_id, object_name): - if "admin" == self.get_intra_extension_dict(self.root_admin_id, intra_extension_id)['genre']: - raise ObjectsWriteNoAuthorized() - return super(IntraExtensionAdminManager, self).add_object_dict(user_id, intra_extension_id, object_name) - - def set_object_dict(self, user_id, intra_extension_id, object_id, object_dict): - if "admin" == self.get_intra_extension_dict(self.root_admin_id, intra_extension_id)['genre']: - raise ObjectsWriteNoAuthorized() - return super(IntraExtensionAdminManager, self).set_object_dict(user_id, intra_extension_id, object_id, object_dict) - - def del_object(self, user_id, intra_extension_id, object_id): - if "admin" == self.get_intra_extension_dict(self.root_admin_id, intra_extension_id)['genre']: - raise ObjectsWriteNoAuthorized() - return super(IntraExtensionAdminManager, self).del_object(user_id, intra_extension_id, object_id) - - def add_action_dict(self, user_id, intra_extension_id, action_name): - if "admin" == self.get_intra_extension_dict(self.root_admin_id, intra_extension_id)['genre']: - raise ActionsWriteNoAuthorized() - return super(IntraExtensionAdminManager, self).add_action_dict(user_id, intra_extension_id, action_name) - - def set_action_dict(self, user_id, intra_extension_id, action_id, action_dict): - if "admin" == self.get_intra_extension_dict(self.root_admin_id, intra_extension_id)['genre']: - raise ActionsWriteNoAuthorized() - return super(IntraExtensionAdminManager, self).set_action_dict(user_id, intra_extension_id, action_id, action_dict) - - def del_action(self, user_id, intra_extension_id, action_id): - if "admin" == self.get_intra_extension_dict(self.root_admin_id, intra_extension_id)['genre']: - raise ActionsWriteNoAuthorized() - return super(IntraExtensionAdminManager, self).del_action(user_id, intra_extension_id, action_id) - - -@dependency.provider('root_api') -class IntraExtensionRootManager(IntraExtensionManager): - - def __init__(self): - super(IntraExtensionRootManager, self).__init__() - - def is_admin_subject(self, keystone_id): - for subject_id, subject_dict in self.driver.get_subjects_dict(self.root_extension_id).iteritems(): - if subject_id == keystone_id: - # subject_id may be a true id from an intra_extension - return True - if subject_dict["name"] == "admin" and subject_dict["keystone_id"] == keystone_id: - return True - return False - - -@dependency.provider('moonlog_api') -class LogManager(manager.Manager): - - driver_namespace = 'keystone.moon.log' - - def __init__(self): - driver = CONF.moon.log_driver - super(LogManager, self).__init__(driver) - - def get_logs(self, logger="authz", options="", event_number=None, time_from=None, time_to=None, filter_str=None): - - if len(options) > 0: - options = options.split(",") - event_number = None - time_from = None - time_to = None - filter_str = None - for opt in options: - if "event_number" in opt: - event_number = "".join(re.findall("\d*", opt.split("=")[-1])) - try: - event_number = int(event_number) - except ValueError: - event_number = None - elif "from" in opt: - time_from = "".join(re.findall("[\w\-:]*", opt.split("=")[-1])) - try: - time_from = time.strptime(time_from, self.TIME_FORMAT) - except ValueError: - time_from = None - elif "to" in opt: - time_to = "".join(re.findall("[\w\-:] *", opt.split("=")[-1])) - try: - time_to = time.strptime(time_to, self.TIME_FORMAT) - except ValueError: - time_to = None - elif "filter" in opt: - filter_str = "".join(re.findall("\w*", opt.split("=")[-1])) - return self.driver.get_logs(logger, event_number, time_from, time_to, filter_str) - - def get_authz_logs(self, options="", event_number=None, time_from=None, time_to=None, filter_str=None): - return self.get_logs( - logger="authz", - options="", - event_number=None, - time_from=None, - time_to=None, - filter_str=None) - - def get_sys_logs(self, options="", event_number=None, time_from=None, time_to=None, filter_str=None): - return self.get_logs( - logger="sys", - options="", - event_number=None, - time_from=None, - time_to=None, - filter_str=None) - - def authz(self, message): - return self.driver.authz(message) - - def debug(self, message): - return self.driver.debug(message) - - def info(self, message): - return self.driver.info(message) - - def warning(self, message): - return self.driver.warning(message) - - def error(self, message): - return self.driver.error(message) - - def critical(self, message): - return self.driver.critical(message) - - -class ConfigurationDriver(object): - - def get_policy_templates_dict(self): - raise exception.NotImplemented() # pragma: no cover - - def get_aggregation_algorithm_id(self): - raise exception.NotImplemented() # pragma: no cover - - def get_sub_meta_rule_algorithms_dict(self): - raise exception.NotImplemented() # pragma: no cover - - -class TenantDriver(object): - - def get_tenants_dict(self): - raise exception.NotImplemented() # pragma: no cover - - def add_tenant_dict(self, tenant_id, tenant_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_tenant_dict(self, tenant_id): - raise exception.NotImplemented() # pragma: no cover - - def set_tenant_dict(self, tenant_id, tenant_dict): - raise exception.NotImplemented() # pragma: no cover - - -class IntraExtensionDriver(object): - - SUBJECT = 'subject' - OBJECT = 'object' - ACTION = 'action' - SUBJECT_CATEGORY = 'subject_category' - OBJECT_CATEGORY = 'object_category' - ACTION_CATEGORY = 'action_category' - SUBJECT_SCOPE = 'subject_scope' - OBJECT_SCOPE = 'object_scope' - ACTION_SCOPE = 'action_scope' - SUB_META_RULE = 'sub_meta_rule' - - def __get_data_from_type(self, - intra_extension_uuid, - name=None, - uuid=None, - data_name=None, - category_name=None, - category_uuid=None): - - def extract_name(data_dict): - for key in data_dict: - try: - yield data_dict[key]["name"] - except KeyError: - for key2 in data_dict[key]: - yield data_dict[key][key2]["name"] - - data_values = list() - - if data_name == self.SUBJECT: - data_values = self.get_subjects_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise SubjectUnknown("{} / {}".format(name, data_values)) - elif data_name == self.OBJECT: - data_values = self.get_objects_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise ObjectUnknown("{} / {}".format(name, data_values)) - elif data_name == self.ACTION: - data_values = self.get_actions_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise ActionUnknown("{} / {}".format(name, data_values)) - elif data_name == self.SUBJECT_CATEGORY: - data_values = self.get_subject_categories_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise SubjectCategoryUnknown("{} / {}".format(name, data_values)) - elif data_name == self.OBJECT_CATEGORY: - data_values = self.get_object_categories_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise ObjectCategoryUnknown("{} / {}".format(name, data_values)) - elif data_name == self.ACTION_CATEGORY: - data_values = self.get_action_categories_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise ActionCategoryUnknown("{} / {}".format(name, data_values)) - elif data_name == self.SUBJECT_SCOPE: - if not category_uuid: - category_uuid = self.get_uuid_from_name(intra_extension_uuid, category_name, self.SUBJECT_CATEGORY) - data_values = self.get_subject_scopes_dict(intra_extension_uuid, - category_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise SubjectScopeUnknown("{} / {}".format(name, data_values)) - elif data_name == self.OBJECT_SCOPE: - if not category_uuid: - category_uuid = self.get_uuid_from_name(intra_extension_uuid, category_name, self.OBJECT_CATEGORY) - data_values = self.get_object_scopes_dict(intra_extension_uuid, - category_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise ObjectScopeUnknown("{} / {}".format(name, data_values)) - elif data_name == self.ACTION_SCOPE: - if not category_uuid: - category_uuid = self.get_uuid_from_name(intra_extension_uuid, category_name, self.ACTION_CATEGORY) - data_values = self.get_action_scopes_dict(intra_extension_uuid, - category_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise ActionScopeUnknown("{} / {}".format(name, data_values)) - elif data_name == self.SUB_META_RULE: - data_values = self.get_sub_meta_rules_dict(intra_extension_uuid) - if (name and name not in extract_name(data_values)) or \ - (uuid and uuid not in data_values.keys()): - raise SubMetaRuleUnknown("{} / {}".format(name, data_values)) - # if data_name in ( - # self.SUBJECT_SCOPE, - # self.OBJECT_SCOPE, - # self.ACTION_SCOPE - # ): - # return data_values[category_uuid] - return data_values - - def get_uuid_from_name(self, intra_extension_uuid, name, data_name, category_name=None, category_uuid=None): - data_values = self.__get_data_from_type( - intra_extension_uuid=intra_extension_uuid, - name=name, - data_name=data_name, - category_name=category_name, - category_uuid=category_uuid, - ) - return filter(lambda v: v[1]["name"] == name, data_values.iteritems())[0][0] - - def get_name_from_uuid(self, intra_extension_uuid, uuid, data_name, category_name=None, category_uuid=None): - data_values = self.__get_data_from_type( - intra_extension_uuid=intra_extension_uuid, - uuid=uuid, - data_name=data_name, - category_name=category_name, - category_uuid=category_uuid, - ) - return data_values[uuid] - - # Getter and Setter for intra_extension - - def get_intra_extensions_dict(self): - raise exception.NotImplemented() # pragma: no cover - - def del_intra_extension(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_intra_extension_dict(self, intra_extension_id, intra_extension_dict): - raise exception.NotImplemented() # pragma: no cover - - # Metadata functions - - def get_subject_categories_dict(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_subject_category_dict(self, intra_extension_id, subject_category_id, subject_category_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_subject_category(self, intra_extension_id, subject_category_id): - raise exception.NotImplemented() # pragma: no cover - - def get_object_categories_dict(self, intra_extension_id): - """Get a list of all object categories - - :param intra_extension_id: IntraExtension UUID - :type intra_extension_id: string - :return: a dictionary containing all object categories {"uuid1": "name1", "uuid2": "name2"} - """ - raise exception.NotImplemented() # pragma: no cover - - def set_object_category_dict(self, intra_extension_id, object_category_id, object_category_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_object_category(self, intra_extension_id, object_category_id): - raise exception.NotImplemented() # pragma: no cover - - def get_action_categories_dict(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_action_category_dict(self, intra_extension_id, action_category_id, action_category_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_action_category(self, intra_extension_id, action_category_id): - raise exception.NotImplemented() # pragma: no cover - - # Perimeter functions - - def get_subjects_dict(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_subject_dict(self, intra_extension_id, subject_id, subject_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_subject(self, intra_extension_id, subject_id): - raise exception.NotImplemented() # pragma: no cover - - def get_objects_dict(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_object_dict(self, intra_extension_id, object_id, object_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_object(self, intra_extension_id, object_id): - raise exception.NotImplemented() # pragma: no cover - - def get_actions_dict(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_action_dict(self, intra_extension_id, action_id, action_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_action(self, intra_extension_id, action_id): - raise exception.NotImplemented() # pragma: no cover - - # Scope functions - - def get_subject_scopes_dict(self, intra_extension_id, subject_category_id): - raise exception.NotImplemented() # pragma: no cover - - def set_subject_scope_dict(self, intra_extension_id, subject_category_id, subject_scope_id, subject_scope_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_subject_scope(self, intra_extension_id, subject_category_id, subject_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def get_object_scopes_dict(self, intra_extension_id, object_category_id): - raise exception.NotImplemented() # pragma: no cover - - def set_object_scope_dict(self, intra_extension_id, object_category_id, object_scope_id, object_scope_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_object_scope(self, intra_extension_id, object_category_id, object_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def get_action_scopes_dict(self, intra_extension_id, action_category_id): - raise exception.NotImplemented() # pragma: no cover - - def set_action_scope_dict(self, intra_extension_id, action_category_id, action_scope_id, action_scope_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_action_scope(self, intra_extension_id, action_category_id, action_scope_id): - raise exception.NotImplemented() # pragma: no cover - - # Assignment functions - - def get_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id): - raise exception.NotImplemented() # pragma: no cover - - def set_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id, subject_assignment_list): - raise exception.NotImplemented() # pragma: no cover - - def add_subject_assignment_list(self, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def del_subject_assignment(self, intra_extension_id, subject_id, subject_category_id, subject_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def get_object_assignment_list(self, intra_extension_id, object_id, object_category_id): - raise exception.NotImplemented() # pragma: no cover - - def set_object_assignment_list(self, intra_extension_id, object_id, object_category_id, object_assignment_list): - raise exception.NotImplemented() # pragma: no cover - - def add_object_assignment_list(self, intra_extension_id, object_id, object_category_id, object_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def del_object_assignment(self, intra_extension_id, object_id, object_category_id, object_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def get_action_assignment_list(self, intra_extension_id, action_id, action_category_id): - raise exception.NotImplemented() # pragma: no cover - - def set_action_assignment_list(self, intra_extension_id, action_id, action_category_id, action_assignment_list): - raise exception.NotImplemented() # pragma: no cover - - def add_action_assignment_list(self, intra_extension_id, action_id, action_category_id, action_scope_id): - raise exception.NotImplemented() # pragma: no cover - - def del_action_assignment(self, intra_extension_id, action_id, action_category_id, action_scope_id): - raise exception.NotImplemented() # pragma: no cover - - # Meta_rule functions - - def set_aggregation_algorithm_id(self, intra_extension_id, aggregation_algorithm_id): - raise exception.NotImplemented() # pragma: no cover - - def get_aggregation_algorithm_id(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def del_aggregation_algorithm(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def get_sub_meta_rules_dict(self, intra_extension_id): - raise exception.NotImplemented() # pragma: no cover - - def set_sub_meta_rule_dict(self, intra_extension_id, sub_meta_rule_id, meta_rule_dict): - raise exception.NotImplemented() # pragma: no cover - - def del_sub_meta_rule(self, intra_extension_id, sub_meta_rule_id): - raise exception.NotImplemented() # pragma: no cover - - # Rule functions - - def get_rules_dict(self, intra_extension_id, sub_meta_rule_id): - raise exception.NotImplemented() # pragma: no cover - - def set_rule_dict(self, intra_extension_id, sub_meta_rule_id, rule_id, rule_list): - raise exception.NotImplemented() # pragma: no cover - - def del_rule(self, intra_extension_id, sub_meta_rule_id, rule_id): - raise exception.NotImplemented() # pragma: no cover - - -class LogDriver(object): - - def authz(self, message): - """Log authorization message - - :param message: the message to log - :type message: string - :return: None - """ - raise exception.NotImplemented() # pragma: no cover - - def debug(self, message): - """Log debug message - - :param message: the message to log - :type message: string - :return: None - """ - raise exception.NotImplemented() # pragma: no cover - - def info(self, message): - """Log informational message - - :param message: the message to log - :type message: string - :return: None - """ - raise exception.NotImplemented() # pragma: no cover - - def warning(self, message): - """Log warning message - - :param message: the message to log - :type message: string - :return: None - """ - raise exception.NotImplemented() # pragma: no cover - - def error(self, message): - """Log error message - - :param message: the message to log - :type message: string - :return: None - """ - raise exception.NotImplemented() # pragma: no cover - - def critical(self, message): - """Log critical message - - :param message: the message to log - :type message: string - :return: None - """ - raise exception.NotImplemented() # pragma: no cover - - def get_logs(self, options): - """Get logs - - :param options: options to filter log events - :type options: string eg: "event_number=10,from=2014-01-01-10:10:10,to=2014-01-01-12:10:10,filter=expression" - :return: a list of log events - - TIME_FORMAT is '%Y-%m-%d-%H:%M:%S' - """ - raise exception.NotImplemented() # pragma: no cover - - -# @dependency.provider('interextension_api') -# @dependency.requires('identity_api') -# class InterExtensionManager(manager.Manager): -# -# def __init__(self): -# driver = CONF.moon.interextension_driver -# super(InterExtensionManager, self).__init__(driver) -# -# def check_inter_extension(self, uuid): -# if uuid not in self.get_inter_extensions(): -# LOG.error("Unknown InterExtension {}".format(uuid)) -# raise exception.NotFound("InterExtension not found.") -# -# def get_inter_extensions(self): -# return self.driver.get_inter_extensions() -# -# def get_inter_extension(self, uuid): -# return self.driver.get_inter_extension(uuid) -# -# def create_inter_extension(self, inter_extension): -# ie = dict() -# ie['id'] = uuid4().hex -# ie["requesting_intra_extension_uuid"] = filter_input(inter_extension["requesting_intra_extension_uuid"]) -# ie["requested_intra_extension_uuid"] = filter_input(inter_extension["requested_intra_extension_uuid"]) -# ie["description"] = filter_input(inter_extension["description"]) -# ie["virtual_entity_uuid"] = filter_input(inter_extension["virtual_entity_uuid"]) -# ie["genre"] = filter_input(inter_extension["genre"]) -# -# ref = self.driver.create_inter_extensions(ie['id'], ie) -# return ref -# -# def delete_inter_extension(self, inter_extension_id): -# LOG.error("Deleting {}".format(inter_extension_id)) -# ref = self.driver.delete_inter_extensions(inter_extension_id) -# return ref -# -# -# class InterExtensionDriver(object): -# -# # Getter and Setter for InterExtensions -# -# def get_inter_extensions(self): -# raise exception.NotImplemented() # pragma: no cover -# -# def get_inter_extension(self, uuid): -# raise exception.NotImplemented() # pragma: no cover -# -# def create_inter_extensions(self, intra_id, intra_extension): -# raise exception.NotImplemented() # pragma: no cover -# -# def delete_inter_extensions(self, intra_extension_id): -# raise exception.NotImplemented() # pragma: no cover -# -# -# class VirtualEntityDriver(object): -# -# # Getter and Setter for InterExtensions -# -# def get_virtual_entities(self): -# raise exception.NotImplemented() # pragma: no cover -# -# def create_virtual_entities(self, ve_id, virtual_entity): -# raise exception.NotImplemented() # pragma: no cover - diff --git a/keystone-moon/keystone/contrib/moon/exception.py b/keystone-moon/keystone/contrib/moon/exception.py deleted file mode 100644 index 4e9bf7c9..00000000 --- a/keystone-moon/keystone/contrib/moon/exception.py +++ /dev/null @@ -1,422 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -from keystone.common import dependency -from keystone.exception import Error -from keystone.i18n import _, _LW -import logging -from oslo_log import log - -LOG = log.getLogger(__name__) - - -class MoonErrorMetaClass(type): - - def __init__(cls, name, bases, dct): - super(MoonErrorMetaClass, cls).__init__(name, bases, dct) - cls.hierarchy += "/"+str(name) - - -@dependency.requires('moonlog_api') -class MoonError(Error): - __metaclass__ = MoonErrorMetaClass - hierarchy = "" - message_format = _("There is an error requesting the Moon platform.") - code = 400 - title = 'Moon Error' - logger = "ERROR" - - def __init__(self, message=""): - if message: - self.message_format = message - super(MoonError, self).__init__() - - def __del__(self): - message = "{} ({})".format(self.hierarchy, self.message_format) - if self.logger == "ERROR": - try: - self.moonlog_api.error(message) - except AttributeError: - LOG.error(message) - elif self.logger == "WARNING": - try: - self.moonlog_api.warning(message) - except AttributeError: - LOG.warning(message) - elif self.logger == "CRITICAL": - try: - self.moonlog_api.critical(message) - except AttributeError: - LOG.critical(message) - elif self.logger == "AUTHZ": - try: - self.moonlog_api.authz(self.hierarchy) - self.moonlog_api.error(message) - except AttributeError: - LOG.error(message) - else: - try: - self.moonlog_api.info(message) - except AttributeError: - LOG.info(message) - - -# Exceptions for Tenant - -class TenantException(MoonError): - message_format = _("There is an error requesting this tenant.") - code = 400 - title = 'Tenant Error' - logger = "ERROR" - - -class TenantUnknown(TenantException): - message_format = _("The tenant is unknown.") - code = 400 - title = 'Tenant Unknown' - logger = "ERROR" - - -class TenantAddedNameExisting(TenantException): - message_format = _("The tenant name is existing.") - code = 400 - title = 'Added Tenant Name Existing' - logger = "ERROR" - - -class TenantNoIntraExtension(TenantException): - message_format = _("The tenant has not intra_extension.") - code = 400 - title = 'Tenant No Intra_Extension' - logger = "ERROR" - - -class TenantNoIntraAuthzExtension(TenantNoIntraExtension): - message_format = _("The tenant has not intra_admin_extension.") - code = 400 - title = 'Tenant No Intra_Admin_Extension' - logger = "ERROR" - -# Exceptions for IntraExtension - - -class IntraExtensionException(MoonError): - message_format = _("There is an error requesting this IntraExtension.") - code = 400 - title = 'Extension Error' - - -class IntraExtensionUnknown(IntraExtensionException): - message_format = _("The intra_extension is unknown.") - code = 400 - title = 'Intra Extension Unknown' - logger = "Error" - - -class RootExtensionUnknown(IntraExtensionUnknown): - message_format = _("The root_extension is unknown.") - code = 400 - title = 'Root Extension Unknown' - logger = "Error" - - -class RootExtensionNotInitialized(IntraExtensionException): - message_format = _("The root_extension is not initialized.") - code = 400 - title = 'Root Extension Not Initialized' - logger = "Error" - - -class IntraExtensionCreationError(IntraExtensionException): - message_format = _("The arguments for the creation of this Extension were malformed.") - code = 400 - title = 'Intra Extension Creation Error' - - -# Authz exceptions - -class AuthzException(MoonError): - message_format = _("There is an authorization error requesting this IntraExtension.") - code = 403 - title = 'Authz Exception' - logger = "AUTHZ" - - -# Admin exceptions - -class AdminException(MoonError): - message_format = _("There is an error requesting this Authz IntraExtension.") - code = 400 - title = 'Authz Exception' - logger = "AUTHZ" - - -class AdminMetaData(AdminException): - code = 400 - title = 'Metadata Exception' - - -class AdminPerimeter(AdminException): - code = 400 - title = 'Perimeter Exception' - - -class AdminScope(AdminException): - code = 400 - title = 'Scope Exception' - - -class AdminAssignment(AdminException): - code = 400 - title = 'Assignment Exception' - - -class AdminMetaRule(AdminException): - code = 400 - title = 'Aggregation Algorithm Exception' - - -class AdminRule(AdminException): - code = 400 - title = 'Rule Exception' - - -class SubjectCategoryNameExisting(AdminMetaData): - message_format = _("The given subject category name is existing.") - code = 400 - title = 'Subject Category Name Existing' - logger = "ERROR" - - -class ObjectCategoryNameExisting(AdminMetaData): - message_format = _("The given object category name is existing.") - code = 400 - title = 'Object Category Name Existing' - logger = "ERROR" - - -class ActionCategoryNameExisting(AdminMetaData): - message_format = _("The given action category name is existing.") - code = 400 - title = 'Action Category Name Existing' - logger = "ERROR" - - -class SubjectCategoryUnknown(AdminMetaData): - message_format = _("The given subject category is unknown.") - code = 400 - title = 'Subject Category Unknown' - logger = "ERROR" - - -class ObjectCategoryUnknown(AdminMetaData): - message_format = _("The given object category is unknown.") - code = 400 - title = 'Object Category Unknown' - logger = "ERROR" - - -class ActionCategoryUnknown(AdminMetaData): - message_format = _("The given action category is unknown.") - code = 400 - title = 'Action Category Unknown' - logger = "ERROR" - - -class SubjectUnknown(AdminPerimeter): - message_format = _("The given subject is unknown.") - code = 400 - title = 'Subject Unknown' - logger = "ERROR" - - -class ObjectUnknown(AdminPerimeter): - message_format = _("The given object is unknown.") - code = 400 - title = 'Object Unknown' - logger = "ERROR" - - -class ActionUnknown(AdminPerimeter): - message_format = _("The given action is unknown.") - code = 400 - title = 'Action Unknown' - logger = "ERROR" - - -class SubjectNameExisting(AdminPerimeter): - message_format = _("The given subject name is existing.") - code = 400 - title = 'Subject Name Existing' - logger = "ERROR" - - -class ObjectNameExisting(AdminPerimeter): - message_format = _("The given object name is existing.") - code = 400 - title = 'Object Name Existing' - logger = "ERROR" - - -class ActionNameExisting(AdminPerimeter): - message_format = _("The given action name is existing.") - code = 400 - title = 'Action Name Existing' - logger = "ERROR" - - -class ObjectsWriteNoAuthorized(AdminPerimeter): - message_format = _("The modification on Objects is not authorized.") - code = 400 - title = 'Objects Write No Authorized' - logger = "AUTHZ" - - -class ActionsWriteNoAuthorized(AdminPerimeter): - message_format = _("The modification on Actions is not authorized.") - code = 400 - title = 'Actions Write No Authorized' - logger = "AUTHZ" - - -class SubjectScopeUnknown(AdminScope): - message_format = _("The given subject scope is unknown.") - code = 400 - title = 'Subject Scope Unknown' - logger = "ERROR" - - -class ObjectScopeUnknown(AdminScope): - message_format = _("The given object scope is unknown.") - code = 400 - title = 'Object Scope Unknown' - logger = "ERROR" - - -class ActionScopeUnknown(AdminScope): - message_format = _("The given action scope is unknown.") - code = 400 - title = 'Action Scope Unknown' - logger = "ERROR" - - -class SubjectScopeNameExisting(AdminScope): - message_format = _("The given subject scope name is existing.") - code = 400 - title = 'Subject Scope Name Existing' - logger = "ERROR" - - -class ObjectScopeNameExisting(AdminScope): - message_format = _("The given object scope name is existing.") - code = 400 - title = 'Object Scope Name Existing' - logger = "ERROR" - - -class ActionScopeNameExisting(AdminScope): - message_format = _("The given action scope name is existing.") - code = 400 - title = 'Action Scope Name Existing' - logger = "ERROR" - - -class SubjectAssignmentUnknown(AdminAssignment): - message_format = _("The given subject assignment value is unknown.") - code = 400 - title = 'Subject Assignment Unknown' - logger = "ERROR" - - -class ObjectAssignmentUnknown(AdminAssignment): - message_format = _("The given object assignment value is unknown.") - code = 400 - title = 'Object Assignment Unknown' - logger = "ERROR" - - -class ActionAssignmentUnknown(AdminAssignment): - message_format = _("The given action assignment value is unknown.") - code = 400 - title = 'Action Assignment Unknown' - logger = "ERROR" - - -class SubjectAssignmentExisting(AdminAssignment): - message_format = _("The given subject assignment value is existing.") - code = 400 - title = 'Subject Assignment Existing' - logger = "ERROR" - - -class ObjectAssignmentExisting(AdminAssignment): - message_format = _("The given object assignment value is existing.") - code = 400 - title = 'Object Assignment Existing' - logger = "ERROR" - - -class ActionAssignmentExisting(AdminAssignment): - message_format = _("The given action assignment value is existing.") - code = 400 - title = 'Action Assignment Existing' - logger = "ERROR" - - -class AggregationAlgorithmNotExisting(AdminMetaRule): - message_format = _("The given aggregation algorithm is not existing.") - code = 400 - title = 'Aggregation Algorithm Not Existing' - logger = "ERROR" - - -class AggregationAlgorithmUnknown(AdminMetaRule): - message_format = _("The given aggregation algorithm is unknown.") - code = 400 - title = 'Aggregation Algorithm Unknown' - logger = "ERROR" - - -class SubMetaRuleAlgorithmNotExisting(AdminMetaRule): - message_format = _("The given sub_meta_rule algorithm is unknown.") - code = 400 - title = 'Sub_meta_rule Algorithm Unknown' - logger = "ERROR" - - -class SubMetaRuleUnknown(AdminMetaRule): - message_format = _("The given sub meta rule is unknown.") - code = 400 - title = 'Sub Meta Rule Unknown' - logger = "ERROR" - - -class SubMetaRuleNameExisting(AdminMetaRule): - message_format = _("The sub meta rule name already exists.") - code = 400 - title = 'Sub Meta Rule Name Existing' - logger = "ERROR" - - -class SubMetaRuleExisting(AdminMetaRule): - message_format = _("The sub meta rule already exists.") - code = 400 - title = 'Sub Meta Rule Existing' - logger = "ERROR" - - -class RuleExisting(AdminRule): - message_format = _("The rule already exists.") - code = 400 - title = 'Rule Existing' - logger = "ERROR" - - -class RuleUnknown(AdminRule): - message_format = _("The rule for that request doesn't exist.") - code = 400 - title = 'Rule Unknown' - logger = "ERROR" - diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/moon/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/moon/migrate_repo/migrate.cfg deleted file mode 100644 index 7a7bd1f8..00000000 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=moon - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py b/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py deleted file mode 100644 index bcd334fa..00000000 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/001_moon.py +++ /dev/null @@ -1,211 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -import sqlalchemy as sql -from keystone.common import sql as k_sql - - -def upgrade(migrate_engine): - meta = sql.MetaData() - meta.bind = migrate_engine - - intra_extension_table = sql.Table( - 'intra_extensions', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('intra_extension', k_sql.JsonBlob(), nullable=True), - mysql_engine='InnoDB', - mysql_charset='utf8') - intra_extension_table.create(migrate_engine, checkfirst=True) - - tenant_table = sql.Table( - 'tenants', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('tenant', k_sql.JsonBlob(), nullable=True), - mysql_engine='InnoDB', - mysql_charset='utf8') - tenant_table.create(migrate_engine, checkfirst=True) - - subject_categories_table = sql.Table( - 'subject_categories', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('subject_category', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - subject_categories_table.create(migrate_engine, checkfirst=True) - - object_categories_table = sql.Table( - 'object_categories', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('object_category', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - object_categories_table.create(migrate_engine, checkfirst=True) - - action_categories_table = sql.Table( - 'action_categories', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('action_category', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - action_categories_table.create(migrate_engine, checkfirst=True) - - subjects_table = sql.Table( - 'subjects', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('subject', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - subjects_table.create(migrate_engine, checkfirst=True) - - objects_table = sql.Table( - 'objects', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('object', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - objects_table.create(migrate_engine, checkfirst=True) - - actions_table = sql.Table( - 'actions', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('action', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - actions_table.create(migrate_engine, checkfirst=True) - - subject_scopes_table = sql.Table( - 'subject_scopes', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('subject_scope', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('subject_category_id', sql.ForeignKey("subject_categories.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - subject_scopes_table.create(migrate_engine, checkfirst=True) - - object_scopes_table = sql.Table( - 'object_scopes', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('object_scope', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('object_category_id', sql.ForeignKey("object_categories.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - object_scopes_table.create(migrate_engine, checkfirst=True) - - action_scopes_table = sql.Table( - 'action_scopes', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('action_scope', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('action_category_id', sql.ForeignKey("action_categories.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - action_scopes_table.create(migrate_engine, checkfirst=True) - - subject_assignments_table = sql.Table( - 'subject_assignments', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('subject_assignment', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('subject_id', sql.ForeignKey("subjects.id"), nullable=False), - sql.Column('subject_category_id', sql.ForeignKey("subject_categories.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - subject_assignments_table.create(migrate_engine, checkfirst=True) - - object_assignments_table = sql.Table( - 'object_assignments', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('object_assignment', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('object_id', sql.ForeignKey("objects.id"), nullable=False), - sql.Column('object_category_id', sql.ForeignKey("object_categories.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - object_assignments_table.create(migrate_engine, checkfirst=True) - - action_assignments_table = sql.Table( - 'action_assignments', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('action_assignment', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('action_id', sql.ForeignKey("actions.id"), nullable=False), - sql.Column('action_category_id', sql.ForeignKey("action_categories.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - action_assignments_table.create(migrate_engine, checkfirst=True) - - sub_meta_rules_table = sql.Table( - 'sub_meta_rules', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('sub_meta_rule', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - sub_meta_rules_table.create(migrate_engine, checkfirst=True) - - rules_table = sql.Table( - 'rules', - meta, - sql.Column('id', sql.String(64), primary_key=True), - sql.Column('rule', k_sql.JsonBlob(), nullable=True), - sql.Column('intra_extension_id', sql.ForeignKey("intra_extensions.id"), nullable=False), - sql.Column('sub_meta_rule_id', sql.ForeignKey("sub_meta_rules.id"), nullable=False), - mysql_engine='InnoDB', - mysql_charset='utf8') - rules_table.create(migrate_engine, checkfirst=True) - - -def downgrade(migrate_engine): - meta = sql.MetaData() - meta.bind = migrate_engine - - for _table in ( - 'rules', - 'sub_meta_rules', - 'action_assignments', - 'object_assignments', - 'subject_assignments', - 'action_scopes', - 'object_scopes', - 'subject_scopes', - 'actions', - 'objects', - 'subjects', - 'action_categories', - 'object_categories', - 'subject_categories', - 'tenants', - 'intra_extensions' - ): - try: - table = sql.Table(_table, meta, autoload=True) - table.drop(migrate_engine, checkfirst=True) - except Exception as e: - print(e.message) - - diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/002_moon.py b/keystone-moon/keystone/contrib/moon/migrate_repo/versions/002_moon.py deleted file mode 100644 index 14e22fc4..00000000 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/002_moon.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -import sqlalchemy as sql -from keystone.common import sql as k_sql - - -def upgrade(migrate_engine): - meta = sql.MetaData() - meta.bind = migrate_engine - -# region_table = sql.Table( -# 'inter_extension', -# meta, -# sql.Column('id', sql.String(64), primary_key=True), -# sql.Column('requesting_intra_extension_uuid', sql.String(64), nullable=False), -# sql.Column('requested_intra_extension_uuid', sql.String(64), nullable=False), -# sql.Column('virtual_entity_uuid', sql.String(64), nullable=False), -# sql.Column('genre', sql.String(64), nullable=False), -# sql.Column('description', sql.Text(), nullable=True), -# -# mysql_engine='InnoDB', -# mysql_charset='utf8') -# region_table.create(migrate_engine, checkfirst=True) -# -# -def downgrade(migrate_engine): - meta = sql.MetaData() - meta.bind = migrate_engine - -# table = sql.Table('inter_extension', meta, autoload=True) -# table.drop(migrate_engine, checkfirst=True) diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/003_moon.py b/keystone-moon/keystone/contrib/moon/migrate_repo/versions/003_moon.py deleted file mode 100644 index f11fb2fb..00000000 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/003_moon.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -import sqlalchemy as sql -from keystone.common import sql as k_sql - - -def upgrade(migrate_engine): - meta = sql.MetaData() - meta.bind = migrate_engine - -# region_table = sql.Table( -# 'tenants', -# meta, -# sql.Column('id', sql.String(64), primary_key=True), -# sql.Column('name', sql.String(128), nullable=True), -# sql.Column('authz', sql.String(64), nullable=True), -# sql.Column('admin', sql.String(64), nullable=True), -# -# mysql_engine='InnoDB', -# mysql_charset='utf8') -# region_table.create(migrate_engine, checkfirst=True) -# - -def downgrade(migrate_engine): - meta = sql.MetaData() - meta.bind = migrate_engine -# -# table = sql.Table('tenants', meta, autoload=True) -# table.drop(migrate_engine, checkfirst=True) diff --git a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/moon/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/moon/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/moon/routers.py b/keystone-moon/keystone/contrib/moon/routers.py deleted file mode 100644 index c3bb7df0..00000000 --- a/keystone-moon/keystone/contrib/moon/routers.py +++ /dev/null @@ -1,507 +0,0 @@ -# Copyright 2015 Open Platform for NFV Project, Inc. and its contributors -# This software is distributed under the terms and conditions of the 'Apache-2.0' -# license which can be found in the file 'LICENSE' in this package distribution -# or at 'http://www.apache.org/licenses/LICENSE-2.0'. - -"""WSGI Routers for the Moon service.""" - -from keystone.contrib.moon import controllers -from keystone.common import wsgi -from oslo_log import log - -LOG = log.getLogger(__name__) - - -class Routers(wsgi.ComposableRouter): - """API Endpoints for the Moon extension. - """ - - PATH_PREFIX = '' - - def __init__(self, description): - self.description = description - - @staticmethod - def _get_rel(component): - return 'http://docs.openstack.org/api/openstack-authz/3/param/{}'.format(component) - - @staticmethod - def _get_path(component): - return 'http://docs.openstack.org/api/openstack-authz/3/param/{}'.format(component) - - def add_routes(self, mapper): - # Controllers creation - authz_controller = controllers.Authz_v3() - configuration_controller = controllers.Configuration() - intra_ext_controller = controllers.IntraExtensions() - tenants_controller = controllers.Tenants() - logs_controller = controllers.Logs() - auth_controller = controllers.MoonAuth() - inter_ext_controller = controllers.InterExtensions() - - # Configuration route - mapper.connect( - self.PATH_PREFIX+'/configuration/templates', - controller=configuration_controller, - action='get_policy_templates', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/configuration/aggregation_algorithms', - controller=configuration_controller, - action='get_aggregation_algorithms', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/configuration/sub_meta_rule_algorithms', - controller=configuration_controller, - action='get_sub_meta_rule_algorithms', - conditions=dict(method=['GET'])) - - # Tenants route - mapper.connect( - self.PATH_PREFIX+'/tenants', - controller=tenants_controller, - action='get_tenants', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/tenants', - controller=tenants_controller, - action='add_tenant', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/tenants/{tenant_id}', - controller=tenants_controller, - action='get_tenant', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/tenants/{tenant_id}', - controller=tenants_controller, - action='del_tenant', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/tenants/{tenant_id}', - controller=tenants_controller, - action='set_tenant', - conditions=dict(method=['POST'])) - - # Authz route - mapper.connect( - self.PATH_PREFIX+'/authz/{tenant_id}/{subject_k_id}/{object_name}/{action_name}', - controller=authz_controller, - action='get_authz', - conditions=dict(method=['GET'])) - - # IntraExtensions/Admin route - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/init', - controller=intra_ext_controller, - action='load_root_intra_extension', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions', - controller=intra_ext_controller, - action='get_intra_extensions', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions', - controller=intra_ext_controller, - action='add_intra_extension', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}', - controller=intra_ext_controller, - action='get_intra_extension', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}', - controller=intra_ext_controller, - action='set_intra_extension', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}', - controller=intra_ext_controller, - action='del_intra_extension', - conditions=dict(method=['DELETE'])) - - # Metadata route - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_categories', - controller=intra_ext_controller, - action='get_subject_categories', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_categories', - controller=intra_ext_controller, - action='add_subject_category', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_categories/{subject_category_id}', - controller=intra_ext_controller, - action='get_subject_category', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_categories/{subject_category_id}', - controller=intra_ext_controller, - action='del_subject_category', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_categories/{subject_category_id}', - controller=intra_ext_controller, - action='set_subject_category', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_categories', - controller=intra_ext_controller, - action='get_object_categories', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_categories', - controller=intra_ext_controller, - action='add_object_category', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_categories/{object_category_id}', - controller=intra_ext_controller, - action='get_object_category', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_categories/{object_category_id}', - controller=intra_ext_controller, - action='del_object_category', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_categories/{object_category_id}', - controller=intra_ext_controller, - action='set_object_category', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_categories', - controller=intra_ext_controller, - action='get_action_categories', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_categories', - controller=intra_ext_controller, - action='add_action_category', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_categories/{action_category_id}', - controller=intra_ext_controller, - action='get_action_category', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_categories/{action_category_id}', - controller=intra_ext_controller, - action='del_action_category', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_categories/{action_category_id}', - controller=intra_ext_controller, - action='set_action_category', - conditions=dict(method=['POST'])) - - # Perimeter route - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subjects', - controller=intra_ext_controller, - action='get_subjects', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subjects', - controller=intra_ext_controller, - action='add_subject', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subjects/{subject_id}', - controller=intra_ext_controller, - action='get_subject', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subjects/{subject_id}', - controller=intra_ext_controller, - action='del_subject', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subjects/{subject_id}', - controller=intra_ext_controller, - action='set_subject', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/objects', - controller=intra_ext_controller, - action='get_objects', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/objects', - controller=intra_ext_controller, - action='add_object', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/objects/{object_id}', - controller=intra_ext_controller, - action='get_object', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/objects/{object_id}', - controller=intra_ext_controller, - action='del_object', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/objects/{object_id}', - controller=intra_ext_controller, - action='set_object', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/actions', - controller=intra_ext_controller, - action='get_actions', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/actions', - controller=intra_ext_controller, - action='add_action', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/actions/{action_id}', - controller=intra_ext_controller, - action='get_action', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/actions/{action_id}', - controller=intra_ext_controller, - action='del_action', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/actions/{action_id}', - controller=intra_ext_controller, - action='set_action', - conditions=dict(method=['POST'])) - - # Scope route - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_scopes/{subject_category_id}', - controller=intra_ext_controller, - action='get_subject_scopes', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_scopes/{subject_category_id}', - controller=intra_ext_controller, - action='add_subject_scope', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_scopes/{subject_category_id}/{subject_scope_id}', - controller=intra_ext_controller, - action='get_subject_scope', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_scopes/{subject_category_id}/{subject_scope_id}', - controller=intra_ext_controller, - action='del_subject_scope', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_scopes/{subject_category_id}/{subject_scope_id}', - controller=intra_ext_controller, - action='set_subject_scope', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_scopes/{object_category_id}', - controller=intra_ext_controller, - action='get_object_scopes', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_scopes/{object_category_id}', - controller=intra_ext_controller, - action='add_object_scope', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_scopes/{object_category_id}/{object_scope_id}', - controller=intra_ext_controller, - action='get_object_scope', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_scopes/{object_category_id}/{object_scope_id}', - controller=intra_ext_controller, - action='del_object_scope', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_scopes/{object_category_id}/{object_scope_id}', - controller=intra_ext_controller, - action='set_object_scope', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_scopes/{action_category_id}', - controller=intra_ext_controller, - action='get_action_scopes', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_scopes/{action_category_id}', - controller=intra_ext_controller, - action='add_action_scope', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_scopes/{action_category_id}/{action_scope_id}', - controller=intra_ext_controller, - action='get_action_scope', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_scopes/{action_category_id}/{action_scope_id}', - controller=intra_ext_controller, - action='del_action_scope', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_scopes/{action_category_id}/{action_scope_id}', - controller=intra_ext_controller, - action='set_action_scope', - conditions=dict(method=['POST'])) - - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/subject_assignments', - controller=intra_ext_controller, - action='add_subject_assignment', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/' - 'subject_assignments/{subject_id}/{subject_category_id}', - controller=intra_ext_controller, - action='get_subject_assignment', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/' - 'subject_assignments/{subject_id}/{subject_category_id}/{subject_scope_id}', - controller=intra_ext_controller, - action='del_subject_assignment', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/object_assignments', - controller=intra_ext_controller, - action='add_object_assignment', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/' - 'object_assignments/{object_id}/{object_category_id}', - controller=intra_ext_controller, - action='get_object_assignment', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/' - 'object_assignments/{object_id}/{object_category_id}/{object_scope_id}', - controller=intra_ext_controller, - action='del_object_assignment', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/action_assignments', - controller=intra_ext_controller, - action='add_action_assignment', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/' - 'action_assignments/{action_id}/{action_category_id}', - controller=intra_ext_controller, - action='get_action_assignment', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/' - 'action_assignments/{action_id}/{action_category_id}/{action_scope_id}', - controller=intra_ext_controller, - action='del_action_assignment', - conditions=dict(method=['DELETE'])) - - # Metarule route - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/aggregation_algorithm', - controller=intra_ext_controller, - action='get_aggregation_algorithm', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/aggregation_algorithm', - controller=intra_ext_controller, - action='set_aggregation_algorithm', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/sub_meta_rules', - controller=intra_ext_controller, - action='get_sub_meta_rules', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/sub_meta_rules', - controller=intra_ext_controller, - action='add_sub_meta_rule', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/sub_meta_rules/{sub_meta_rule_id}', - controller=intra_ext_controller, - action='get_sub_meta_rule', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/sub_meta_rules/{sub_meta_rule_id}', - controller=intra_ext_controller, - action='del_sub_meta_rule', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/sub_meta_rules/{sub_meta_rule_id}', - controller=intra_ext_controller, - action='set_sub_meta_rule', - conditions=dict(method=['POST'])) - - # Rules route - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/rule/{sub_meta_rule_id}', - controller=intra_ext_controller, - action='get_rules', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/rule/{sub_meta_rule_id}', - controller=intra_ext_controller, - action='add_rule', - conditions=dict(method=['POST'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/rule/{sub_meta_rule_id}/{rule_id}', - controller=intra_ext_controller, - action='get_rule', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/rule/{sub_meta_rule_id}/{rule_id}', - controller=intra_ext_controller, - action='del_rule', - conditions=dict(method=['DELETE'])) - mapper.connect( - self.PATH_PREFIX+'/intra_extensions/{intra_extension_id}/rule/{sub_meta_rule_id}/{rule_id}', - controller=intra_ext_controller, - action='set_rule', - conditions=dict(method=['POST'])) - - # Logs route - mapper.connect( - self.PATH_PREFIX+'/logs', - controller=logs_controller, - action='get_logs', - conditions=dict(method=['GET'])) - mapper.connect( - self.PATH_PREFIX+'/logs/{options}', - controller=logs_controller, - action='get_logs', - conditions=dict(method=['GET'])) - - # Auth route - mapper.connect( - self.PATH_PREFIX+'/auth/tokens', - controller=auth_controller, - action='get_token', - conditions=dict(method=['POST'])) - - # InterExtensions route - # mapper.connect( - # controller=inter_ext_controller, - # self.PATH_PREFIX+'/inter_extensions', - # action='get_inter_extensions', - # action='create_inter_extension', - # rel=self._get_rel('inter_extensions'), - # path_vars={}) - # mapper.connect( - # controller=inter_ext_controller, - # self.PATH_PREFIX+'/inter_extensions/{inter_extension_id}', - # action='get_inter_extension', - # action='delete_inter_extension', - # rel=self._get_rel('inter_extensions'), - # path_vars={ - # 'inter_extension_id': self._get_path('inter_extensions'), - # }) diff --git a/keystone-moon/keystone/contrib/moon/service.py b/keystone-moon/keystone/contrib/moon/service.py deleted file mode 100644 index cd68e98a..00000000 --- a/keystone-moon/keystone/contrib/moon/service.py +++ /dev/null @@ -1,57 +0,0 @@ -import functools -import sys - -from oslo_config import cfg -from oslo_log import log -from paste import deploy -import routes -from keystone.contrib.moon.routers import Routers - -from keystone import assignment -from keystone import auth -from keystone import catalog -from keystone.common import wsgi -from keystone import controllers -from keystone import credential -from keystone import endpoint_policy -from keystone import identity -from keystone import policy -from keystone import resource -from keystone import routers -from keystone import token -from keystone import trust - - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - - -# def loadapp(conf, name): -# # NOTE(blk-u): Save the application being loaded in the controllers module. -# # This is similar to how public_app_factory() and v3_app_factory() -# # register the version with the controllers module. -# controllers.latest_app = deploy.loadapp(conf, name=name) -# return controllers.latest_app - - -def fail_gracefully(f): - """Logs exceptions and aborts.""" - @functools.wraps(f) - def wrapper(*args, **kw): - try: - return f(*args, **kw) - except Exception as e: - LOG.debug(e, exc_info=True) - - # exception message is printed to all logs - LOG.critical(e) - sys.exit(1) - - return wrapper - - -@fail_gracefully -def moon_app_factory(global_conf, **local_conf): - return wsgi.ComposingRouter(routes.Mapper(), - [Routers('moon_service')]) - diff --git a/keystone-moon/keystone/contrib/moon/wsgi.py b/keystone-moon/keystone/contrib/moon/wsgi.py deleted file mode 100644 index f2a99633..00000000 --- a/keystone-moon/keystone/contrib/moon/wsgi.py +++ /dev/null @@ -1,8 +0,0 @@ -from keystone.server import wsgi -from oslo_log import log - -LOG = log.getLogger(__name__) - - -def initialize_moon_application(): - return wsgi.initialize_application('moon_service') diff --git a/keystone-moon/keystone/contrib/oauth1/__init__.py b/keystone-moon/keystone/contrib/oauth1/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/oauth1/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/oauth1/backends/__init__.py b/keystone-moon/keystone/contrib/oauth1/backends/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/oauth1/backends/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/oauth1/backends/sql.py b/keystone-moon/keystone/contrib/oauth1/backends/sql.py deleted file mode 100644 index 31b6ce3b..00000000 --- a/keystone-moon/keystone/contrib/oauth1/backends/sql.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import versionutils - -from keystone.oauth1.backends import sql - - -_OLD = "keystone.contrib.oauth1.backends.sql.OAuth1" -_NEW = "sql" - - -class OAuth1(sql.OAuth1): - - @versionutils.deprecated(versionutils.deprecated.MITAKA, - in_favor_of=_NEW, - what=_OLD) - def __init__(self, *args, **kwargs): - super(OAuth1, self).__init__(*args, **kwargs) diff --git a/keystone-moon/keystone/contrib/oauth1/controllers.py b/keystone-moon/keystone/contrib/oauth1/controllers.py deleted file mode 100644 index d12fc96b..00000000 --- a/keystone-moon/keystone/contrib/oauth1/controllers.py +++ /dev/null @@ -1,411 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Extensions supporting OAuth1.""" - -from oslo_config import cfg -from oslo_serialization import jsonutils -from oslo_utils import timeutils - -from keystone.common import controller -from keystone.common import dependency -from keystone.common import utils -from keystone.common import wsgi -from keystone.contrib.oauth1 import core as oauth1 -from keystone.contrib.oauth1 import validator -from keystone import exception -from keystone.i18n import _ -from keystone import notifications - - -CONF = cfg.CONF - - -@notifications.internal(notifications.INVALIDATE_USER_OAUTH_CONSUMER_TOKENS, - resource_id_arg_index=0) -def _emit_user_oauth_consumer_token_invalidate(payload): - # This is a special case notification that expect the payload to be a dict - # containing the user_id and the consumer_id. This is so that the token - # provider can invalidate any tokens in the token persistence if - # token persistence is enabled - pass - - -@dependency.requires('oauth_api', 'token_provider_api') -class ConsumerCrudV3(controller.V3Controller): - collection_name = 'consumers' - member_name = 'consumer' - - @classmethod - def base_url(cls, context, path=None): - """Construct a path and pass it to V3Controller.base_url method.""" - - # NOTE(stevemar): Overriding path to /OS-OAUTH1/consumers so that - # V3Controller.base_url handles setting the self link correctly. - path = '/OS-OAUTH1/' + cls.collection_name - return controller.V3Controller.base_url(context, path=path) - - @controller.protected() - def create_consumer(self, context, consumer): - ref = self._assign_unique_id(self._normalize_dict(consumer)) - initiator = notifications._get_request_audit_info(context) - consumer_ref = self.oauth_api.create_consumer(ref, initiator) - return ConsumerCrudV3.wrap_member(context, consumer_ref) - - @controller.protected() - def update_consumer(self, context, consumer_id, consumer): - self._require_matching_id(consumer_id, consumer) - ref = self._normalize_dict(consumer) - self._validate_consumer_ref(ref) - initiator = notifications._get_request_audit_info(context) - ref = self.oauth_api.update_consumer(consumer_id, ref, initiator) - return ConsumerCrudV3.wrap_member(context, ref) - - @controller.protected() - def list_consumers(self, context): - ref = self.oauth_api.list_consumers() - return ConsumerCrudV3.wrap_collection(context, ref) - - @controller.protected() - def get_consumer(self, context, consumer_id): - ref = self.oauth_api.get_consumer(consumer_id) - return ConsumerCrudV3.wrap_member(context, ref) - - @controller.protected() - def delete_consumer(self, context, consumer_id): - user_token_ref = utils.get_token_ref(context) - payload = {'user_id': user_token_ref.user_id, - 'consumer_id': consumer_id} - _emit_user_oauth_consumer_token_invalidate(payload) - initiator = notifications._get_request_audit_info(context) - self.oauth_api.delete_consumer(consumer_id, initiator) - - def _validate_consumer_ref(self, consumer): - if 'secret' in consumer: - msg = _('Cannot change consumer secret') - raise exception.ValidationError(message=msg) - - -@dependency.requires('oauth_api') -class AccessTokenCrudV3(controller.V3Controller): - collection_name = 'access_tokens' - member_name = 'access_token' - - @classmethod - def _add_self_referential_link(cls, context, ref): - # NOTE(lwolf): overriding method to add proper path to self link - ref.setdefault('links', {}) - path = '/users/%(user_id)s/OS-OAUTH1/access_tokens' % { - 'user_id': cls._get_user_id(ref) - } - ref['links']['self'] = cls.base_url(context, path) + '/' + ref['id'] - - @controller.protected() - def get_access_token(self, context, user_id, access_token_id): - access_token = self.oauth_api.get_access_token(access_token_id) - if access_token['authorizing_user_id'] != user_id: - raise exception.NotFound() - access_token = self._format_token_entity(context, access_token) - return AccessTokenCrudV3.wrap_member(context, access_token) - - @controller.protected() - def list_access_tokens(self, context, user_id): - auth_context = context.get('environment', - {}).get('KEYSTONE_AUTH_CONTEXT', {}) - if auth_context.get('is_delegated_auth'): - raise exception.Forbidden( - _('Cannot list request tokens' - ' with a token issued via delegation.')) - refs = self.oauth_api.list_access_tokens(user_id) - formatted_refs = ([self._format_token_entity(context, x) - for x in refs]) - return AccessTokenCrudV3.wrap_collection(context, formatted_refs) - - @controller.protected() - def delete_access_token(self, context, user_id, access_token_id): - access_token = self.oauth_api.get_access_token(access_token_id) - consumer_id = access_token['consumer_id'] - payload = {'user_id': user_id, 'consumer_id': consumer_id} - _emit_user_oauth_consumer_token_invalidate(payload) - initiator = notifications._get_request_audit_info(context) - return self.oauth_api.delete_access_token( - user_id, access_token_id, initiator) - - @staticmethod - def _get_user_id(entity): - return entity.get('authorizing_user_id', '') - - def _format_token_entity(self, context, entity): - - formatted_entity = entity.copy() - access_token_id = formatted_entity['id'] - user_id = self._get_user_id(formatted_entity) - if 'role_ids' in entity: - formatted_entity.pop('role_ids') - if 'access_secret' in entity: - formatted_entity.pop('access_secret') - - url = ('/users/%(user_id)s/OS-OAUTH1/access_tokens/%(access_token_id)s' - '/roles' % {'user_id': user_id, - 'access_token_id': access_token_id}) - - formatted_entity.setdefault('links', {}) - formatted_entity['links']['roles'] = (self.base_url(context, url)) - - return formatted_entity - - -@dependency.requires('oauth_api', 'role_api') -class AccessTokenRolesV3(controller.V3Controller): - collection_name = 'roles' - member_name = 'role' - - @controller.protected() - def list_access_token_roles(self, context, user_id, access_token_id): - access_token = self.oauth_api.get_access_token(access_token_id) - if access_token['authorizing_user_id'] != user_id: - raise exception.NotFound() - authed_role_ids = access_token['role_ids'] - authed_role_ids = jsonutils.loads(authed_role_ids) - refs = ([self._format_role_entity(x) for x in authed_role_ids]) - return AccessTokenRolesV3.wrap_collection(context, refs) - - @controller.protected() - def get_access_token_role(self, context, user_id, - access_token_id, role_id): - access_token = self.oauth_api.get_access_token(access_token_id) - if access_token['authorizing_user_id'] != user_id: - raise exception.Unauthorized(_('User IDs do not match')) - authed_role_ids = access_token['role_ids'] - authed_role_ids = jsonutils.loads(authed_role_ids) - for authed_role_id in authed_role_ids: - if authed_role_id == role_id: - role = self._format_role_entity(role_id) - return AccessTokenRolesV3.wrap_member(context, role) - raise exception.RoleNotFound(_('Could not find role')) - - def _format_role_entity(self, role_id): - role = self.role_api.get_role(role_id) - formatted_entity = role.copy() - if 'description' in role: - formatted_entity.pop('description') - if 'enabled' in role: - formatted_entity.pop('enabled') - return formatted_entity - - -@dependency.requires('assignment_api', 'oauth_api', - 'resource_api', 'token_provider_api') -class OAuthControllerV3(controller.V3Controller): - collection_name = 'not_used' - member_name = 'not_used' - - def create_request_token(self, context): - headers = context['headers'] - oauth_headers = oauth1.get_oauth_headers(headers) - consumer_id = oauth_headers.get('oauth_consumer_key') - requested_project_id = headers.get('Requested-Project-Id') - - if not consumer_id: - raise exception.ValidationError( - attribute='oauth_consumer_key', target='request') - if not requested_project_id: - raise exception.ValidationError( - attribute='requested_project_id', target='request') - - # NOTE(stevemar): Ensure consumer and requested project exist - self.resource_api.get_project(requested_project_id) - self.oauth_api.get_consumer(consumer_id) - - url = self.base_url(context, context['path']) - - req_headers = {'Requested-Project-Id': requested_project_id} - req_headers.update(headers) - request_verifier = oauth1.RequestTokenEndpoint( - request_validator=validator.OAuthValidator(), - token_generator=oauth1.token_generator) - h, b, s = request_verifier.create_request_token_response( - url, - http_method='POST', - body=context['query_string'], - headers=req_headers) - - if (not b) or int(s) > 399: - msg = _('Invalid signature') - raise exception.Unauthorized(message=msg) - - request_token_duration = CONF.oauth1.request_token_duration - initiator = notifications._get_request_audit_info(context) - token_ref = self.oauth_api.create_request_token(consumer_id, - requested_project_id, - request_token_duration, - initiator) - - result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' - % {'key': token_ref['id'], - 'secret': token_ref['request_secret']}) - - if CONF.oauth1.request_token_duration: - expiry_bit = '&oauth_expires_at=%s' % token_ref['expires_at'] - result += expiry_bit - - headers = [('Content-Type', 'application/x-www-urlformencoded')] - response = wsgi.render_response(result, - status=(201, 'Created'), - headers=headers) - - return response - - def create_access_token(self, context): - headers = context['headers'] - oauth_headers = oauth1.get_oauth_headers(headers) - consumer_id = oauth_headers.get('oauth_consumer_key') - request_token_id = oauth_headers.get('oauth_token') - oauth_verifier = oauth_headers.get('oauth_verifier') - - if not consumer_id: - raise exception.ValidationError( - attribute='oauth_consumer_key', target='request') - if not request_token_id: - raise exception.ValidationError( - attribute='oauth_token', target='request') - if not oauth_verifier: - raise exception.ValidationError( - attribute='oauth_verifier', target='request') - - req_token = self.oauth_api.get_request_token( - request_token_id) - - expires_at = req_token['expires_at'] - if expires_at: - now = timeutils.utcnow() - expires = timeutils.normalize_time( - timeutils.parse_isotime(expires_at)) - if now > expires: - raise exception.Unauthorized(_('Request token is expired')) - - url = self.base_url(context, context['path']) - - access_verifier = oauth1.AccessTokenEndpoint( - request_validator=validator.OAuthValidator(), - token_generator=oauth1.token_generator) - h, b, s = access_verifier.create_access_token_response( - url, - http_method='POST', - body=context['query_string'], - headers=headers) - params = oauth1.extract_non_oauth_params(b) - if len(params) != 0: - msg = _('There should not be any non-oauth parameters') - raise exception.Unauthorized(message=msg) - - if req_token['consumer_id'] != consumer_id: - msg = _('provided consumer key does not match stored consumer key') - raise exception.Unauthorized(message=msg) - - if req_token['verifier'] != oauth_verifier: - msg = _('provided verifier does not match stored verifier') - raise exception.Unauthorized(message=msg) - - if req_token['id'] != request_token_id: - msg = _('provided request key does not match stored request key') - raise exception.Unauthorized(message=msg) - - if not req_token.get('authorizing_user_id'): - msg = _('Request Token does not have an authorizing user id') - raise exception.Unauthorized(message=msg) - - access_token_duration = CONF.oauth1.access_token_duration - initiator = notifications._get_request_audit_info(context) - token_ref = self.oauth_api.create_access_token(request_token_id, - access_token_duration, - initiator) - - result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' - % {'key': token_ref['id'], - 'secret': token_ref['access_secret']}) - - if CONF.oauth1.access_token_duration: - expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at']) - result += expiry_bit - - headers = [('Content-Type', 'application/x-www-urlformencoded')] - response = wsgi.render_response(result, - status=(201, 'Created'), - headers=headers) - - return response - - @controller.protected() - def authorize_request_token(self, context, request_token_id, roles): - """An authenticated user is going to authorize a request token. - - As a security precaution, the requested roles must match those in - the request token. Because this is in a CLI-only world at the moment, - there is not another easy way to make sure the user knows which roles - are being requested before authorizing. - """ - auth_context = context.get('environment', - {}).get('KEYSTONE_AUTH_CONTEXT', {}) - if auth_context.get('is_delegated_auth'): - raise exception.Forbidden( - _('Cannot authorize a request token' - ' with a token issued via delegation.')) - - req_token = self.oauth_api.get_request_token(request_token_id) - - expires_at = req_token['expires_at'] - if expires_at: - now = timeutils.utcnow() - expires = timeutils.normalize_time( - timeutils.parse_isotime(expires_at)) - if now > expires: - raise exception.Unauthorized(_('Request token is expired')) - - # put the roles in a set for easy comparison - authed_roles = set() - for role in roles: - authed_roles.add(role['id']) - - # verify the authorizing user has the roles - user_token = utils.get_token_ref(context) - user_id = user_token.user_id - project_id = req_token['requested_project_id'] - user_roles = self.assignment_api.get_roles_for_user_and_project( - user_id, project_id) - cred_set = set(user_roles) - - if not cred_set.issuperset(authed_roles): - msg = _('authorizing user does not have role required') - raise exception.Unauthorized(message=msg) - - # create list of just the id's for the backend - role_list = list(authed_roles) - - # verify the user has the project too - req_project_id = req_token['requested_project_id'] - user_projects = self.assignment_api.list_projects_for_user(user_id) - for user_project in user_projects: - if user_project['id'] == req_project_id: - break - else: - msg = _("User is not a member of the requested project") - raise exception.Unauthorized(message=msg) - - # finally authorize the token - authed_token = self.oauth_api.authorize_request_token( - request_token_id, user_id, role_list) - - to_return = {'token': {'oauth_verifier': authed_token['verifier']}} - return to_return diff --git a/keystone-moon/keystone/contrib/oauth1/core.py b/keystone-moon/keystone/contrib/oauth1/core.py deleted file mode 100644 index 6406a803..00000000 --- a/keystone-moon/keystone/contrib/oauth1/core.py +++ /dev/null @@ -1,367 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into the OAuth1 service.""" - -from __future__ import absolute_import - -import abc -import string -import uuid - -import oauthlib.common -from oauthlib import oauth1 -from oslo_config import cfg -from oslo_log import log -import six - -from keystone.common import dependency -from keystone.common import extension -from keystone.common import manager -from keystone import exception -from keystone.i18n import _LE -from keystone import notifications - - -RequestValidator = oauth1.RequestValidator -Client = oauth1.Client -AccessTokenEndpoint = oauth1.AccessTokenEndpoint -ResourceEndpoint = oauth1.ResourceEndpoint -AuthorizationEndpoint = oauth1.AuthorizationEndpoint -SIG_HMAC = oauth1.SIGNATURE_HMAC -RequestTokenEndpoint = oauth1.RequestTokenEndpoint -oRequest = oauthlib.common.Request -# The characters used to generate verifiers are limited to alphanumerical -# values for ease of manual entry. Commonly confused characters are omitted. -VERIFIER_CHARS = string.ascii_letters + string.digits -CONFUSED_CHARS = 'jiIl1oO0' -VERIFIER_CHARS = ''.join(c for c in VERIFIER_CHARS if c not in CONFUSED_CHARS) - - -class Token(object): - def __init__(self, key, secret): - self.key = key - self.secret = secret - self.verifier = None - - def set_verifier(self, verifier): - self.verifier = verifier - - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - - -def token_generator(*args, **kwargs): - return uuid.uuid4().hex - - -EXTENSION_DATA = { - 'name': 'OpenStack OAUTH1 API', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-OAUTH1/v1.0', - 'alias': 'OS-OAUTH1', - 'updated': '2013-07-07T12:00:0-00:00', - 'description': 'OpenStack OAuth 1.0a Delegated Auth Mechanism.', - 'links': [ - { - 'rel': 'describedby', - # TODO(dolph): link needs to be revised after - # bug 928059 merges - 'type': 'text/html', - 'href': 'https://github.com/openstack/identity-api', - } - ]} -extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) -extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) - - -def filter_consumer(consumer_ref): - """Filter out private items in a consumer dict. - - 'secret' is never returned. - - :returns: consumer_ref - - """ - if consumer_ref: - consumer_ref = consumer_ref.copy() - consumer_ref.pop('secret', None) - return consumer_ref - - -def filter_token(access_token_ref): - """Filter out private items in an access token dict. - - 'access_secret' is never returned. - - :returns: access_token_ref - - """ - if access_token_ref: - access_token_ref = access_token_ref.copy() - access_token_ref.pop('access_secret', None) - return access_token_ref - - -def get_oauth_headers(headers): - parameters = {} - - # The incoming headers variable is your usual heading from context - # In an OAuth signed req, where the oauth variables are in the header, - # they with the key 'Authorization'. - - if headers and 'Authorization' in headers: - # A typical value for Authorization is seen below - # 'OAuth realm="", oauth_body_hash="2jm%3D", oauth_nonce="14475435" - # along with other oauth variables, the 'OAuth ' part is trimmed - # to split the rest of the headers. - - auth_header = headers['Authorization'] - params = oauth1.rfc5849.utils.parse_authorization_header(auth_header) - parameters.update(dict(params)) - return parameters - else: - msg = _LE('Cannot retrieve Authorization headers') - LOG.error(msg) - raise exception.OAuthHeadersMissingError() - - -def extract_non_oauth_params(query_string): - params = oauthlib.common.extract_params(query_string) - return {k: v for k, v in params if not k.startswith('oauth_')} - - -@dependency.provider('oauth_api') -class Manager(manager.Manager): - """Default pivot point for the OAuth1 backend. - - See :mod:`keystone.common.manager.Manager` for more details on how this - dynamically calls the backend. - - """ - - driver_namespace = 'keystone.oauth1' - - _ACCESS_TOKEN = "OS-OAUTH1:access_token" - _REQUEST_TOKEN = "OS-OAUTH1:request_token" - _CONSUMER = "OS-OAUTH1:consumer" - - def __init__(self): - super(Manager, self).__init__(CONF.oauth1.driver) - - def create_consumer(self, consumer_ref, initiator=None): - ret = self.driver.create_consumer(consumer_ref) - notifications.Audit.created(self._CONSUMER, ret['id'], initiator) - return ret - - def update_consumer(self, consumer_id, consumer_ref, initiator=None): - ret = self.driver.update_consumer(consumer_id, consumer_ref) - notifications.Audit.updated(self._CONSUMER, consumer_id, initiator) - return ret - - def delete_consumer(self, consumer_id, initiator=None): - ret = self.driver.delete_consumer(consumer_id) - notifications.Audit.deleted(self._CONSUMER, consumer_id, initiator) - return ret - - def create_access_token(self, request_id, access_token_duration, - initiator=None): - ret = self.driver.create_access_token(request_id, - access_token_duration) - notifications.Audit.created(self._ACCESS_TOKEN, ret['id'], initiator) - return ret - - def delete_access_token(self, user_id, access_token_id, initiator=None): - ret = self.driver.delete_access_token(user_id, access_token_id) - notifications.Audit.deleted(self._ACCESS_TOKEN, access_token_id, - initiator) - return ret - - def create_request_token(self, consumer_id, requested_project, - request_token_duration, initiator=None): - ret = self.driver.create_request_token( - consumer_id, requested_project, request_token_duration) - notifications.Audit.created(self._REQUEST_TOKEN, ret['id'], - initiator) - return ret - - -@six.add_metaclass(abc.ABCMeta) -class Oauth1DriverV8(object): - """Interface description for an OAuth1 driver.""" - - @abc.abstractmethod - def create_consumer(self, consumer_ref): - """Create consumer. - - :param consumer_ref: consumer ref with consumer name - :type consumer_ref: dict - :returns: consumer_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def update_consumer(self, consumer_id, consumer_ref): - """Update consumer. - - :param consumer_id: id of consumer to update - :type consumer_id: string - :param consumer_ref: new consumer ref with consumer name - :type consumer_ref: dict - :returns: consumer_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_consumers(self): - """List consumers. - - :returns: list of consumers - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_consumer(self, consumer_id): - """Get consumer, returns the consumer id (key) - and description. - - :param consumer_id: id of consumer to get - :type consumer_id: string - :returns: consumer_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_consumer_with_secret(self, consumer_id): - """Like get_consumer() but returned consumer_ref includes - the consumer secret. - - Secrets should only be shared upon consumer creation; the - consumer secret is required to verify incoming OAuth requests. - - :param consumer_id: id of consumer to get - :type consumer_id: string - :returns: consumer_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_consumer(self, consumer_id): - """Delete consumer. - - :param consumer_id: id of consumer to get - :type consumer_id: string - :returns: None. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def list_access_tokens(self, user_id): - """List access tokens. - - :param user_id: search for access tokens authorized by given user id - :type user_id: string - :returns: list of access tokens the user has authorized - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def delete_access_token(self, user_id, access_token_id): - """Delete access token. - - :param user_id: authorizing user id - :type user_id: string - :param access_token_id: access token to delete - :type access_token_id: string - :returns: None - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def create_request_token(self, consumer_id, requested_project, - request_token_duration): - """Create request token. - - :param consumer_id: the id of the consumer - :type consumer_id: string - :param requested_project_id: requested project id - :type requested_project_id: string - :param request_token_duration: duration of request token - :type request_token_duration: string - :returns: request_token_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_request_token(self, request_token_id): - """Get request token. - - :param request_token_id: the id of the request token - :type request_token_id: string - :returns: request_token_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def get_access_token(self, access_token_id): - """Get access token. - - :param access_token_id: the id of the access token - :type access_token_id: string - :returns: access_token_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def authorize_request_token(self, request_id, user_id, role_ids): - """Authorize request token. - - :param request_id: the id of the request token, to be authorized - :type request_id: string - :param user_id: the id of the authorizing user - :type user_id: string - :param role_ids: list of role ids to authorize - :type role_ids: list - :returns: verifier - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def create_access_token(self, request_id, access_token_duration): - """Create access token. - - :param request_id: the id of the request token, to be deleted - :type request_id: string - :param access_token_duration: duration of an access token - :type access_token_duration: string - :returns: access_token_ref - - """ - raise exception.NotImplemented() # pragma: no cover - - -Driver = manager.create_legacy_driver(Oauth1DriverV8) diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/oauth1/migrate_repo/migrate.cfg deleted file mode 100644 index 97ca7810..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=oauth1 - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/001_add_oauth_tables.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/001_add_oauth_tables.py deleted file mode 100644 index fe0212d7..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/001_add_oauth_tables.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='oauth1') diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/002_fix_oauth_tables_fk.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/002_fix_oauth_tables_fk.py deleted file mode 100644 index fe0212d7..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/002_fix_oauth_tables_fk.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='oauth1') diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/003_consumer_description_nullalbe.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/003_consumer_description_nullalbe.py deleted file mode 100644 index fe0212d7..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/003_consumer_description_nullalbe.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='oauth1') diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/004_request_token_roles_nullable.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/004_request_token_roles_nullable.py deleted file mode 100644 index fe0212d7..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/004_request_token_roles_nullable.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='oauth1') diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/005_consumer_id_index.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/005_consumer_id_index.py deleted file mode 100644 index a4681e16..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/005_consumer_id_index.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2014 Mirantis.inc -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='oauth1') diff --git a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/oauth1/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/oauth1/routers.py b/keystone-moon/keystone/contrib/oauth1/routers.py deleted file mode 100644 index 42a26c10..00000000 --- a/keystone-moon/keystone/contrib/oauth1/routers.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class OAuth1Extension(wsgi.Middleware): - - def __init__(self, *args, **kwargs): - super(OAuth1Extension, self).__init__(*args, **kwargs) - msg = _("Remove oauth1_extension from the paste pipeline, the " - "oauth1 extension is now always available. Update the " - "[pipeline:api_v3] section in keystone-paste.ini accordingly, " - "as it will be removed in the O release.") - versionutils.report_deprecated_feature(LOG, msg) diff --git a/keystone-moon/keystone/contrib/oauth1/validator.py b/keystone-moon/keystone/contrib/oauth1/validator.py deleted file mode 100644 index 8f44059e..00000000 --- a/keystone-moon/keystone/contrib/oauth1/validator.py +++ /dev/null @@ -1,179 +0,0 @@ -# Copyright 2014 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""oAuthlib request validator.""" - -from oslo_log import log -import six - -from keystone.common import dependency -from keystone.contrib.oauth1 import core as oauth1 -from keystone import exception - - -METHOD_NAME = 'oauth_validator' -LOG = log.getLogger(__name__) - - -@dependency.requires('oauth_api') -class OAuthValidator(oauth1.RequestValidator): - - # TODO(mhu) set as option probably? - @property - def enforce_ssl(self): - return False - - @property - def safe_characters(self): - # oauth tokens are generated from a uuid hex value - return set("abcdef0123456789") - - def _check_token(self, token): - # generic token verification when they're obtained from a uuid hex - return (set(token) <= self.safe_characters and - len(token) == 32) - - def check_client_key(self, client_key): - return self._check_token(client_key) - - def check_request_token(self, request_token): - return self._check_token(request_token) - - def check_access_token(self, access_token): - return self._check_token(access_token) - - def check_nonce(self, nonce): - # Assuming length is not a concern - return set(nonce) <= self.safe_characters - - def check_verifier(self, verifier): - return (all(i in oauth1.VERIFIER_CHARS for i in verifier) and - len(verifier) == 8) - - def get_client_secret(self, client_key, request): - client = self.oauth_api.get_consumer_with_secret(client_key) - return client['secret'] - - def get_request_token_secret(self, client_key, token, request): - token_ref = self.oauth_api.get_request_token(token) - return token_ref['request_secret'] - - def get_access_token_secret(self, client_key, token, request): - access_token = self.oauth_api.get_access_token(token) - return access_token['access_secret'] - - def get_default_realms(self, client_key, request): - # realms weren't implemented with the previous library - return [] - - def get_realms(self, token, request): - return [] - - def get_redirect_uri(self, token, request): - # OOB (out of band) is supposed to be the default value to use - return 'oob' - - def get_rsa_key(self, client_key, request): - # HMAC signing is used, so return a dummy value - return '' - - def invalidate_request_token(self, client_key, request_token, request): - # this method is invoked when an access token is generated out of a - # request token, to make sure that request token cannot be consumed - # anymore. This is done in the backend, so we do nothing here. - pass - - def validate_client_key(self, client_key, request): - try: - return self.oauth_api.get_consumer(client_key) is not None - except exception.NotFound: - return False - - def validate_request_token(self, client_key, token, request): - try: - return self.oauth_api.get_request_token(token) is not None - except exception.NotFound: - return False - - def validate_access_token(self, client_key, token, request): - try: - return self.oauth_api.get_access_token(token) is not None - except exception.NotFound: - return False - - def validate_timestamp_and_nonce(self, - client_key, - timestamp, - nonce, - request, - request_token=None, - access_token=None): - return True - - def validate_redirect_uri(self, client_key, redirect_uri, request): - # we expect OOB, we don't really care - return True - - def validate_requested_realms(self, client_key, realms, request): - # realms are not used - return True - - def validate_realms(self, - client_key, - token, - request, - uri=None, - realms=None): - return True - - def validate_verifier(self, client_key, token, verifier, request): - try: - req_token = self.oauth_api.get_request_token(token) - return req_token['verifier'] == verifier - except exception.NotFound: - return False - - def verify_request_token(self, token, request): - # there aren't strong expectations on the request token format - return isinstance(token, six.string_types) - - def verify_realms(self, token, realms, request): - return True - - # The following save_XXX methods are called to create tokens. I chose to - # keep the original logic, but the comments below show how that could be - # implemented. The real implementation logic is in the backend. - def save_access_token(self, token, request): - pass -# token_duration = CONF.oauth1.request_token_duration -# request_token_id = request.client_key -# self.oauth_api.create_access_token(request_token_id, -# token_duration, -# token["oauth_token"], -# token["oauth_token_secret"]) - - def save_request_token(self, token, request): - pass -# project_id = request.headers.get('Requested-Project-Id') -# token_duration = CONF.oauth1.request_token_duration -# self.oauth_api.create_request_token(request.client_key, -# project_id, -# token_duration, -# token["oauth_token"], -# token["oauth_token_secret"]) - - def save_verifier(self, token, verifier, request): - # keep the old logic for this, as it is done in two steps and requires - # information that the request validator has no access to - pass diff --git a/keystone-moon/keystone/contrib/revoke/__init__.py b/keystone-moon/keystone/contrib/revoke/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/revoke/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/revoke/backends/__init__.py b/keystone-moon/keystone/contrib/revoke/backends/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/revoke/backends/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/revoke/backends/kvs.py b/keystone-moon/keystone/contrib/revoke/backends/kvs.py deleted file mode 100644 index 086becb0..00000000 --- a/keystone-moon/keystone/contrib/revoke/backends/kvs.py +++ /dev/null @@ -1,74 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import datetime - -from oslo_config import cfg -from oslo_log import versionutils -from oslo_utils import timeutils - -from keystone.common import kvs -from keystone.contrib import revoke -from keystone import exception - - -CONF = cfg.CONF - -_EVENT_KEY = 'os-revoke-events' -_KVS_BACKEND = 'openstack.kvs.Memory' - - -class Revoke(revoke.RevokeDriverV8): - - @versionutils.deprecated( - versionutils.deprecated.JUNO, - in_favor_of='keystone.contrib.revoke.backends.sql', - remove_in=+1, - what='keystone.contrib.revoke.backends.kvs') - def __init__(self, **kwargs): - super(Revoke, self).__init__() - self._store = kvs.get_key_value_store('os-revoke-driver') - self._store.configure(backing_store=_KVS_BACKEND, **kwargs) - - def _list_events(self): - try: - return self._store.get(_EVENT_KEY) - except exception.NotFound: - return [] - - def list_events(self, last_fetch=None): - results = [] - - with self._store.get_lock(_EVENT_KEY): - events = self._list_events() - - for event in events: - revoked_at = event.revoked_at - if last_fetch is None or revoked_at > last_fetch: - results.append(event) - return results - - def revoke(self, event): - pruned = [] - expire_delta = datetime.timedelta(seconds=CONF.token.expiration) - oldest = timeutils.utcnow() - expire_delta - - with self._store.get_lock(_EVENT_KEY) as lock: - events = self._list_events() - if event: - events.append(event) - - for event in events: - revoked_at = event.revoked_at - if revoked_at > oldest: - pruned.append(event) - self._store.set(_EVENT_KEY, pruned, lock) diff --git a/keystone-moon/keystone/contrib/revoke/backends/sql.py b/keystone-moon/keystone/contrib/revoke/backends/sql.py deleted file mode 100644 index 0bf493ae..00000000 --- a/keystone-moon/keystone/contrib/revoke/backends/sql.py +++ /dev/null @@ -1,28 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import versionutils - -from keystone.revoke.backends import sql - - -_OLD = "keystone.contrib.revoke.backends.sql.Revoke" -_NEW = "sql" - - -class Revoke(sql.Revoke): - - @versionutils.deprecated(versionutils.deprecated.MITAKA, - in_favor_of=_NEW, - what=_OLD) - def __init__(self, *args, **kwargs): - super(Revoke, self).__init__(*args, **kwargs) diff --git a/keystone-moon/keystone/contrib/revoke/controllers.py b/keystone-moon/keystone/contrib/revoke/controllers.py deleted file mode 100644 index 40151bae..00000000 --- a/keystone-moon/keystone/contrib/revoke/controllers.py +++ /dev/null @@ -1,44 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_utils import timeutils - -from keystone.common import controller -from keystone.common import dependency -from keystone import exception -from keystone.i18n import _ - - -@dependency.requires('revoke_api') -class RevokeController(controller.V3Controller): - @controller.protected() - def list_revoke_events(self, context): - since = context['query_string'].get('since') - last_fetch = None - if since: - try: - last_fetch = timeutils.normalize_time( - timeutils.parse_isotime(since)) - except ValueError: - raise exception.ValidationError( - message=_('invalid date format %s') % since) - events = self.revoke_api.list_events(last_fetch=last_fetch) - # Build the links by hand as the standard controller calls require ids - response = {'events': [event.to_dict() for event in events], - 'links': { - 'next': None, - 'self': RevokeController.base_url( - context, - path=context['path']), - 'previous': None} - } - return response diff --git a/keystone-moon/keystone/contrib/revoke/core.py b/keystone-moon/keystone/contrib/revoke/core.py deleted file mode 100644 index 3b108c9e..00000000 --- a/keystone-moon/keystone/contrib/revoke/core.py +++ /dev/null @@ -1,262 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into the Revoke service.""" - -import abc -import datetime - -from oslo_config import cfg -from oslo_log import log -from oslo_log import versionutils -from oslo_utils import timeutils -import six - -from keystone.common import cache -from keystone.common import dependency -from keystone.common import extension -from keystone.common import manager -from keystone.contrib.revoke import model -from keystone import exception -from keystone.i18n import _ -from keystone import notifications - - -CONF = cfg.CONF -LOG = log.getLogger(__name__) - - -EXTENSION_DATA = { - 'name': 'OpenStack Revoke API', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-REVOKE/v1.0', - 'alias': 'OS-REVOKE', - 'updated': '2014-02-24T20:51:0-00:00', - 'description': 'OpenStack revoked token reporting mechanism.', - 'links': [ - { - 'rel': 'describedby', - 'type': 'text/html', - 'href': ('https://github.com/openstack/identity-api/blob/master/' - 'openstack-identity-api/v3/src/markdown/' - 'identity-api-v3-os-revoke-ext.md'), - } - ]} -extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) -extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) - -MEMOIZE = cache.get_memoization_decorator(section='revoke') - - -def revoked_before_cutoff_time(): - expire_delta = datetime.timedelta( - seconds=CONF.token.expiration + CONF.revoke.expiration_buffer) - oldest = timeutils.utcnow() - expire_delta - return oldest - - -@dependency.provider('revoke_api') -class Manager(manager.Manager): - """Default pivot point for the Revoke backend. - - Performs common logic for recording revocations. - - See :mod:`keystone.common.manager.Manager` for more details on - how this dynamically calls the backend. - - """ - - driver_namespace = 'keystone.revoke' - - def __init__(self): - super(Manager, self).__init__(CONF.revoke.driver) - self._register_listeners() - self.model = model - - def _user_callback(self, service, resource_type, operation, - payload): - self.revoke_by_user(payload['resource_info']) - - def _role_callback(self, service, resource_type, operation, - payload): - self.revoke( - model.RevokeEvent(role_id=payload['resource_info'])) - - def _project_callback(self, service, resource_type, operation, - payload): - self.revoke( - model.RevokeEvent(project_id=payload['resource_info'])) - - def _domain_callback(self, service, resource_type, operation, - payload): - self.revoke( - model.RevokeEvent(domain_id=payload['resource_info'])) - - def _trust_callback(self, service, resource_type, operation, - payload): - self.revoke( - model.RevokeEvent(trust_id=payload['resource_info'])) - - def _consumer_callback(self, service, resource_type, operation, - payload): - self.revoke( - model.RevokeEvent(consumer_id=payload['resource_info'])) - - def _access_token_callback(self, service, resource_type, operation, - payload): - self.revoke( - model.RevokeEvent(access_token_id=payload['resource_info'])) - - def _role_assignment_callback(self, service, resource_type, operation, - payload): - info = payload['resource_info'] - self.revoke_by_grant(role_id=info['role_id'], user_id=info['user_id'], - domain_id=info.get('domain_id'), - project_id=info.get('project_id')) - - def _register_listeners(self): - callbacks = { - notifications.ACTIONS.deleted: [ - ['OS-TRUST:trust', self._trust_callback], - ['OS-OAUTH1:consumer', self._consumer_callback], - ['OS-OAUTH1:access_token', self._access_token_callback], - ['role', self._role_callback], - ['user', self._user_callback], - ['project', self._project_callback], - ['role_assignment', self._role_assignment_callback] - ], - notifications.ACTIONS.disabled: [ - ['user', self._user_callback], - ['project', self._project_callback], - ['domain', self._domain_callback], - ], - notifications.ACTIONS.internal: [ - [notifications.INVALIDATE_USER_TOKEN_PERSISTENCE, - self._user_callback], - ] - } - - for event, cb_info in callbacks.items(): - for resource_type, callback_fns in cb_info: - notifications.register_event_callback(event, resource_type, - callback_fns) - - def revoke_by_user(self, user_id): - return self.revoke(model.RevokeEvent(user_id=user_id)) - - def _assert_not_domain_and_project_scoped(self, domain_id=None, - project_id=None): - if domain_id is not None and project_id is not None: - msg = _('The revoke call must not have both domain_id and ' - 'project_id. This is a bug in the Keystone server. The ' - 'current request is aborted.') - raise exception.UnexpectedError(exception=msg) - - @versionutils.deprecated(as_of=versionutils.deprecated.JUNO, - remove_in=0) - def revoke_by_expiration(self, user_id, expires_at, - domain_id=None, project_id=None): - - self._assert_not_domain_and_project_scoped(domain_id=domain_id, - project_id=project_id) - - self.revoke( - model.RevokeEvent(user_id=user_id, - expires_at=expires_at, - domain_id=domain_id, - project_id=project_id)) - - def revoke_by_audit_id(self, audit_id): - self.revoke(model.RevokeEvent(audit_id=audit_id)) - - def revoke_by_audit_chain_id(self, audit_chain_id, project_id=None, - domain_id=None): - - self._assert_not_domain_and_project_scoped(domain_id=domain_id, - project_id=project_id) - - self.revoke(model.RevokeEvent(audit_chain_id=audit_chain_id, - domain_id=domain_id, - project_id=project_id)) - - def revoke_by_grant(self, role_id, user_id=None, - domain_id=None, project_id=None): - self.revoke( - model.RevokeEvent(user_id=user_id, - role_id=role_id, - domain_id=domain_id, - project_id=project_id)) - - def revoke_by_user_and_project(self, user_id, project_id): - self.revoke( - model.RevokeEvent(project_id=project_id, user_id=user_id)) - - def revoke_by_project_role_assignment(self, project_id, role_id): - self.revoke(model.RevokeEvent(project_id=project_id, role_id=role_id)) - - def revoke_by_domain_role_assignment(self, domain_id, role_id): - self.revoke(model.RevokeEvent(domain_id=domain_id, role_id=role_id)) - - @MEMOIZE - def _get_revoke_tree(self): - events = self.driver.list_events() - revoke_tree = model.RevokeTree(revoke_events=events) - - return revoke_tree - - def check_token(self, token_values): - """Checks the values from a token against the revocation list - - :param token_values: dictionary of values from a token, - normalized for differences between v2 and v3. The checked values are a - subset of the attributes of model.TokenEvent - - :raises exception.TokenNotFound: if the token is invalid - - """ - if self._get_revoke_tree().is_revoked(token_values): - raise exception.TokenNotFound(_('Failed to validate token')) - - def revoke(self, event): - self.driver.revoke(event) - self._get_revoke_tree.invalidate(self) - - -@six.add_metaclass(abc.ABCMeta) -class RevokeDriverV8(object): - """Interface for recording and reporting revocation events.""" - - @abc.abstractmethod - def list_events(self, last_fetch=None): - """return the revocation events, as a list of objects - - :param last_fetch: Time of last fetch. Return all events newer. - :returns: A list of keystone.contrib.revoke.model.RevokeEvent - newer than `last_fetch.` - If no last_fetch is specified, returns all events - for tokens issued after the expiration cutoff. - - """ - raise exception.NotImplemented() # pragma: no cover - - @abc.abstractmethod - def revoke(self, event): - """register a revocation event - - :param event: An instance of - keystone.contrib.revoke.model.RevocationEvent - - """ - raise exception.NotImplemented() # pragma: no cover - - -Driver = manager.create_legacy_driver(RevokeDriverV8) diff --git a/keystone-moon/keystone/contrib/revoke/migrate_repo/__init__.py b/keystone-moon/keystone/contrib/revoke/migrate_repo/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/revoke/migrate_repo/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/revoke/migrate_repo/migrate.cfg b/keystone-moon/keystone/contrib/revoke/migrate_repo/migrate.cfg deleted file mode 100644 index 0e61bcaa..00000000 --- a/keystone-moon/keystone/contrib/revoke/migrate_repo/migrate.cfg +++ /dev/null @@ -1,25 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=revoke - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] - -# When creating new change scripts, Migrate will stamp the new script with -# a version number. By default this is latest_version + 1. You can set this -# to 'true' to tell Migrate to use the UTC timestamp instead. -use_timestamp_numbering=False diff --git a/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/001_revoke_table.py b/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/001_revoke_table.py deleted file mode 100644 index 81c535e1..00000000 --- a/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/001_revoke_table.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='revoke') diff --git a/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/002_add_audit_id_and_chain_to_revoke_table.py b/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/002_add_audit_id_and_chain_to_revoke_table.py deleted file mode 100644 index 81c535e1..00000000 --- a/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/002_add_audit_id_and_chain_to_revoke_table.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone import exception - - -def upgrade(migrate_engine): - raise exception.MigrationMovedFailure(extension='revoke') diff --git a/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/__init__.py b/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/keystone-moon/keystone/contrib/revoke/migrate_repo/versions/__init__.py +++ /dev/null diff --git a/keystone-moon/keystone/contrib/revoke/model.py b/keystone-moon/keystone/contrib/revoke/model.py deleted file mode 100644 index e677bfb5..00000000 --- a/keystone-moon/keystone/contrib/revoke/model.py +++ /dev/null @@ -1,371 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_utils import timeutils -from six.moves import map - -from keystone.common import utils - - -# The set of attributes common between the RevokeEvent -# and the dictionaries created from the token Data. -_NAMES = ['trust_id', - 'consumer_id', - 'access_token_id', - 'audit_id', - 'audit_chain_id', - 'expires_at', - 'domain_id', - 'project_id', - 'user_id', - 'role_id'] - - -# Additional arguments for creating a RevokeEvent -_EVENT_ARGS = ['issued_before', 'revoked_at'] - -# Names of attributes in the RevocationEvent, including "virtual" attributes. -# Virtual attributes are those added based on other values. -_EVENT_NAMES = _NAMES + ['domain_scope_id'] - -# Values that will be in the token data but not in the event. -# These will compared with event values that have different names. -# For example: both trustor_id and trustee_id are compared against user_id -_TOKEN_KEYS = ['identity_domain_id', - 'assignment_domain_id', - 'issued_at', - 'trustor_id', - 'trustee_id'] - -# Alternative names to be checked in token for every field in -# revoke tree. -ALTERNATIVES = { - 'user_id': ['user_id', 'trustor_id', 'trustee_id'], - 'domain_id': ['identity_domain_id', 'assignment_domain_id'], - # For a domain-scoped token, the domain is in assignment_domain_id. - 'domain_scope_id': ['assignment_domain_id', ], -} - - -REVOKE_KEYS = _NAMES + _EVENT_ARGS - - -def blank_token_data(issued_at): - token_data = dict() - for name in _NAMES: - token_data[name] = None - for name in _TOKEN_KEYS: - token_data[name] = None - # required field - token_data['issued_at'] = issued_at - return token_data - - -class RevokeEvent(object): - def __init__(self, **kwargs): - for k in REVOKE_KEYS: - v = kwargs.get(k, None) - setattr(self, k, v) - - if self.domain_id and self.expires_at: - # This is revoking a domain-scoped token. - self.domain_scope_id = self.domain_id - self.domain_id = None - else: - # This is revoking all tokens for a domain. - self.domain_scope_id = None - - if self.expires_at is not None: - # Trim off the expiration time because MySQL timestamps are only - # accurate to the second. - self.expires_at = self.expires_at.replace(microsecond=0) - - if self.revoked_at is None: - self.revoked_at = timeutils.utcnow() - if self.issued_before is None: - self.issued_before = self.revoked_at - - def to_dict(self): - keys = ['user_id', - 'role_id', - 'domain_id', - 'domain_scope_id', - 'project_id', - 'audit_id', - 'audit_chain_id', - ] - event = {key: self.__dict__[key] for key in keys - if self.__dict__[key] is not None} - if self.trust_id is not None: - event['OS-TRUST:trust_id'] = self.trust_id - if self.consumer_id is not None: - event['OS-OAUTH1:consumer_id'] = self.consumer_id - if self.consumer_id is not None: - event['OS-OAUTH1:access_token_id'] = self.access_token_id - if self.expires_at is not None: - event['expires_at'] = utils.isotime(self.expires_at) - if self.issued_before is not None: - event['issued_before'] = utils.isotime(self.issued_before, - subsecond=True) - return event - - def key_for_name(self, name): - return "%s=%s" % (name, getattr(self, name) or '*') - - -def attr_keys(event): - return list(map(event.key_for_name, _EVENT_NAMES)) - - -class RevokeTree(object): - """Fast Revocation Checking Tree Structure - - The Tree is an index to quickly match tokens against events. - Each node is a hashtable of key=value combinations from revocation events. - The - - """ - - def __init__(self, revoke_events=None): - self.revoke_map = dict() - self.add_events(revoke_events) - - def add_event(self, event): - """Updates the tree based on a revocation event. - - Creates any necessary internal nodes in the tree corresponding to the - fields of the revocation event. The leaf node will always be set to - the latest 'issued_before' for events that are otherwise identical. - - :param: Event to add to the tree - - :returns: the event that was passed in. - - """ - revoke_map = self.revoke_map - for key in attr_keys(event): - revoke_map = revoke_map.setdefault(key, {}) - revoke_map['issued_before'] = max( - event.issued_before, revoke_map.get( - 'issued_before', event.issued_before)) - return event - - def remove_event(self, event): - """Update the tree based on the removal of a Revocation Event - - Removes empty nodes from the tree from the leaf back to the root. - - If multiple events trace the same path, but have different - 'issued_before' values, only the last is ever stored in the tree. - So only an exact match on 'issued_before' ever triggers a removal - - :param: Event to remove from the tree - - """ - stack = [] - revoke_map = self.revoke_map - for name in _EVENT_NAMES: - key = event.key_for_name(name) - nxt = revoke_map.get(key) - if nxt is None: - break - stack.append((revoke_map, key, nxt)) - revoke_map = nxt - else: - if event.issued_before == revoke_map['issued_before']: - revoke_map.pop('issued_before') - for parent, key, child in reversed(stack): - if not any(child): - del parent[key] - - def add_events(self, revoke_events): - return list(map(self.add_event, revoke_events or [])) - - @staticmethod - def _next_level_keys(name, token_data): - """Generate keys based on current field name and token data - - Generate all keys to look for in the next iteration of revocation - event tree traversal. - """ - yield '*' - if name == 'role_id': - # Roles are very special since a token has a list of them. - # If the revocation event matches any one of them, - # revoke the token. - for role_id in token_data.get('roles', []): - yield role_id - else: - # For other fields we try to get any branch that concur - # with any alternative field in the token. - for alt_name in ALTERNATIVES.get(name, [name]): - yield token_data[alt_name] - - def _search(self, revoke_map, names, token_data): - """Search for revocation event by token_data - - Traverse the revocation events tree looking for event matching token - data issued after the token. - """ - if not names: - # The last (leaf) level is checked in a special way because we - # verify issued_at field differently. - try: - return revoke_map['issued_before'] >= token_data['issued_at'] - except KeyError: - return False - - name, remaining_names = names[0], names[1:] - - for key in self._next_level_keys(name, token_data): - subtree = revoke_map.get('%s=%s' % (name, key)) - if subtree and self._search(subtree, remaining_names, token_data): - return True - - # If we made it out of the loop then no element in revocation tree - # corresponds to our token and it is good. - return False - - def is_revoked(self, token_data): - """Check if a token matches the revocation event - - Compare the values for each level of the tree with the values from - the token, accounting for attributes that have alternative - keys, and for wildcard matches. - if there is a match, continue down the tree. - if there is no match, exit early. - - token_data is a map based on a flattened view of token. - The required fields are: - - 'expires_at','user_id', 'project_id', 'identity_domain_id', - 'assignment_domain_id', 'trust_id', 'trustor_id', 'trustee_id' - 'consumer_id', 'access_token_id' - - """ - return self._search(self.revoke_map, _EVENT_NAMES, token_data) - - -def build_token_values_v2(access, default_domain_id): - token_data = access['token'] - - token_expires_at = timeutils.parse_isotime(token_data['expires']) - - # Trim off the microseconds because the revocation event only has - # expirations accurate to the second. - token_expires_at = token_expires_at.replace(microsecond=0) - - token_values = { - 'expires_at': timeutils.normalize_time(token_expires_at), - 'issued_at': timeutils.normalize_time( - timeutils.parse_isotime(token_data['issued_at'])), - 'audit_id': token_data.get('audit_ids', [None])[0], - 'audit_chain_id': token_data.get('audit_ids', [None])[-1], - } - - token_values['user_id'] = access.get('user', {}).get('id') - - project = token_data.get('tenant') - if project is not None: - token_values['project_id'] = project['id'] - else: - token_values['project_id'] = None - - token_values['identity_domain_id'] = default_domain_id - token_values['assignment_domain_id'] = default_domain_id - - trust = token_data.get('trust') - if trust is None: - token_values['trust_id'] = None - token_values['trustor_id'] = None - token_values['trustee_id'] = None - else: - token_values['trust_id'] = trust['id'] - token_values['trustor_id'] = trust['trustor_id'] - token_values['trustee_id'] = trust['trustee_id'] - - token_values['consumer_id'] = None - token_values['access_token_id'] = None - - role_list = [] - # Roles are by ID in metadata and by name in the user section - roles = access.get('metadata', {}).get('roles', []) - for role in roles: - role_list.append(role) - token_values['roles'] = role_list - return token_values - - -def build_token_values(token_data): - - token_expires_at = timeutils.parse_isotime(token_data['expires_at']) - - # Trim off the microseconds because the revocation event only has - # expirations accurate to the second. - token_expires_at = token_expires_at.replace(microsecond=0) - - token_values = { - 'expires_at': timeutils.normalize_time(token_expires_at), - 'issued_at': timeutils.normalize_time( - timeutils.parse_isotime(token_data['issued_at'])), - 'audit_id': token_data.get('audit_ids', [None])[0], - 'audit_chain_id': token_data.get('audit_ids', [None])[-1], - } - - user = token_data.get('user') - if user is not None: - token_values['user_id'] = user['id'] - # Federated users do not have a domain, be defensive and get the user - # domain set to None in the federated user case. - token_values['identity_domain_id'] = user.get('domain', {}).get('id') - else: - token_values['user_id'] = None - token_values['identity_domain_id'] = None - - project = token_data.get('project', token_data.get('tenant')) - if project is not None: - token_values['project_id'] = project['id'] - token_values['assignment_domain_id'] = project['domain']['id'] - else: - token_values['project_id'] = None - - domain = token_data.get('domain') - if domain is not None: - token_values['assignment_domain_id'] = domain['id'] - else: - token_values['assignment_domain_id'] = None - - role_list = [] - roles = token_data.get('roles') - if roles is not None: - for role in roles: - role_list.append(role['id']) - token_values['roles'] = role_list - - trust = token_data.get('OS-TRUST:trust') - if trust is None: - token_values['trust_id'] = None - token_values['trustor_id'] = None - token_values['trustee_id'] = None - else: - token_values['trust_id'] = trust['id'] - token_values['trustor_id'] = trust['trustor_user']['id'] - token_values['trustee_id'] = trust['trustee_user']['id'] - - oauth1 = token_data.get('OS-OAUTH1') - if oauth1 is None: - token_values['consumer_id'] = None - token_values['access_token_id'] = None - else: - token_values['consumer_id'] = oauth1['consumer_id'] - token_values['access_token_id'] = oauth1['access_token_id'] - return token_values diff --git a/keystone-moon/keystone/contrib/revoke/routers.py b/keystone-moon/keystone/contrib/revoke/routers.py deleted file mode 100644 index a44c6194..00000000 --- a/keystone-moon/keystone/contrib/revoke/routers.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class RevokeExtension(wsgi.Middleware): - - def __init__(self, *args, **kwargs): - super(RevokeExtension, self).__init__(*args, **kwargs) - msg = _("Remove revoke_extension from the paste pipeline, the " - "revoke extension is now always available. Update the " - "[pipeline:api_v3] section in keystone-paste.ini accordingly, " - "as it will be removed in the O release.") - versionutils.report_deprecated_feature(LOG, msg) diff --git a/keystone-moon/keystone/contrib/s3/__init__.py b/keystone-moon/keystone/contrib/s3/__init__.py deleted file mode 100644 index eec77c72..00000000 --- a/keystone-moon/keystone/contrib/s3/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.contrib.s3.core import * # noqa diff --git a/keystone-moon/keystone/contrib/s3/core.py b/keystone-moon/keystone/contrib/s3/core.py deleted file mode 100644 index c497f5d5..00000000 --- a/keystone-moon/keystone/contrib/s3/core.py +++ /dev/null @@ -1,125 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Main entry point into the S3 Credentials service. - -This service provides S3 token validation for services configured with the -s3_token middleware to authorize S3 requests. - -This service uses the same credentials used by EC2. Refer to the documentation -for the EC2 module for how to generate the required credentials. -""" - -import base64 -import hashlib -import hmac - -import six - -from keystone.common import extension -from keystone.common import json_home -from keystone.common import utils -from keystone.common import wsgi -from keystone.contrib.ec2 import controllers -from keystone import exception -from keystone.i18n import _ - - -EXTENSION_DATA = { - 'name': 'OpenStack S3 API', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 's3tokens/v1.0', - 'alias': 's3tokens', - 'updated': '2013-07-07T12:00:0-00:00', - 'description': 'OpenStack S3 API.', - 'links': [ - { - 'rel': 'describedby', - 'type': 'text/html', - 'href': 'http://developer.openstack.org/' - 'api-ref-identity-v2-ext.html', - } - ]} -extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) - - -class S3Extension(wsgi.V3ExtensionRouter): - def add_routes(self, mapper): - controller = S3Controller() - # validation - self._add_resource( - mapper, controller, - path='/s3tokens', - post_action='authenticate', - rel=json_home.build_v3_extension_resource_relation( - 's3tokens', '1.0', 's3tokens')) - - -class S3Controller(controllers.Ec2Controller): - def check_signature(self, creds_ref, credentials): - string_to_sign = base64.urlsafe_b64decode(str(credentials['token'])) - - if string_to_sign[0:4] != b'AWS4': - signature = self._calculate_signature_v1(string_to_sign, - creds_ref['secret']) - else: - signature = self._calculate_signature_v4(string_to_sign, - creds_ref['secret']) - - if not utils.auth_str_equal(credentials['signature'], signature): - raise exception.Unauthorized( - message=_('Credential signature mismatch')) - - def _calculate_signature_v1(self, string_to_sign, secret_key): - """Calculates a v1 signature. - - :param bytes string_to_sign: String that contains request params and - is used for calculate signature of request - :param text secret_key: Second auth key of EC2 account that is used to - sign requests - """ - key = str(secret_key).encode('utf-8') - if six.PY2: - b64_encode = base64.encodestring - else: - b64_encode = base64.encodebytes - signed = b64_encode(hmac.new(key, string_to_sign, hashlib.sha1) - .digest()).decode('utf-8').strip() - return signed - - def _calculate_signature_v4(self, string_to_sign, secret_key): - """Calculates a v4 signature. - - :param bytes string_to_sign: String that contains request params and - is used for calculate signature of request - :param text secret_key: Second auth key of EC2 account that is used to - sign requests - """ - parts = string_to_sign.split(b'\n') - if len(parts) != 4 or parts[0] != b'AWS4-HMAC-SHA256': - raise exception.Unauthorized(message=_('Invalid EC2 signature.')) - scope = parts[2].split(b'/') - if len(scope) != 4 or scope[2] != b's3' or scope[3] != b'aws4_request': - raise exception.Unauthorized(message=_('Invalid EC2 signature.')) - - def _sign(key, msg): - return hmac.new(key, msg, hashlib.sha256).digest() - - signed = _sign(('AWS4' + secret_key).encode('utf-8'), scope[0]) - signed = _sign(signed, scope[1]) - signed = _sign(signed, scope[2]) - signed = _sign(signed, b'aws4_request') - - signature = hmac.new(signed, string_to_sign, hashlib.sha256) - return signature.hexdigest() diff --git a/keystone-moon/keystone/contrib/simple_cert/__init__.py b/keystone-moon/keystone/contrib/simple_cert/__init__.py deleted file mode 100644 index 2e5f9928..00000000 --- a/keystone-moon/keystone/contrib/simple_cert/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.contrib.simple_cert.routers import SimpleCertExtension # noqa diff --git a/keystone-moon/keystone/contrib/simple_cert/controllers.py b/keystone-moon/keystone/contrib/simple_cert/controllers.py deleted file mode 100644 index d34c03a6..00000000 --- a/keystone-moon/keystone/contrib/simple_cert/controllers.py +++ /dev/null @@ -1,42 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg -import webob - -from keystone.common import controller -from keystone.common import dependency -from keystone import exception - -CONF = cfg.CONF - - -@dependency.requires('token_provider_api') -class SimpleCert(controller.V3Controller): - - def _get_certificate(self, name): - try: - with open(name, 'r') as f: - body = f.read() - except IOError: - raise exception.CertificateFilesUnavailable() - - # NOTE(jamielennox): We construct the webob Response ourselves here so - # that we don't pass through the JSON encoding process. - headers = [('Content-Type', 'application/x-pem-file')] - return webob.Response(body=body, headerlist=headers, status="200 OK") - - def get_ca_certificate(self, context): - return self._get_certificate(CONF.signing.ca_certs) - - def list_certificates(self, context): - return self._get_certificate(CONF.signing.certfile) diff --git a/keystone-moon/keystone/contrib/simple_cert/core.py b/keystone-moon/keystone/contrib/simple_cert/core.py deleted file mode 100644 index 531c6aae..00000000 --- a/keystone-moon/keystone/contrib/simple_cert/core.py +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.common import extension - -EXTENSION_DATA = { - 'name': 'OpenStack Simple Certificate API', - 'namespace': 'http://docs.openstack.org/identity/api/ext/' - 'OS-SIMPLE-CERT/v1.0', - 'alias': 'OS-SIMPLE-CERT', - 'updated': '2014-01-20T12:00:0-00:00', - 'description': 'OpenStack simple certificate retrieval extension', - 'links': [ - { - 'rel': 'describedby', - # TODO(dolph): link needs to be revised after - # bug 928059 merges - 'type': 'text/html', - 'href': 'https://github.com/openstack/identity-api', - } - ]} -extension.register_admin_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) -extension.register_public_extension(EXTENSION_DATA['alias'], EXTENSION_DATA) diff --git a/keystone-moon/keystone/contrib/simple_cert/routers.py b/keystone-moon/keystone/contrib/simple_cert/routers.py deleted file mode 100644 index b1d509e7..00000000 --- a/keystone-moon/keystone/contrib/simple_cert/routers.py +++ /dev/null @@ -1,33 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class SimpleCertExtension(wsgi.Middleware): - - def __init__(self, application): - super(SimpleCertExtension, self).__init__(application) - msg = _("Remove simple_cert from the paste pipeline, the " - "PKI and PKIz token providers are now deprecated and " - "simple_cert was only used insupport of these token " - "providers. Update the [pipeline:api_v3] section in " - "keystone-paste.ini accordingly, as it will be removed in the " - "O release.") - versionutils.report_deprecated_feature(LOG, msg) diff --git a/keystone-moon/keystone/contrib/user_crud/__init__.py b/keystone-moon/keystone/contrib/user_crud/__init__.py deleted file mode 100644 index 271ceee6..00000000 --- a/keystone-moon/keystone/contrib/user_crud/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2012 Red Hat, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from keystone.contrib.user_crud.core import * # noqa diff --git a/keystone-moon/keystone/contrib/user_crud/core.py b/keystone-moon/keystone/contrib/user_crud/core.py deleted file mode 100644 index b37157ea..00000000 --- a/keystone-moon/keystone/contrib/user_crud/core.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2012 Red Hat, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log -from oslo_log import versionutils - -from keystone.common import wsgi -from keystone.i18n import _ - - -LOG = log.getLogger(__name__) - - -class CrudExtension(wsgi.Middleware): - def __init__(self, application): - super(CrudExtension, self).__init__(application) - msg = _("Remove user_crud_extension from the paste pipeline, the " - "user_crud extension is now always available. Update" - "the [pipeline:public_api] section in keystone-paste.ini " - "accordingly, as it will be removed in the O release.") - versionutils.report_deprecated_feature(LOG, msg) |