summaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/v2_crud
diff options
context:
space:
mode:
Diffstat (limited to 'keystone-moon/keystone/v2_crud')
-rw-r--r--keystone-moon/keystone/v2_crud/__init__.py0
-rw-r--r--keystone-moon/keystone/v2_crud/admin_crud.py240
-rw-r--r--keystone-moon/keystone/v2_crud/user_crud.py134
3 files changed, 374 insertions, 0 deletions
diff --git a/keystone-moon/keystone/v2_crud/__init__.py b/keystone-moon/keystone/v2_crud/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/keystone-moon/keystone/v2_crud/__init__.py
diff --git a/keystone-moon/keystone/v2_crud/admin_crud.py b/keystone-moon/keystone/v2_crud/admin_crud.py
new file mode 100644
index 00000000..86ccfcd8
--- /dev/null
+++ b/keystone-moon/keystone/v2_crud/admin_crud.py
@@ -0,0 +1,240 @@
+# 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 import assignment
+from keystone import catalog
+from keystone.common import extension
+from keystone.common import wsgi
+from keystone import identity
+from keystone import resource
+
+
+extension.register_admin_extension(
+ 'OS-KSADM', {
+ 'name': 'OpenStack Keystone Admin',
+ 'namespace': 'http://docs.openstack.org/identity/api/ext/'
+ 'OS-KSADM/v1.0',
+ 'alias': 'OS-KSADM',
+ 'updated': '2013-07-11T17:14:00-00:00',
+ 'description': 'OpenStack extensions to Keystone v2.0 API '
+ 'enabling Administrative Operations.',
+ 'links': [
+ {
+ 'rel': 'describedby',
+ 'type': 'text/html',
+ 'href': 'http://developer.openstack.org/'
+ 'api-ref-identity-v2-ext.html',
+ }
+ ]})
+
+
+class Router(wsgi.ComposableRouter):
+ """Previously known as the OS-KSADM extension.
+
+ Provides a bunch of CRUD operations for internal data types.
+
+ """
+
+ def add_routes(self, mapper):
+ tenant_controller = resource.controllers.Tenant()
+ assignment_tenant_controller = (
+ assignment.controllers.TenantAssignment())
+ user_controller = identity.controllers.User()
+ role_controller = assignment.controllers.Role()
+ assignment_role_controller = assignment.controllers.RoleAssignmentV2()
+ service_controller = catalog.controllers.Service()
+ endpoint_controller = catalog.controllers.Endpoint()
+
+ # Tenant Operations
+ mapper.connect(
+ '/tenants',
+ controller=tenant_controller,
+ action='create_project',
+ conditions=dict(method=['POST']))
+ mapper.connect(
+ '/tenants/{tenant_id}',
+ controller=tenant_controller,
+ action='update_project',
+ conditions=dict(method=['PUT', 'POST']))
+ mapper.connect(
+ '/tenants/{tenant_id}',
+ controller=tenant_controller,
+ action='delete_project',
+ conditions=dict(method=['DELETE']))
+ mapper.connect(
+ '/tenants/{tenant_id}/users',
+ controller=assignment_tenant_controller,
+ action='get_project_users',
+ conditions=dict(method=['GET']))
+
+ # User Operations
+ mapper.connect(
+ '/users',
+ controller=user_controller,
+ action='get_users',
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ '/users',
+ controller=user_controller,
+ action='create_user',
+ conditions=dict(method=['POST']))
+ # NOTE(termie): not in diablo
+ mapper.connect(
+ '/users/{user_id}',
+ controller=user_controller,
+ action='update_user',
+ conditions=dict(method=['PUT']))
+ mapper.connect(
+ '/users/{user_id}',
+ controller=user_controller,
+ action='delete_user',
+ conditions=dict(method=['DELETE']))
+
+ # COMPAT(diablo): the copy with no OS-KSADM is from diablo
+ mapper.connect(
+ '/users/{user_id}/password',
+ controller=user_controller,
+ action='set_user_password',
+ conditions=dict(method=['PUT']))
+ mapper.connect(
+ '/users/{user_id}/OS-KSADM/password',
+ controller=user_controller,
+ action='set_user_password',
+ conditions=dict(method=['PUT']))
+
+ # COMPAT(diablo): the copy with no OS-KSADM is from diablo
+ mapper.connect(
+ '/users/{user_id}/tenant',
+ controller=user_controller,
+ action='update_user',
+ conditions=dict(method=['PUT']))
+ mapper.connect(
+ '/users/{user_id}/OS-KSADM/tenant',
+ controller=user_controller,
+ action='update_user',
+ conditions=dict(method=['PUT']))
+
+ # COMPAT(diablo): the copy with no OS-KSADM is from diablo
+ mapper.connect(
+ '/users/{user_id}/enabled',
+ controller=user_controller,
+ action='set_user_enabled',
+ conditions=dict(method=['PUT']))
+ mapper.connect(
+ '/users/{user_id}/OS-KSADM/enabled',
+ controller=user_controller,
+ action='set_user_enabled',
+ conditions=dict(method=['PUT']))
+
+ # User Roles
+ mapper.connect(
+ '/users/{user_id}/roles/OS-KSADM/{role_id}',
+ controller=assignment_role_controller,
+ action='add_role_to_user',
+ conditions=dict(method=['PUT']))
+ mapper.connect(
+ '/users/{user_id}/roles/OS-KSADM/{role_id}',
+ controller=assignment_role_controller,
+ action='remove_role_from_user',
+ conditions=dict(method=['DELETE']))
+
+ # COMPAT(diablo): User Roles
+ mapper.connect(
+ '/users/{user_id}/roleRefs',
+ controller=assignment_role_controller,
+ action='get_role_refs',
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ '/users/{user_id}/roleRefs',
+ controller=assignment_role_controller,
+ action='create_role_ref',
+ conditions=dict(method=['POST']))
+ mapper.connect(
+ '/users/{user_id}/roleRefs/{role_ref_id}',
+ controller=assignment_role_controller,
+ action='delete_role_ref',
+ conditions=dict(method=['DELETE']))
+
+ # User-Tenant Roles
+ mapper.connect(
+ '/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}',
+ controller=assignment_role_controller,
+ action='add_role_to_user',
+ conditions=dict(method=['PUT']))
+ mapper.connect(
+ '/tenants/{tenant_id}/users/{user_id}/roles/OS-KSADM/{role_id}',
+ controller=assignment_role_controller,
+ action='remove_role_from_user',
+ conditions=dict(method=['DELETE']))
+
+ # Service Operations
+ mapper.connect(
+ '/OS-KSADM/services',
+ controller=service_controller,
+ action='get_services',
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ '/OS-KSADM/services',
+ controller=service_controller,
+ action='create_service',
+ conditions=dict(method=['POST']))
+ mapper.connect(
+ '/OS-KSADM/services/{service_id}',
+ controller=service_controller,
+ action='delete_service',
+ conditions=dict(method=['DELETE']))
+ mapper.connect(
+ '/OS-KSADM/services/{service_id}',
+ controller=service_controller,
+ action='get_service',
+ conditions=dict(method=['GET']))
+
+ # Endpoint Templates
+ mapper.connect(
+ '/endpoints',
+ controller=endpoint_controller,
+ action='get_endpoints',
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ '/endpoints',
+ controller=endpoint_controller,
+ action='create_endpoint',
+ conditions=dict(method=['POST']))
+ mapper.connect(
+ '/endpoints/{endpoint_id}',
+ controller=endpoint_controller,
+ action='delete_endpoint',
+ conditions=dict(method=['DELETE']))
+
+ # Role Operations
+ mapper.connect(
+ '/OS-KSADM/roles',
+ controller=role_controller,
+ action='create_role',
+ conditions=dict(method=['POST']))
+ mapper.connect(
+ '/OS-KSADM/roles',
+ controller=role_controller,
+ action='get_roles',
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ '/OS-KSADM/roles/{role_id}',
+ controller=role_controller,
+ action='get_role',
+ conditions=dict(method=['GET']))
+ mapper.connect(
+ '/OS-KSADM/roles/{role_id}',
+ controller=role_controller,
+ action='delete_role',
+ conditions=dict(method=['DELETE']))
diff --git a/keystone-moon/keystone/v2_crud/user_crud.py b/keystone-moon/keystone/v2_crud/user_crud.py
new file mode 100644
index 00000000..9da7f31f
--- /dev/null
+++ b/keystone-moon/keystone/v2_crud/user_crud.py
@@ -0,0 +1,134 @@
+# 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.
+
+import copy
+import uuid
+
+from oslo_log import log
+
+from keystone.common import dependency
+from keystone.common import extension
+from keystone.common import wsgi
+from keystone import exception
+from keystone import identity
+from keystone.models import token_model
+
+
+LOG = log.getLogger(__name__)
+
+
+extension.register_public_extension(
+ 'OS-KSCRUD', {
+ 'name': 'OpenStack Keystone User CRUD',
+ 'namespace': 'http://docs.openstack.org/identity/api/ext/'
+ 'OS-KSCRUD/v1.0',
+ 'alias': 'OS-KSCRUD',
+ 'updated': '2013-07-07T12:00:0-00:00',
+ 'description': 'OpenStack extensions to Keystone v2.0 API '
+ 'enabling User Operations.',
+ 'links': [
+ {
+ 'rel': 'describedby',
+ 'type': 'text/html',
+ 'href': 'http://developer.openstack.org/'
+ 'api-ref-identity-v2-ext.html',
+ }
+ ]})
+
+
+@dependency.requires('catalog_api', 'identity_api', 'resource_api',
+ 'token_provider_api')
+class UserController(identity.controllers.User):
+ def set_user_password(self, context, user_id, user):
+ token_id = context.get('token_id')
+ original_password = user.get('original_password')
+
+ token_data = self.token_provider_api.validate_token(token_id)
+ token_ref = token_model.KeystoneToken(token_id=token_id,
+ token_data=token_data)
+
+ if token_ref.user_id != user_id:
+ raise exception.Forbidden('Token belongs to another user')
+ if original_password is None:
+ raise exception.ValidationError(target='user',
+ attribute='original password')
+
+ try:
+ user_ref = self.identity_api.authenticate(
+ context,
+ user_id=token_ref.user_id,
+ password=original_password)
+ if not user_ref.get('enabled', True):
+ # NOTE(dolph): why can't you set a disabled user's password?
+ raise exception.Unauthorized('User is disabled')
+ except AssertionError:
+ raise exception.Unauthorized()
+
+ update_dict = {'password': user['password'], 'id': user_id}
+
+ admin_context = copy.copy(context)
+ admin_context['is_admin'] = True
+ super(UserController, self).set_user_password(admin_context,
+ user_id,
+ update_dict)
+
+ # Issue a new token based upon the original token data. This will
+ # always be a V2.0 token.
+
+ # TODO(morganfainberg): Add a mechanism to issue a new token directly
+ # from a token model so that this code can go away. This is likely
+ # not the norm as most cases do not need to yank apart a token to
+ # issue a new one.
+ new_token_ref = {}
+ metadata_ref = {}
+ roles_ref = None
+
+ new_token_ref['user'] = user_ref
+ if token_ref.bind:
+ new_token_ref['bind'] = token_ref.bind
+ if token_ref.project_id:
+ new_token_ref['tenant'] = self.resource_api.get_project(
+ token_ref.project_id)
+ if token_ref.role_names:
+ roles_ref = [dict(name=value)
+ for value in token_ref.role_names]
+ if token_ref.role_ids:
+ metadata_ref['roles'] = token_ref.role_ids
+ if token_ref.trust_id:
+ metadata_ref['trust'] = {
+ 'id': token_ref.trust_id,
+ 'trustee_user_id': token_ref.trustee_user_id}
+ new_token_ref['metadata'] = metadata_ref
+ new_token_ref['id'] = uuid.uuid4().hex
+
+ catalog_ref = self.catalog_api.get_catalog(user_id,
+ token_ref.project_id)
+
+ new_token_id, new_token_data = self.token_provider_api.issue_v2_token(
+ token_ref=new_token_ref, roles_ref=roles_ref,
+ catalog_ref=catalog_ref)
+ LOG.debug('TOKEN_REF %s', new_token_data)
+ return new_token_data
+
+
+class Router(wsgi.ComposableRouter):
+ """Provides a subset of CRUD operations for internal data types."""
+
+ def add_routes(self, mapper):
+ user_controller = UserController()
+
+ mapper.connect('/OS-KSCRUD/users/{user_id}',
+ controller=user_controller,
+ action='set_user_password',
+ conditions=dict(method=['PATCH']))