Working on secure DB access (part 3)

* Moving method get_project_id() to services/security.py

Change-Id: Id4a166a754c1eda24280e7454530339b43243cb3
This commit is contained in:
Renat Akhmerov 2015-01-19 17:27:19 +06:00
parent 14a7b44bb0
commit 9fcbfbe2f9
11 changed files with 31 additions and 72 deletions

View File

@ -23,7 +23,7 @@ from sqlalchemy import event
from sqlalchemy.ext import declarative
from sqlalchemy.orm import attributes
from mistral.db import v2 as db_base
from mistral.services import security
def _generate_unicode_uuid():
@ -90,11 +90,11 @@ class MistralSecureModelBase(MistralModelBase):
__abstract__ = True
scope = sa.Column(sa.String(80), default='private')
project_id = sa.Column(sa.String(80), default=db_base.get_project_id)
project_id = sa.Column(sa.String(80), default=security.get_project_id)
def _set_project_id(target, value, oldvalue, initiator):
return db_base.get_project_id()
return security.get_project_id()
def register_secure_model_hooks():

View File

@ -1,32 +0,0 @@
# Copyright 2014 - Mirantis, 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.config import cfg
from mistral import context as auth_context
# Make sure to import 'auth_enable' option before using it.
cfg.CONF.import_opt('auth_enable', 'mistral.config', group='pecan')
CONF = cfg.CONF
DEFAULT_PROJECT_ID = "<default-project>"
def get_project_id():
if CONF.pecan.auth_enable and auth_context.has_ctx():
return auth_context.ctx().project_id
else:
return DEFAULT_PROJECT_ID

View File

@ -21,11 +21,10 @@ from oslo.db import exception as db_exc
import sqlalchemy as sa
from mistral.db.sqlalchemy import base as b
from mistral.db import v2 as db_base
from mistral.db.v2.sqlalchemy import models
from mistral import exceptions as exc
from mistral.openstack.common import log as logging
from mistral.services import security
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
@ -94,7 +93,7 @@ def _get_collection_sorted_by_name(model, **kwargs):
query = b.model_query(model)
proj = query.filter_by(
project_id=db_base.get_project_id(),
project_id=security.get_project_id(),
**kwargs
)
public = query.filter_by(scope='public', **kwargs)
@ -106,7 +105,7 @@ def _get_collection_sorted_by_time(model, **kwargs):
query = b.model_query(model)
return query.filter_by(
project_id=db_base.get_project_id(),
project_id=security.get_project_id(),
**kwargs
).order_by(model.created_at).all()
@ -114,7 +113,7 @@ def _get_collection_sorted_by_time(model, **kwargs):
def _get_db_object_by_name(model, name):
query = b.model_query(model)
private = query.filter_by(name=name, project_id=db_base.get_project_id())
private = query.filter_by(name=name, project_id=security.get_project_id())
public = query.filter_by(name=name, scope='public')
return private.union(public).first()
@ -123,7 +122,7 @@ def _get_db_object_by_name(model, name):
def _get_db_object_by_id(model, id):
query = b.model_query(model)
return query.filter_by(id=id, project_id=db_base.get_project_id()).first()
return query.filter_by(id=id, project_id=security.get_project_id()).first()
# Workbooks.

View File

@ -16,7 +16,6 @@
import copy
from oslo.config import cfg
from mistral.db import v2 as db_base
from mistral.db.v2 import api as db_api
from mistral.engine1 import base
from mistral.engine1 import commands
@ -194,7 +193,6 @@ class DefaultEngine(base.Engine):
'output': {},
'context': copy.copy(wf_input) or {},
'parent_task_id': params.get('parent_task_id'),
'project_id': db_base.get_project_id()
})
data_flow.add_openstack_data_to_context(wf_db, exec_db.context)

View File

@ -1,4 +1,4 @@
# Copyright 2013 - Mirantis, Inc.
# Copyright 2015 - Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -14,7 +14,6 @@
from mistral.db.v2 import api as db_api
from mistral import exceptions as exc
from mistral.services import security
from mistral.workbook import parser as spec_parser
@ -80,6 +79,4 @@ def _get_action_values(action_spec, definition, scope):
'scope': scope
}
security.add_project_id(values, scope)
return values

