summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-21 01:18:46 +0000
committerGerrit Code Review <review@openstack.org>2013-02-21 01:18:46 +0000
commit4b4781bd5909abdc993b0edff22da407571212f9 (patch)
tree5e9ce75e38d195bcee7ab30085baac8d9c2a8809
parentf080f1146f22b305ac720be3afc3eb9f94da4b14 (diff)
parent6915ba0d7f737445b634fc5db67a8c7345d8b6d7 (diff)
downloadnova-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.py3
-rw-r--r--nova/api/openstack/compute/contrib/quotas.py4
-rw-r--r--nova/context.py53
-rw-r--r--nova/db/sqlalchemy/api.py89
-rw-r--r--nova/virt/baremetal/db/sqlalchemy/api.py3
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