From dac602738e17691266673147eaaa780272d67367 Mon Sep 17 00:00:00 2001 From: Brian Waldon Date: Mon, 7 May 2012 14:58:15 -0700 Subject: Remove Deprecated AuthMiddleware * Remove nova.api.openstack.auth:AuthMiddleware * Remove associated tests * Remove 'deprecated' api pipelines * Partially implements bp remove-deprecated-auth Change-Id: Ifcfac573a569f982c2626bbd0bc740d3c908c9fa --- nova/api/openstack/auth.py | 198 ---------------------------- nova/api/openstack/compute/contrib/hosts.py | 2 - 2 files changed, 200 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index 89afb682a..9e9e4d978 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -15,21 +15,15 @@ # License for the specific language governing permissions and limitations # under the License. -import hashlib import os -import time import webob.dec import webob.exc from nova.api.openstack import wsgi -from nova.auth import manager from nova import context -from nova import exception from nova import flags from nova import log as logging -from nova.openstack.common import importutils -from nova import utils from nova import wsgi as base_wsgi LOG = logging.getLogger(__name__) @@ -69,195 +63,3 @@ class NoAuthMiddleware(base_wsgi.Middleware): req.environ['nova.context'] = ctx return self.application - - -class AuthMiddleware(base_wsgi.Middleware): - """Authorize the openstack API request or return an HTTP Forbidden.""" - - def __init__(self, application, db_driver=None): - if not db_driver: - db_driver = FLAGS.db_driver - self.db = importutils.import_module(db_driver) - self.auth = manager.AuthManager() - super(AuthMiddleware, self).__init__(application) - - @webob.dec.wsgify(RequestClass=wsgi.Request) - def __call__(self, req): - if not self.has_authentication(req): - return self.authenticate(req) - user_id = self.get_user_by_authentication(req) - if not user_id: - token = req.headers["X-Auth-Token"] - msg = _("%(user_id)s could not be found with token '%(token)s'") - LOG.warn(msg % locals()) - return wsgi.Fault(webob.exc.HTTPUnauthorized()) - - # Get all valid projects for the user - projects = self.auth.get_projects(user_id) - if not projects: - return wsgi.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] in ('v1.1', 'v2'): - project_id = path_parts[2] - # Check that the project for project_id exists, and that user - # is authorized to use it - try: - self.auth.get_project(project_id) - except exception.ProjectNotFound: - return wsgi.Fault(webob.exc.HTTPUnauthorized()) - if project_id not in [p.id for p in projects]: - return wsgi.Fault(webob.exc.HTTPUnauthorized()) - else: - # As a fallback, set project_id from the headers, which is the v1.0 - # behavior. As a last resort, be forgiving to the user and set - # project_id based on a valid project of theirs. - try: - project_id = req.headers["X-Auth-Project-Id"] - except KeyError: - project_id = projects[0].id - - is_admin = self.auth.is_admin(user_id) - remote_address = getattr(req, 'remote_address', '127.0.0.1') - if FLAGS.use_forwarded_for: - remote_address = req.headers.get('X-Forwarded-For', remote_address) - ctx = context.RequestContext(user_id, - project_id, - is_admin=is_admin, - remote_address=remote_address) - req.environ['nova.context'] = ctx - - if not is_admin and not self.auth.is_project_member(user_id, - project_id): - msg = _("%(user_id)s must be an admin or a " - "member of %(project_id)s") - LOG.warn(msg % locals()) - return wsgi.Fault(webob.exc.HTTPUnauthorized()) - - return self.application - - def has_authentication(self, req): - return 'X-Auth-Token' in req.headers - - def get_user_by_authentication(self, req): - return self.authorize_token(req.headers["X-Auth-Token"]) - - def authenticate(self, req): - # Unless the request is explicitly made against // don't - # honor it - path_info = req.path_info - if len(path_info) > 1: - msg = _("Authentication requests must be made against a version " - "root (e.g. /v2).") - LOG.warn(msg) - return wsgi.Fault(webob.exc.HTTPUnauthorized(explanation=msg)) - - def _get_auth_header(key): - """Ensures that the KeyError returned is meaningful.""" - try: - return req.headers[key] - except KeyError: - raise KeyError(key) - try: - username = _get_auth_header('X-Auth-User') - key = _get_auth_header('X-Auth-Key') - except KeyError as ex: - msg = _("Could not find %s in request.") % ex - LOG.warn(msg) - return wsgi.Fault(webob.exc.HTTPUnauthorized(explanation=msg)) - - token, user = self._authorize_user(username, key, req) - if user and token: - res = webob.Response() - res.headers['X-Auth-Token'] = token['token_hash'] - _x_server_url = 'X-Server-Management-Url' - _server_url = 'server_management_url' - res.headers[_x_server_url] = token[_server_url] - - if token['storage_url']: - _x_storage_url = 'X-Storage-Url' - _storage_url = 'storage_url' - res.headers[_x_storage_url] = token[_storage_url] - - if token['cdn_management_url']: - _x_cdn_url = 'X-CDN-Management-Url' - _cdn_url = 'cdn_management_url' - res.headers[_x_cdn_url] = token[_cdn_url] - - res.content_type = 'text/plain' - res.status = '204' - LOG.debug(_("Successfully authenticated '%s'") % username) - return res - else: - return wsgi.Fault(webob.exc.HTTPUnauthorized()) - - def authorize_token(self, token_hash): - """ retrieves user information from the datastore given a token - - If the token has expired, returns None - If the token is not found, returns None - Otherwise returns dict(id=(the authorized user's id)) - - This method will also remove the token if the timestamp is older than - 2 days ago. - """ - ctxt = context.get_admin_context() - try: - token = self.db.auth_token_get(ctxt, token_hash) - except exception.NotFound: - return None - if token: - delta = utils.utcnow() - token['created_at'] - if delta.days >= 2: - self.db.auth_token_destroy(ctxt, token['token_hash']) - else: - return token['user_id'] - return None - - def _authorize_user(self, username, key, req): - """Generates a new token and assigns it to a user. - - username - string - key - string API key - req - wsgi.Request object - """ - ctxt = context.get_admin_context() - - project_id = req.headers.get('X-Auth-Project-Id') - if project_id is None: - # If the project_id is not provided in the headers, be forgiving to - # the user and set project_id based on a valid project of theirs. - user = self.auth.get_user_from_access_key(key) - projects = self.auth.get_projects(user.id) - if not projects: - raise webob.exc.HTTPUnauthorized() - project_id = projects[0].id - - try: - user = self.auth.get_user_from_access_key(key) - except exception.NotFound: - LOG.warn(_("User not found with provided API key.")) - user = None - - if user and utils.strcmp_const_time(user.name, username): - token_hash = hashlib.sha1('%s%s%f' % (username, key, - time.time())).hexdigest() - token_dict = {} - token_dict['token_hash'] = token_hash - token_dict['cdn_management_url'] = '' - os_url = req.url.strip('/') - os_url += '/' + project_id - token_dict['server_management_url'] = os_url - token_dict['storage_url'] = '' - token_dict['user_id'] = user.id - token = self.db.auth_token_create(ctxt, token_dict) - return token, user - elif user and user.name != username: - msg = _("Provided API key is valid, but not for user " - "'%(username)s'") % locals() - LOG.warn(msg) - - return None, None diff --git a/nova/api/openstack/compute/contrib/hosts.py b/nova/api/openstack/compute/contrib/hosts.py index a93da9e01..b93d3a48c 100644 --- a/nova/api/openstack/compute/contrib/hosts.py +++ b/nova/api/openstack/compute/contrib/hosts.py @@ -224,8 +224,6 @@ class HostController(object): """ host = id context = req.environ['nova.context'] - # Expected to use AuthMiddleware. - # Otherwise, non-admin user can use describe-resource if not context.is_admin: msg = _("Describe-resource is admin only functionality") raise webob.exc.HTTPForbidden(explanation=msg) -- cgit