summaryrefslogtreecommitdiffstats
path: root/keystone/policy
diff options
context:
space:
mode:
authorDolph Mathews <dolph.mathews@gmail.com>2012-08-29 02:57:38 -0500
committerDolph Mathews <dolph.mathews@gmail.com>2012-11-19 14:50:26 -0600
commit827fc4c731189352a58390b464ea4efb5141461b (patch)
tree1d04e355ca7091c4a98d8c704c860dc17a68ab7c /keystone/policy
parent71692f7805b62329f7367a120700b6ed050b20b4 (diff)
downloadkeystone-827fc4c731189352a58390b464ea4efb5141461b.tar.gz
keystone-827fc4c731189352a58390b464ea4efb5141461b.tar.xz
keystone-827fc4c731189352a58390b464ea4efb5141461b.zip
v3 Policies
- v3 policy (bp rbac-keystone-api) - v3 policy tests (bug 1023935) - v3 policy implementation (bug 1023939) Change-Id: I163fbb67726c295fe9ed09b68cd18d2273345d29
Diffstat (limited to 'keystone/policy')
-rw-r--r--keystone/policy/backends/sql.py103
-rw-r--r--keystone/policy/core.py16
2 files changed, 106 insertions, 13 deletions
diff --git a/keystone/policy/backends/sql.py b/keystone/policy/backends/sql.py
new file mode 100644
index 00000000..6c45dade
--- /dev/null
+++ b/keystone/policy/backends/sql.py
@@ -0,0 +1,103 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack LLC
+#
+# 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 sql
+from keystone.common.sql import migration
+from keystone import exception
+from keystone.policy.backends import rules
+
+
+def handle_conflicts(type='object'):
+ """Converts IntegrityError into HTTP 409 Conflict."""
+ def decorator(method):
+ @functools.wraps(method)
+ def wrapper(*args, **kwargs):
+ try:
+ return method(*args, **kwargs)
+ except sql.IntegrityError as e:
+ raise exception.Conflict(type=type, details=str(e))
+ return wrapper
+ return decorator
+
+
+class PolicyModel(sql.ModelBase, sql.DictBase):
+ __tablename__ = 'policy'
+ attributes = ['id', 'blob', 'type']
+ id = sql.Column(sql.String(64), primary_key=True)
+ blob = sql.Column(sql.JsonBlob(), nullable=False)
+ type = sql.Column(sql.String(255), nullable=False)
+ extra = sql.Column(sql.JsonBlob())
+
+
+class Policy(sql.Base, rules.Policy):
+ # Internal interface to manage the database
+ def db_sync(self):
+ migration.db_sync()
+
+ @handle_conflicts(type='policy')
+ def create_policy(self, policy_id, policy):
+ session = self.get_session()
+
+ with session.begin():
+ ref = PolicyModel.from_dict(policy)
+ session.add(ref)
+ session.flush()
+
+ return ref.to_dict()
+
+ def list_policies(self):
+ session = self.get_session()
+
+ refs = session.query(PolicyModel).all()
+ return [ref.to_dict() for ref in refs]
+
+ def _get_policy(self, session, policy_id):
+ """Private method to get a policy model object (NOT a dictionary)."""
+ try:
+ return session.query(PolicyModel).filter_by(id=policy_id).one()
+ except sql.NotFound:
+ raise exception.PolicyNotFound(policy_id=policy_id)
+
+ def get_policy(self, policy_id):
+ session = self.get_session()
+
+ return self._get_policy(session, policy_id).to_dict()
+
+ @handle_conflicts(type='policy')
+ def update_policy(self, policy_id, policy):
+ session = self.get_session()
+
+ with session.begin():
+ ref = self._get_policy(session, policy_id)
+ old_dict = ref.to_dict()
+ old_dict.update(policy)
+ new_policy = PolicyModel.from_dict(old_dict)
+ ref.blob = new_policy.blob
+ ref.type = new_policy.type
+ ref.extra = new_policy.extra
+ session.flush()
+
+ return ref.to_dict()
+
+ def delete_policy(self, policy_id):
+ session = self.get_session()
+
+ with session.begin():
+ ref = self._get_policy(session, policy_id)
+ session.delete(ref)
+ session.flush()
diff --git a/keystone/policy/core.py b/keystone/policy/core.py
index 498e027b..36b982c8 100644
--- a/keystone/policy/core.py
+++ b/keystone/policy/core.py
@@ -68,10 +68,9 @@ class Driver(object):
raise exception.NotImplemented()
def create_policy(self, policy_id, policy):
- """Store a policy blob for a particular endpoint.
+ """Store a policy blob.
- :raises: keystone.exception.EndpointNotFound,
- keystone.exception.Conflict
+ :raises: keystone.exception.Conflict
"""
raise exception.NotImplemented()
@@ -91,8 +90,7 @@ class Driver(object):
def update_policy(self, policy_id, policy):
"""Update a policy blob.
- :raises: keystone.exception.PolicyNotFound,
- keystone.exception.EndpointNotFound
+ :raises: keystone.exception.PolicyNotFound
"""
raise exception.NotImplemented()
@@ -113,9 +111,6 @@ class PolicyControllerV3(controller.V3Controller):
ref = self._assign_unique_id(self._normalize_dict(policy))
self._require_attribute(ref, 'blob')
self._require_attribute(ref, 'type')
- self._require_attribute(ref, 'endpoint_id')
-
- self.catalog_api.get_endpoint(context, ref['endpoint_id'])
ref = self.policy_api.create_policy(context, ref['id'], ref)
return {'policy': ref}
@@ -123,7 +118,6 @@ class PolicyControllerV3(controller.V3Controller):
def list_policies(self, context):
self.assert_admin(context)
refs = self.policy_api.list_policies(context)
- refs = self._filter_by_attribute(context, refs, 'endpoint_id')
refs = self._filter_by_attribute(context, refs, 'type')
return {'policies': self._paginate(context, refs)}
@@ -134,10 +128,6 @@ class PolicyControllerV3(controller.V3Controller):
def update_policy(self, context, policy_id, policy):
self.assert_admin(context)
-
- if 'endpoint_id' in policy:
- self.catalog_api.get_endpoint(context, policy['endpoint_id'])
-
ref = self.policy_api.update_policy(context, policy_id, policy)
return {'policy': ref}