Merge pull request #408 from chrismeyersfsu/7500_process_workflow_cornercase_for_user_capability

memoize workflow license feature check
This commit is contained in:
Chris Meyers
2017-09-14 08:29:41 -04:00
committed by GitHub
4 changed files with 16 additions and 4 deletions

View File

@@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
# Tower # Tower
from awx.main.utils.common import get_licenser from awx.main.utils.common import get_licenser, memoize
__all__ = ['LicenseForbids', 'get_license', 'get_licensed_features', __all__ = ['LicenseForbids', 'get_license', 'get_licensed_features',
'feature_enabled', 'feature_exists'] 'feature_enabled', 'feature_exists']
@@ -40,6 +40,7 @@ def get_licensed_features():
return features return features
@memoize(cache_name='ephemeral')
def feature_enabled(name): def feature_enabled(name):
"""Return True if the requested feature is enabled, False otherwise.""" """Return True if the requested feature is enabled, False otherwise."""
validated_license_data = _get_validated_license_data() validated_license_data = _get_validated_license_data()

View File

@@ -22,7 +22,7 @@ from awx.main.models import * # noqa
from awx.main.models.unified_jobs import ACTIVE_STATES from awx.main.models.unified_jobs import ACTIVE_STATES
from awx.main.models.mixins import ResourceMixin from awx.main.models.mixins import ResourceMixin
from awx.conf.license import LicenseForbids from awx.conf.license import LicenseForbids, feature_enabled
__all__ = ['get_user_queryset', 'check_user_access', 'check_user_access_with_errors', __all__ = ['get_user_queryset', 'check_user_access', 'check_user_access_with_errors',
'user_accessible_objects', 'consumer_access', 'user_accessible_objects', 'consumer_access',
@@ -311,6 +311,10 @@ class BaseAccess(object):
if validation_errors: if validation_errors:
user_capabilities[display_method] = False user_capabilities[display_method] = False
continue continue
elif isinstance(obj, (WorkflowJobTemplate, WorkflowJob)):
if not feature_enabled('workflows'):
user_capabilities[display_method] = (display_method == 'delete')
continue
elif display_method == 'copy' and isinstance(obj, WorkflowJobTemplate) and obj.organization_id is None: elif display_method == 'copy' and isinstance(obj, WorkflowJobTemplate) and obj.organization_id is None:
user_capabilities[display_method] = self.user.is_superuser user_capabilities[display_method] = self.user.is_superuser
continue continue

View File

@@ -107,13 +107,14 @@ class RequireDebugTrueOrTest(logging.Filter):
return settings.DEBUG or 'test' in sys.argv return settings.DEBUG or 'test' in sys.argv
def memoize(ttl=60, cache_key=None): def memoize(ttl=60, cache_key=None, cache_name='default'):
''' '''
Decorator to wrap a function and cache its result. Decorator to wrap a function and cache its result.
''' '''
from django.core.cache import cache from django.core.cache import caches
def _memoizer(f, *args, **kwargs): def _memoizer(f, *args, **kwargs):
cache = caches[cache_name]
key = cache_key or slugify('%s %r %r' % (f.__name__, args, kwargs)) key = cache_key or slugify('%s %r %r' % (f.__name__, args, kwargs))
value = cache.get(key) value = cache.get(key)
if value is None: if value is None:

View File

@@ -481,6 +481,9 @@ if is_testing():
'default': { 'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}, },
'ephemeral': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
} }
else: else:
CACHES = { CACHES = {
@@ -488,6 +491,9 @@ else:
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'memcached:11211', 'LOCATION': 'memcached:11211',
}, },
'ephemeral': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
} }
# Social Auth configuration. # Social Auth configuration.