Merge "Rework service broker authorization process"

This commit is contained in:
Jenkins
2015-11-13 12:22:14 +00:00
committed by Gerrit Code Review
4 changed files with 17 additions and 90 deletions

View File

@@ -1,5 +1,5 @@
[pipeline:cloudfoundry]
pipeline = cloudfoundryapi
pipeline = request_id ssl ext_context authtoken context cloudfoundryapi
[pipeline:murano]
pipeline = request_id ssl versionnegotiation faultwrap authtoken context rootapp

View File

@@ -1,28 +0,0 @@
# Copyright (c) 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. 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 keystoneclient.v3 import client
from oslo_config import cfg
CONF = cfg.CONF
def authenticate(user, password, tenant=None):
project_name = tenant or CONF.cfapi.tenant
keystone = client.Client(username=user,
password=password,
project_name=project_name,
auth_url=CONF.cfapi.auth_url.replace(
'v2.0', 'v3'))
return keystone

View File

@@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import base64
import json
import uuid
@@ -20,13 +19,10 @@ import muranoclient.client as client
from oslo_config import cfg
from oslo_log import log as logging
import six
from webob import exc
from webob import response
from murano.api.v1.cloudfoundry import auth as keystone_auth
from murano.common.i18n import _LI
from murano.common import wsgi
from murano import context
from murano.db.catalog import api as db_api
from murano.db.services import cf_connections as db_cf
@@ -64,21 +60,6 @@ class Controller(object):
srv['plans'] = [plan]
return srv
def _check_auth(self, req, tenant=None):
auth = req.headers.get('Authorization', None)
if auth is None:
raise exc.HTTPUnauthorized(explanation='Bad credentials')
auth_info = auth.split(' ')[1]
auth_decoded = base64.b64decode(auth_info)
user = auth_decoded.split(':')[0]
password = auth_decoded.split(':')[1]
if tenant:
keystone = keystone_auth.authenticate(user, password, tenant)
else:
keystone = keystone_auth.authenticate(user, password)
return (user, password, keystone)
def _make_service(self, name, package, plan_id):
id = uuid.uuid4().hex
@@ -94,13 +75,9 @@ class Controller(object):
return None
def list(self, req):
user, _, keystone = self._check_auth(req)
# Once we get here we were authorized by keystone
token = keystone.auth_token
ctx = context.RequestContext(user=user, tenant='', auth_token=token)
packages = db_api.package_search({'type': 'application'}, ctx,
packages = db_api.package_search({'type': 'application'},
req.context,
catalog=True)
services = []
for package in packages:
@@ -135,19 +112,13 @@ class Controller(object):
try:
tenant = db_cf.get_tenant_for_org(org_guid)
except AttributeError:
# FIXME(Kezar): need to find better way to get tenant
tenant = CONF.cfapi.tenant
tenant = req.headers['X-Project-Id']
db_cf.set_tenant_for_org(org_guid, tenant)
LOG.info(_LI("Cloud Foundry {org_id} mapped to tenant "
"{tenant_name}").format(org_id=org_guid,
tenant_name=tenant))
# Now as we have all parameters we can try to auth user in actual
# tenant
user, _, keystone = self._check_auth(req, tenant)
# Once we get here we were authorized by keystone
token = keystone.auth_token
token = req.headers['X-Auth-Token']
m_cli = muranoclient(token)
try:
environment_id = db_cf.get_environment_for_space(space_guid)
@@ -160,11 +131,7 @@ class Controller(object):
.format(space_id=space_guid,
environment_id=environment_id))
LOG.debug('Keystone endpoint: {0}'.format(keystone.auth_ref))
tenant_id = keystone.project_id
ctx = context.RequestContext(user=user, tenant=tenant_id)
package = db_api.package_get(service_id, ctx)
package = db_api.package_get(service_id, req.context)
LOG.debug('Adding service {name}'.format(name=package.name))
service = self._make_service(space_guid, package, plan_id)
@@ -198,10 +165,7 @@ class Controller(object):
service_id = service.service_id
environment_id = service.environment_id
tenant = service.tenant
_, _, keystone = self._check_auth(req, tenant)
# Once we get here we were authorized by keystone
token = keystone.auth_token
token = req.headers['X-Auth-Token']
m_cli = muranoclient(token)
session_id = create_session(m_cli, environment_id)
@@ -217,10 +181,7 @@ class Controller(object):
service_id = db_service.service_id
environment_id = db_service.environment_id
tenant = db_service.tenant
_, _, keystone = self._check_auth(req, tenant)
# Once we get here we were authorized by keystone
token = keystone.auth_token
token = req.headers['X-Auth-Token']
m_cli = muranoclient(token)
session_id = create_session(m_cli, environment_id)
@@ -250,10 +211,7 @@ class Controller(object):
def get_last_operation(self, req, instance_id):
service = db_cf.get_service_for_instance(instance_id)
env_id = service.environment_id
tenant = service.tenant
_, _, keystone = self._check_auth(req, tenant)
# Once we get here we were authorized by keystone
token = keystone.auth_token
token = req.headers["X-Auth-Token"]
m_cli = muranoclient(token)
# NOTE(starodubcevna): we can track only environment status. it's
@@ -276,6 +234,7 @@ class Controller(object):
def muranoclient(token_id):
# TODO(starodubcevna): I guess it can be done better.
endpoint = "http://{murano_host}:{murano_port}".format(
murano_host=CONF.bind_host, murano_port=CONF.bind_port)
insecure = False

