make project_id authorization work properly, with test

This commit is contained in:
William Wolf
2011-08-16 15:11:32 -04:00
parent d3becc6a0c
commit f4d608549f
3 changed files with 37 additions and 7 deletions

View File

@@ -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,

View File

@@ -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"),

View File

@@ -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()