View File

@ -16,17 +16,31 @@
from oslo.config import cfg
from mistral import context
from mistral import context as auth_ctx
from mistral.utils.openstack import keystone
CONF = cfg.CONF
# Make sure to import 'auth_enable' option before using it.
# TODO(rakhmerov): Try to find a better solution.
CONF.import_opt('auth_enable', 'mistral.config', group='pecan')
DEFAULT_PROJECT_ID = "<default-project>"
def get_project_id():
if CONF.pecan.auth_enable and auth_ctx.has_ctx():
return auth_ctx.ctx().project_id
else:
return DEFAULT_PROJECT_ID
def create_trust():
client = keystone.client()
ctx = context.ctx()
ctx = auth_ctx.ctx()
trustee_id = keystone.client_for_admin(
CONF.keystone_authtoken.admin_tenant_name).user_id
@ -53,13 +67,13 @@ def create_context(trust_id, project_id):
if CONF.pecan.auth_enable:
client = keystone.client_for_trusts(trust_id)
return context.MistralContext(
return auth_ctx.MistralContext(
user_id=client.user_id,
project_id=project_id,
auth_token=client.auth_token
)
return context.MistralContext(
return auth_ctx.MistralContext(
user_id=None,
project_id=None,
auth_token=None,
@ -75,13 +89,6 @@ def delete_trust(workbook):
keystone_client.trusts.delete(workbook.trust_id)
def add_project_id(secure_object_values, scope='private'):
if cfg.CONF.pecan.auth_enable and scope == 'private':
secure_object_values.update({
'project_id': context.ctx().project_id
})
def add_trust_id(secure_object_values):
if cfg.CONF.pecan.auth_enable:
secure_object_values.update({

View File

@ -17,7 +17,6 @@ import datetime
from mistral.db.v1 import api as db_api_v1
from mistral.db.v2 import api as db_api_v2
from mistral.services import security
from mistral.workbook import parser as spec_parser
@ -100,8 +99,6 @@ def create_cron_trigger(name, pattern, workflow_name, workflow_input,
'scope': 'private'
}
security.add_project_id(values)
trig = db_api_v2.create_cron_trigger(values)
return trig

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Copyright 2013 - Mirantis, Inc.
# Copyright 2015 - Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -22,8 +22,6 @@ from mistral.workbook import parser as spec_parser
def create_workbook_v1(values, scope='private'):
security.add_project_id(values, scope)
return db_api_v1.workbook_create(values)
@ -115,6 +113,4 @@ def _get_workbook_values(wb_spec, definition, scope):
'scope': scope
}
security.add_project_id(values, scope)
return values

View File

@ -70,7 +70,6 @@ def _get_workflow_values(wf_spec, definition, scope):
'scope': scope
}
security.add_project_id(values, scope)
security.add_trust_id(values)
return values

View File

@ -79,8 +79,6 @@ class TestWorkbooksController(base.FunctionalTest):
@mock.patch.object(db_api, "workbook_create",
mock.MagicMock(side_effect=exceptions.DBDuplicateEntry))
@mock.patch("mistral.services.security.add_project_id",
mock.MagicMock(return_value=None))
def test_post_dup(self):
resp = self.app.post_json('/v1/workbooks', WORKBOOKS[0],
expect_errors=True)

View File

@ -21,9 +21,9 @@ import datetime
from oslo.config import cfg
from mistral import context as auth_context
from mistral.db import v2 as db_base
from mistral.db.v2.sqlalchemy import api as db_api
from mistral import exceptions as exc
from mistral.services import security
from mistral.tests import base as test_base
@ -335,8 +335,8 @@ class WorkflowTest(SQLAlchemyTest):
fetched0 = db_api.load_workflow(created0.name)
fetched1 = db_api.load_workflow(created1.name)
self.assertEqual(db_base.get_project_id(), fetched0.project_id)
self.assertEqual(db_base.get_project_id(), fetched1.project_id)
self.assertEqual(security.get_project_id(), fetched0.project_id)
self.assertEqual(security.get_project_id(), fetched1.project_id)
fetched = db_api.get_workflows()