View File

@@ -29,12 +29,12 @@ class TestController(base.MuranoTestCase):
self.request = mock.MagicMock()
self.request.headers = {'Authorization': 'Basic {encoded}'.format(
encoded=base64.b64encode('test:test'))}
encoded=base64.b64encode('test:test')), 'X-Auth-Token': 'foo-bar',
'X-Project-Id': 'bar-baz'}
@mock.patch('murano.common.policy.check_is_admin')
@mock.patch('murano.db.catalog.api.package_search')
@mock.patch('murano.api.v1.cloudfoundry.auth.authenticate')
def test_list(self, mock_auth, mock_db_search, mock_policy):
def test_list(self, mock_db_search, mock_policy):
pkg0 = mock.MagicMock()
pkg0.id = 'xxx'
@@ -64,8 +64,7 @@ class TestController(base.MuranoTestCase):
@mock.patch('murano.db.services.cf_connections.set_instance_for_service')
@mock.patch('murano.db.services.cf_connections.get_environment_for_space')
@mock.patch('murano.db.services.cf_connections.get_tenant_for_org')
@mock.patch('murano.api.v1.cloudfoundry.auth.authenticate')
def test_provision_from_scratch(self, mock_auth, mock_get_tenant,
def test_provision_from_scratch(self, mock_get_tenant,
mock_get_environment, mock_is, mock_client,
mock_package, mock_policy):
@@ -93,8 +92,7 @@ class TestController(base.MuranoTestCase):
@mock.patch('murano.db.services.cf_connections.set_tenant_for_org')
@mock.patch('murano.db.services.cf_connections.get_environment_for_space')
@mock.patch('murano.db.services.cf_connections.get_tenant_for_org')
@mock.patch('murano.api.v1.cloudfoundry.auth.authenticate')
def test_provision_existent(self, mock_auth, mock_get_tenant,
def test_provision_existent(self, mock_get_tenant,
mock_get_environment, mock_set_tenant,
mock_set_environment, mock_is, mock_client,
mock_package, mock_policy):
@@ -116,9 +114,8 @@ class TestController(base.MuranoTestCase):
self.assertIsInstance(resp, response.Response)
@mock.patch('murano.api.v1.cloudfoundry.cfapi.muranoclient')
@mock.patch('murano.api.v1.cloudfoundry.auth.authenticate')
@mock.patch('murano.db.services.cf_connections.get_service_for_instance')
def test_deprovision(self, mock_get_si, mock_auth, mock_client):
def test_deprovision(self, mock_get_si, mock_client):
service = mock.MagicMock()
service.service_id = '111-111'
service.tenant_id = '222-222'
@@ -131,8 +128,7 @@ class TestController(base.MuranoTestCase):
@mock.patch('murano.api.v1.cloudfoundry.cfapi.muranoclient')
@mock.patch('murano.db.services.cf_connections.get_service_for_instance')
@mock.patch('murano.api.v1.cloudfoundry.auth.authenticate')
def test_bind(self, mock_auth, mock_get_si, mock_client):
def test_bind(self, mock_get_si, mock_client):
service = mock.MagicMock()
service.service_id = '111-111'
service.tenant_id = '222-222'