Moved authorized_tenants retrieval to middleware.
Fixes bug 917263. By moving the tenant API call from the context processor to the middleware the API call is no longer made multiple times per request/response cycle. Additionally, there are various PEP8 fixes included, with the addition of one "ignore" flag to the PEP8 runner (related to github issue #34 for pep8.py). Change-Id: I5c755dfe381b1c38dbeeb99eb2b7ed9172d16f86
This commit is contained in:
parent
3cb2c0d919
commit
a77ed5e534
|
@ -37,8 +37,8 @@ def horizon(request):
|
|||
|
||||
Adds three variables to the request context:
|
||||
|
||||
``tenants``
|
||||
A list of the tenants the current uses is authorized to access.
|
||||
``authorized_tenants``
|
||||
A list of tenant objects which the current user has access to.
|
||||
|
||||
``object_store_configured``
|
||||
Boolean. Will be ``True`` if there is a service of type
|
||||
|
@ -49,6 +49,12 @@ def horizon(request):
|
|||
|
||||
Additionally, it sets the names ``True`` and ``False`` in the context
|
||||
to their boolean equivalents for convenience.
|
||||
|
||||
.. warning::
|
||||
|
||||
Don't put API calls in context processors; they will be called once
|
||||
for each template/template fragment which takes context that is used
|
||||
to render the complete output.
|
||||
"""
|
||||
context = {"True": True,
|
||||
"False": False}
|
||||
|
@ -56,19 +62,7 @@ def horizon(request):
|
|||
# Auth/Keystone context
|
||||
context.setdefault('authorized_tenants', [])
|
||||
if request.user.is_authenticated():
|
||||
try:
|
||||
tenants = api.tenant_list_for_token(request,
|
||||
request.user.token,
|
||||
endpoint_type='internalURL')
|
||||
context['authorized_tenants'] = tenants
|
||||
except Exception, e:
|
||||
if hasattr(request.user, 'message_set'):
|
||||
if not hasattr(e, 'message'):
|
||||
e.message = str(e)
|
||||
messages.error(request, _("Unable to retrieve tenant list: %s")
|
||||
% e.message)
|
||||
else:
|
||||
LOG.exception('Could not retrieve tenant list.')
|
||||
context['authorized_tenants'] = request.user.authorized_tenants
|
||||
|
||||
# Object Store/Swift context
|
||||
catalog = getattr(request.user, 'service_catalog', [])
|
||||
|
|
|
@ -52,7 +52,7 @@ class TenantsViewTests(test.BaseAdminViewTests):
|
|||
cores='1')
|
||||
self.quota = FakeQuotaSet(id=self.TEST_TENANT, **self.quota_data)
|
||||
|
||||
self.tenants = [self.tenant,]
|
||||
self.tenants = [self.tenant]
|
||||
|
||||
def test_index(self):
|
||||
self.mox.StubOutWithMock(api, 'tenant_list')
|
||||
|
|
|
@ -96,7 +96,7 @@ class SelectDateWidget(widgets.Widget):
|
|||
self.month_field, value, month_val, choices)
|
||||
choices = [(i, i) for i in range(1, 32)]
|
||||
day_html = self.create_select(name,
|
||||
self.day_field, value, day_val, choices)
|
||||
self.day_field, value, day_val, choices)
|
||||
|
||||
format = formats.get_format('DATE_FORMAT')
|
||||
escaped = False
|
||||
|
|
|
@ -21,13 +21,19 @@
|
|||
Middleware provided and used by Horizon.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from django.contrib import messages
|
||||
from django import shortcuts
|
||||
|
||||
from horizon import api
|
||||
from horizon import exceptions
|
||||
from horizon import users
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class HorizonMiddleware(object):
|
||||
""" The main Horizon middleware class. Required for use of Horizon. """
|
||||
|
||||
|
@ -41,6 +47,19 @@ class HorizonMiddleware(object):
|
|||
"""
|
||||
request.__class__.user = users.LazyUser()
|
||||
request.horizon = {'dashboard': None, 'panel': None}
|
||||
if request.user.is_authenticated() and \
|
||||
request.user.authorized_tenants is None:
|
||||
try:
|
||||
authd = api.tenant_list_for_token(request,
|
||||
request.user.token,
|
||||
endpoint_type='internalURL')
|
||||
except Exception, e:
|
||||
authd = []
|
||||
LOG.exception('Could not retrieve tenant list.')
|
||||
if hasattr(request.user, 'message_set'):
|
||||
messages.error(request,
|
||||
_("Unable to retrieve tenant list."))
|
||||
request.user.authorized_tenants = authd
|
||||
|
||||
def process_exception(self, request, exception):
|
||||
""" Catch NotAuthorized and Http302 and handle them gracefully. """
|
||||
|
|
|
@ -137,10 +137,12 @@ class TestCase(django_test.TestCase):
|
|||
context_processors.horizon = lambda request: self.TEST_CONTEXT
|
||||
|
||||
self._real_get_user_from_request = users.get_user_from_request
|
||||
tenants = self.TEST_CONTEXT['authorized_tenants']
|
||||
self.setActiveUser(token=self.TEST_TOKEN,
|
||||
username=self.TEST_USER,
|
||||
tenant_id=self.TEST_TENANT,
|
||||
service_catalog=self.TEST_SERVICE_CATALOG)
|
||||
service_catalog=self.TEST_SERVICE_CATALOG,
|
||||
authorized_tenants=tenants)
|
||||
self.request = http.HttpRequest()
|
||||
middleware.HorizonMiddleware().process_request(self.request)
|
||||
|
||||
|
@ -152,13 +154,15 @@ class TestCase(django_test.TestCase):
|
|||
self.mox.VerifyAll()
|
||||
|
||||
def setActiveUser(self, id=None, token=None, username=None, tenant_id=None,
|
||||
service_catalog=None, tenant_name=None, roles=None):
|
||||
service_catalog=None, tenant_name=None, roles=None,
|
||||
authorized_tenants=None):
|
||||
users.get_user_from_request = lambda x: \
|
||||
users.User(id=id,
|
||||
token=token,
|
||||
user=username,
|
||||
tenant_id=tenant_id,
|
||||
service_catalog=service_catalog)
|
||||
service_catalog=service_catalog,
|
||||
authorized_tenants=authorized_tenants)
|
||||
|
||||
def override_times(self):
|
||||
now = datetime.datetime.utcnow()
|
||||
|
@ -187,11 +191,13 @@ class BaseViewTests(TestCase):
|
|||
|
||||
class BaseAdminViewTests(BaseViewTests):
|
||||
def setActiveUser(self, id=None, token=None, username=None, tenant_id=None,
|
||||
service_catalog=None, tenant_name=None, roles=None):
|
||||
service_catalog=None, tenant_name=None, roles=None,
|
||||
authorized_tenants=None):
|
||||
users.get_user_from_request = lambda x: \
|
||||
users.User(id=self.TEST_USER_ID,
|
||||
token=self.TEST_TOKEN,
|
||||
user=self.TEST_USER,
|
||||
tenant_id=self.TEST_TENANT,
|
||||
service_catalog=self.TEST_SERVICE_CATALOG,
|
||||
roles=self.TEST_ROLES)
|
||||
roles=self.TEST_ROLES,
|
||||
authorized_tenants=None)
|
||||
|
|
|
@ -174,16 +174,7 @@ class AuthViewTests(test.BaseViewTests):
|
|||
NEW_TENANT_ID = '6'
|
||||
NEW_TENANT_NAME = 'FAKENAME'
|
||||
TOKEN_ID = 1
|
||||
|
||||
self.setActiveUser(self.TEST_USER_ID, self.TEST_TOKEN, self.TEST_USER,
|
||||
self.TEST_TENANT, False, self.TEST_SERVICE_CATALOG)
|
||||
|
||||
form_data = {'method': 'LoginWithTenant',
|
||||
'password': self.PASSWORD,
|
||||
'tenant': NEW_TENANT_ID,
|
||||
'username': self.TEST_USER}
|
||||
|
||||
self.mox.StubOutWithMock(api, 'token_create')
|
||||
tenants = self.TEST_CONTEXT['authorized_tenants']
|
||||
|
||||
aTenant = self.mox.CreateMock(api.Token)
|
||||
aTenant.id = NEW_TENANT_ID
|
||||
|
@ -196,15 +187,27 @@ class AuthViewTests(test.BaseViewTests):
|
|||
aToken.serviceCatalog = {}
|
||||
aToken.tenant = {'id': aTenant.id, 'name': aTenant.name}
|
||||
|
||||
self.setActiveUser(id=self.TEST_USER_ID,
|
||||
token=self.TEST_TOKEN,
|
||||
username=self.TEST_USER,
|
||||
tenant_id=self.TEST_TENANT,
|
||||
service_catalog=self.TEST_SERVICE_CATALOG,
|
||||
authorized_tenants=tenants)
|
||||
|
||||
self.mox.StubOutWithMock(api, 'token_create')
|
||||
self.mox.StubOutWithMock(api, 'tenant_list_for_token')
|
||||
|
||||
api.token_create(IsA(http.HttpRequest), NEW_TENANT_ID, self.TEST_USER,
|
||||
self.PASSWORD).AndReturn(aToken)
|
||||
|
||||
self.mox.StubOutWithMock(api, 'tenant_list_for_token')
|
||||
api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id).\
|
||||
AndReturn([aTenant])
|
||||
api.tenant_list_for_token(IsA(http.HttpRequest), aToken.id) \
|
||||
.AndReturn([aTenant])
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
form_data = {'method': 'LoginWithTenant',
|
||||
'password': self.PASSWORD,
|
||||
'tenant': NEW_TENANT_ID,
|
||||
'username': self.TEST_USER}
|
||||
res = self.client.post(reverse('horizon:auth_switch',
|
||||
args=[NEW_TENANT_ID]), form_data)
|
||||
|
||||
|
|
|
@ -21,9 +21,10 @@
|
|||
from django import http
|
||||
from mox import IsA
|
||||
|
||||
from horizon import context_processors
|
||||
from horizon import test
|
||||
from horizon import api
|
||||
from horizon import context_processors
|
||||
from horizon import middleware
|
||||
from horizon import test
|
||||
|
||||
|
||||
class ContextProcessorTests(test.TestCase):
|
||||
|
@ -38,6 +39,7 @@ class ContextProcessorTests(test.TestCase):
|
|||
|
||||
def test_authorized_tenants(self):
|
||||
tenant_list = self.TEST_CONTEXT['authorized_tenants']
|
||||
self.request.user.authorized_tenants = None # Reset from setUp
|
||||
self.mox.StubOutWithMock(api, 'tenant_list_for_token')
|
||||
api.tenant_list_for_token(IsA(http.HttpRequest),
|
||||
self.TEST_TOKEN,
|
||||
|
@ -45,6 +47,7 @@ class ContextProcessorTests(test.TestCase):
|
|||
.AndReturn(tenant_list)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
middleware.HorizonMiddleware().process_request(self.request)
|
||||
context = context_processors.horizon(self.request)
|
||||
self.assertEqual(len(context['authorized_tenants']), 1)
|
||||
tenant = context['authorized_tenants'].pop()
|
||||
|
|
|
@ -101,7 +101,8 @@ class User(object):
|
|||
privileges. Internally mapped to :meth:`horizon.users.User.is_admin`.
|
||||
"""
|
||||
def __init__(self, id=None, token=None, user=None, tenant_id=None,
|
||||
service_catalog=None, tenant_name=None, roles=None):
|
||||
service_catalog=None, tenant_name=None, roles=None,
|
||||
authorized_tenants=None):
|
||||
self.id = id
|
||||
self.token = token
|
||||
self.username = user
|
||||
|
@ -109,6 +110,7 @@ class User(object):
|
|||
self.tenant_name = tenant_name
|
||||
self.service_catalog = service_catalog
|
||||
self.roles = roles or []
|
||||
self.authorized_tenants = authorized_tenants
|
||||
|
||||
def is_authenticated(self):
|
||||
"""
|
||||
|
|
|
@ -70,9 +70,9 @@ class Login(forms.SelfHandlingForm):
|
|||
data['username'],
|
||||
data['password'])
|
||||
tenants = api.tenant_list_for_token(request, token.id)
|
||||
except Exception, e:
|
||||
except:
|
||||
exceptions.handle(request,
|
||||
message=_('Error authenticating: %s') % e,
|
||||
message=_('Unable to authenticate tenant.'),
|
||||
escalate=True)
|
||||
tenant = None
|
||||
for t in tenants:
|
||||
|
@ -94,7 +94,6 @@ class Login(forms.SelfHandlingForm):
|
|||
except:
|
||||
exceptions.handle(request, escalate=True)
|
||||
|
||||
|
||||
# Unscoped token
|
||||
request.session['unscoped_token'] = token.id
|
||||
request.user.username = data['username']
|
||||
|
|
|
@ -115,7 +115,8 @@ function run_pep8 {
|
|||
echo "Running pep8 ..."
|
||||
rm -f pep8.txt
|
||||
PEP8_EXCLUDE=vcsversion.py
|
||||
PEP8_OPTIONS="--exclude=$PEP8_EXCLUDE --repeat"
|
||||
PEP8_IGNORE=W602
|
||||
PEP8_OPTIONS="--exclude=$PEP8_EXCLUDE --ignore=$PEP8_IGNORE --repeat"
|
||||
${command_wrapper} pep8 $PEP8_OPTIONS $included_dirs | perl -ple 's/: ([WE]\d+)/: [$1]/' > pep8.txt || true
|
||||
PEP8_COUNT=`wc -l pep8.txt | awk '{ print $1 }'`
|
||||
if [ $PEP8_COUNT -ge 1 ]; then
|
||||
|
|
Loading…
Reference in New Issue