diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-02-21 01:18:46 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-02-21 01:18:46 +0000 |
| commit | 4b4781bd5909abdc993b0edff22da407571212f9 (patch) | |
| tree | 5e9ce75e38d195bcee7ab30085baac8d9c2a8809 | |
| parent | f080f1146f22b305ac720be3afc3eb9f94da4b14 (diff) | |
| parent | 6915ba0d7f737445b634fc5db67a8c7345d8b6d7 (diff) | |
| download | nova-4b4781bd5909abdc993b0edff22da407571212f9.tar.gz nova-4b4781bd5909abdc993b0edff22da407571212f9.tar.xz nova-4b4781bd5909abdc993b0edff22da407571212f9.zip | |
Merge "Move some context checking code from sqlalchemy"
| -rw-r--r-- | nova/api/openstack/compute/contrib/quota_classes.py | 3 | ||||
| -rw-r--r-- | nova/api/openstack/compute/contrib/quotas.py | 4 | ||||
| -rw-r--r-- | nova/context.py | 53 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 89 | ||||
| -rw-r--r-- | nova/virt/baremetal/db/sqlalchemy/api.py | 3 |
5 files changed, 84 insertions, 68 deletions
diff --git a/nova/api/openstack/compute/contrib/quota_classes.py b/nova/api/openstack/compute/contrib/quota_classes.py index f3f5b9b08..7b94e45b1 100644 --- a/nova/api/openstack/compute/contrib/quota_classes.py +++ b/nova/api/openstack/compute/contrib/quota_classes.py @@ -18,6 +18,7 @@ import webob from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil +import nova.context from nova import db from nova import exception from nova import quota @@ -59,7 +60,7 @@ class QuotaClassSetsController(object): context = req.environ['nova.context'] authorize(context) try: - db.sqlalchemy.api.authorize_quota_class_context(context, id) + nova.context.authorize_quota_class_context(context, id) return self._format_quota_set(id, QUOTAS.get_class_quotas(context, id)) except exception.NotAuthorized: diff --git a/nova/api/openstack/compute/contrib/quotas.py b/nova/api/openstack/compute/contrib/quotas.py index 728c3fad6..b1a461431 100644 --- a/nova/api/openstack/compute/contrib/quotas.py +++ b/nova/api/openstack/compute/contrib/quotas.py @@ -20,8 +20,8 @@ import webob from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil +import nova.context from nova import db -from nova.db.sqlalchemy import api as sqlalchemy_api from nova import exception from nova.openstack.common import log as logging from nova import quota @@ -78,7 +78,7 @@ class QuotaSetsController(object): context = req.environ['nova.context'] authorize_show(context) try: - sqlalchemy_api.authorize_project_context(context, id) + nova.context.authorize_project_context(context, id) return self._format_quota_set(id, self._get_quotas(context, id)) except exception.NotAuthorized: raise webob.exc.HTTPForbidden() diff --git a/nova/context.py b/nova/context.py index 60fd5b4c0..831a91b11 100644 --- a/nova/context.py +++ b/nova/context.py @@ -22,6 +22,7 @@ import copy import uuid +from nova import exception from nova.openstack.common import local from nova.openstack.common import log as logging from nova.openstack.common import timeutils @@ -166,3 +167,55 @@ def get_admin_context(read_deleted="no"): is_admin=True, read_deleted=read_deleted, overwrite=False) + + +def is_user_context(context): + """Indicates if the request context is a normal user.""" + if not context: + return False + if context.is_admin: + return False + if not context.user_id or not context.project_id: + return False + return True + + +def require_admin_context(ctxt): + """Raise exception.AdminRequired() if context is an admin context.""" + if not ctxt.is_admin: + raise exception.AdminRequired() + + +def require_context(ctxt): + """Raise exception.NotAuthorized() if context is not a user or an + admin context. + """ + if not ctxt.is_admin and not is_user_context(ctxt): + raise exception.NotAuthorized() + + +def authorize_project_context(context, project_id): + """Ensures a request has permission to access the given project.""" + if is_user_context(context): + if not context.project_id: + raise exception.NotAuthorized() + elif context.project_id != project_id: + raise exception.NotAuthorized() + + +def authorize_user_context(context, user_id): + """Ensures a request has permission to access the given user.""" + if is_user_context(context): + if not context.user_id: + raise exception.NotAuthorized() + elif context.user_id != user_id: + raise exception.NotAuthorized() + + +def authorize_quota_class_context(context, class_name): + """Ensures a request has permission to access the given quota class.""" + if is_user_context(context): + if not context.quota_class: + raise exception.NotAuthorized() + elif context.quota_class != class_name: + raise exception.NotAuthorized() diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index b83b8e839..4de0caf15 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -45,6 +45,7 @@ from sqlalchemy import String from nova import block_device from nova.compute import task_states from nova.compute import vm_states +import nova.context from nova import db from nova.db.sqlalchemy import models from nova import exception @@ -74,44 +75,6 @@ get_engine = db_session.get_engine get_session = db_session.get_session -def is_user_context(context): - """Indicates if the request context is a normal user.""" - if not context: - return False - if context.is_admin: - return False - if not context.user_id or not context.project_id: - return False - return True - - -def authorize_project_context(context, project_id): - """Ensures a request has permission to access the given project.""" - if is_user_context(context): - if not context.project_id: - raise exception.NotAuthorized() - elif context.project_id != project_id: - raise exception.NotAuthorized() - - -def authorize_user_context(context, user_id): - """Ensures a request has permission to access the given user.""" - if is_user_context(context): - if not context.user_id: - raise exception.NotAuthorized() - elif context.user_id != user_id: - raise exception.NotAuthorized() - - -def authorize_quota_class_context(context, class_name): - """Ensures a request has permission to access the given quota class.""" - if is_user_context(context): - if not context.quota_class: - raise exception.NotAuthorized() - elif context.quota_class != class_name: - raise exception.NotAuthorized() - - def require_admin_context(f): """Decorator to require admin request context. @@ -120,9 +83,7 @@ def require_admin_context(f): """ def wrapper(*args, **kwargs): - context = args[0] - if not context.is_admin: - raise exception.AdminRequired() + nova.context.require_admin_context(args[0]) return f(*args, **kwargs) return wrapper @@ -131,17 +92,15 @@ def require_context(f): """Decorator to require *any* user or admin context. This does no authorization for user or project access matching, see - :py:func:`authorize_project_context` and - :py:func:`authorize_user_context`. + :py:func:`nova.context.authorize_project_context` and + :py:func:`nova.context.authorize_user_context`. The first argument to the wrapped function must be the context. """ def wrapper(*args, **kwargs): - context = args[0] - if not context.is_admin and not is_user_context(context): - raise exception.NotAuthorized() + nova.context.require_context(args[0]) return f(*args, **kwargs) return wrapper @@ -215,7 +174,7 @@ def model_query(context, model, *args, **kwargs): raise Exception(_("Unrecognized read_deleted value '%s'") % read_deleted) - if is_user_context(context) and project_only: + if nova.context.is_user_context(context) and project_only: if project_only == 'allow_none': query = query.\ filter(or_(base_model.project_id == context.project_id, @@ -658,7 +617,7 @@ def floating_ip_get_pools(context): @require_context def floating_ip_allocate_address(context, project_id, pool): - authorize_project_context(context, project_id) + nova.context.authorize_project_context(context, project_id) session = get_session() with session.begin(): floating_ip_ref = model_query(context, models.FloatingIp, @@ -749,7 +708,7 @@ def floating_ip_create(context, values, session=None): @require_context def floating_ip_count_by_project(context, project_id, session=None): - authorize_project_context(context, project_id) + nova.context.authorize_project_context(context, project_id) # TODO(tr3buchet): why leave auto_assigned floating IPs out? return model_query(context, models.FloatingIp, read_deleted="no", session=session).\ @@ -848,7 +807,7 @@ def floating_ip_get_all_by_host(context, host): @require_context def floating_ip_get_all_by_project(context, project_id): - authorize_project_context(context, project_id) + nova.context.authorize_project_context(context, project_id) # TODO(tr3buchet): why do we not want auto_assigned floating IPs here? return _floating_ip_get_all(context).\ filter_by(project_id=project_id).\ @@ -879,8 +838,8 @@ def _floating_ip_get_by_address(context, address, session=None): # If the floating IP has a project ID set, check to make sure # the non-admin user has access. - if result.project_id and is_user_context(context): - authorize_project_context(context, result.project_id) + if result.project_id and nova.context.is_user_context(context): + nova.context.authorize_project_context(context, result.project_id) return result @@ -1128,10 +1087,11 @@ def fixed_ip_get(context, id, get_network=False): # FIXME(sirp): shouldn't we just use project_only here to restrict the # results? - if is_user_context(context) and result['instance_uuid'] is not None: + if (nova.context.is_user_context(context) and + result['instance_uuid'] is not None): instance = instance_get_by_uuid(context.elevated(read_deleted='yes'), result['instance_uuid']) - authorize_project_context(context, instance.project_id) + nova.context.authorize_project_context(context, instance.project_id) return result @@ -1157,11 +1117,12 @@ def fixed_ip_get_by_address(context, address, session=None): # NOTE(sirp): shouldn't we just use project_only here to restrict the # results? - if is_user_context(context) and result['instance_uuid'] is not None: + if (nova.context.is_user_context(context) and + result['instance_uuid'] is not None): instance = _instance_get_by_uuid(context.elevated(read_deleted='yes'), result['instance_uuid'], session) - authorize_project_context(context, instance.project_id) + nova.context.authorize_project_context(context, instance.project_id) return result @@ -1966,7 +1927,7 @@ def key_pair_create(context, values): @require_context def key_pair_destroy(context, user_id, name): - authorize_user_context(context, user_id) + nova.context.authorize_user_context(context, user_id) model_query(context, models.KeyPair).\ filter_by(user_id=user_id).\ filter_by(name=name).\ @@ -1975,7 +1936,7 @@ def key_pair_destroy(context, user_id, name): @require_context def key_pair_get(context, user_id, name): - authorize_user_context(context, user_id) + nova.context.authorize_user_context(context, user_id) result = model_query(context, models.KeyPair).\ filter_by(user_id=user_id).\ filter_by(name=name).\ @@ -1989,14 +1950,14 @@ def key_pair_get(context, user_id, name): @require_context def key_pair_get_all_by_user(context, user_id): - authorize_user_context(context, user_id) + nova.context.authorize_user_context(context, user_id) return model_query(context, models.KeyPair, read_deleted="no").\ filter_by(user_id=user_id).\ all() def key_pair_count_by_user(context, user_id): - authorize_user_context(context, user_id) + nova.context.authorize_user_context(context, user_id) return model_query(context, models.KeyPair, read_deleted="no").\ filter_by(user_id=user_id).\ count() @@ -2365,7 +2326,7 @@ def quota_get(context, project_id, resource): @require_context def quota_get_all_by_project(context, project_id): - authorize_project_context(context, project_id) + nova.context.authorize_project_context(context, project_id) rows = model_query(context, models.Quota, read_deleted="no").\ filter_by(project_id=project_id).\ @@ -2417,7 +2378,7 @@ def quota_class_get(context, class_name, resource): @require_context def quota_class_get_all_by_name(context, class_name): - authorize_quota_class_context(context, class_name) + nova.context.authorize_quota_class_context(context, class_name) rows = model_query(context, models.QuotaClass, read_deleted="no").\ filter_by(class_name=class_name).\ @@ -2469,7 +2430,7 @@ def quota_usage_get(context, project_id, resource): @require_context def quota_usage_get_all_by_project(context, project_id): - authorize_project_context(context, project_id) + nova.context.authorize_project_context(context, project_id) rows = model_query(context, models.QuotaUsage, read_deleted="no").\ filter_by(project_id=project_id).\ @@ -3168,7 +3129,7 @@ def security_group_destroy(context, security_group_id): @require_context def security_group_count_by_project(context, project_id, session=None): - authorize_project_context(context, project_id) + nova.context.authorize_project_context(context, project_id) return model_query(context, models.SecurityGroup, read_deleted="no", session=session).\ filter_by(project_id=project_id).\ diff --git a/nova/virt/baremetal/db/sqlalchemy/api.py b/nova/virt/baremetal/db/sqlalchemy/api.py index e06bcd7d2..bbfc17a35 100644 --- a/nova/virt/baremetal/db/sqlalchemy/api.py +++ b/nova/virt/baremetal/db/sqlalchemy/api.py @@ -25,6 +25,7 @@ import uuid from sqlalchemy.sql.expression import asc from sqlalchemy.sql.expression import literal_column +import nova.context from nova.db.sqlalchemy import api as sqlalchemy_api from nova import exception from nova.openstack.common import log as logging @@ -61,7 +62,7 @@ def model_query(context, *args, **kwargs): raise Exception( _("Unrecognized read_deleted value '%s'") % read_deleted) - if project_only and sqlalchemy_api.is_user_context(context): + if project_only and nova.context.is_user_context(context): query = query.filter_by(project_id=context.project_id) return query |
