summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wolf <throughnothing@gmail.com>2011-08-16 15:11:32 -0400
committerWilliam Wolf <throughnothing@gmail.com>2011-08-16 15:11:32 -0400
commitf4d608549f0a539e48276be163593ced558a136f (patch)
tree46432e832365a4d72e6b71cd330f6ddf7f321ed8
parentd3becc6a0c99fb73637e7fdb89540fd8c4b48be2 (diff)
make project_id authorization work properly, with test
-rw-r--r--nova/api/openstack/auth.py23
-rw-r--r--nova/tests/integrated/api/client.py15
-rw-r--r--nova/tests/integrated/test_login.py6
3 files changed, 37 insertions, 7 deletions
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index c9c740a1d..8f1319cca 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -55,23 +55,36 @@ class AuthMiddleware(wsgi.Middleware):
LOG.warn(msg % locals())
return faults.Fault(webob.exc.HTTPUnauthorized())
+ # Get all valid projects for the user
+ projects = self.auth.get_projects(user_id)
+ if not projects:
+ return faults.Fault(webob.exc.HTTPUnauthorized())
+
project_id = ""
path_parts = req.path.split('/')
# TODO(wwolf): this v1.1 check will be temporary as
# keystone should be taking this over at some point
if len(path_parts) > 1 and path_parts[1] == 'v1.1':
project_id = path_parts[2]
+ # Check that the project for project_id exists, and that user
+ # is authorized to use it
+ try:
+ project = self.auth.get_project(project_id)
+ except exception.ProjectNotFound:
+ project = None
+ if project:
+ user = self.auth.get_user(user_id)
+ if not project.has_member(user):
+ return faults.Fault(webob.exc.HTTPUnauthorized())
+ else:
+ return faults.Fault(webob.exc.HTTPUnauthorized())
elif len(path_parts) > 1 and path_parts[1] == 'v1.0':
try:
project_id = req.headers["X-Auth-Project-Id"]
except KeyError:
# FIXME(usrleon): It needed only for compatibility
# while osapi clients don't use this header
- projects = self.auth.get_projects(user_id)
- if projects:
- project_id = projects[0].id
- else:
- return faults.Fault(webob.exc.HTTPUnauthorized())
+ project_id = projects[0].id
is_admin = self.auth.is_admin(user_id)
req.environ['nova.context'] = context.RequestContext(user_id,
diff --git a/nova/tests/integrated/api/client.py b/nova/tests/integrated/api/client.py
index da78995cd..fabf49817 100644
--- a/nova/tests/integrated/api/client.py
+++ b/nova/tests/integrated/api/client.py
@@ -48,6 +48,14 @@ class OpenStackApiAuthenticationException(OpenStackApiException):
response)
+class OpenStackApiAuthorizationException(OpenStackApiException):
+ def __init__(self, response=None, message=None):
+ if not message:
+ message = _("Authorization error")
+ super(OpenStackApiAuthorizationException, self).__init__(message,
+ response)
+
+
class OpenStackApiNotFoundException(OpenStackApiException):
def __init__(self, response=None, message=None):
if not message:
@@ -69,6 +77,8 @@ class TestOpenStackClient(object):
self.auth_user = auth_user
self.auth_key = auth_key
self.auth_uri = auth_uri
+ # default project_id
+ self.project_id = 'openstack'
def request(self, url, method='GET', body=None, headers=None):
_headers = {'Content-Type': 'application/json'}
@@ -128,8 +138,7 @@ class TestOpenStackClient(object):
# NOTE(justinsb): httplib 'helpfully' converts headers to lower case
base_uri = auth_result['x-server-management-url']
- # /openstack is the project_id
- full_uri = base_uri + '/openstack' + relative_uri
+ full_uri = '%s/%s%s' % (base_uri, self.project_id, relative_uri)
headers = kwargs.setdefault('headers', {})
headers['X-Auth-Token'] = auth_result['x-auth-token']
@@ -143,6 +152,8 @@ class TestOpenStackClient(object):
if not http_status in check_response_status:
if http_status == 404:
raise OpenStackApiNotFoundException(response=response)
+ elif http_status == 401:
+ raise OpenStackApiAuthorizationException(response=response)
else:
raise OpenStackApiException(
message=_("Unexpected status code"),
diff --git a/nova/tests/integrated/test_login.py b/nova/tests/integrated/test_login.py
index 06359a52f..9d1925bc0 100644
--- a/nova/tests/integrated/test_login.py
+++ b/nova/tests/integrated/test_login.py
@@ -59,6 +59,12 @@ class LoginTest(integrated_helpers._IntegratedTestBase):
self.assertRaises(client.OpenStackApiAuthenticationException,
bad_credentials_api.get_flavors)
+ def test_good_login_bad_project(self):
+ """Test that I get a 401 with valid user/pass but bad project"""
+ self.api.project_id = 'openstackBAD'
+
+ self.assertRaises(client.OpenStackApiAuthorizationException,
+ self.api.get_flavors)
if __name__ == "__main__":
unittest.main()