def test_get_active_app_none_none(self): # Get the active TethysApp object, with a request of None and url of None result = utilities.get_active_app(request=None, url=None) self.assertEqual(None, result) # Try again with the defaults, which are a request of None and url of None result = utilities.get_active_app() self.assertEqual(None, result)
def wrapper(*args, **kwargs): from tethys_quotas.models import ResourceQuota from tethys_apps.utilities import get_active_app request = None for index, arg in enumerate(args): if isinstance(arg, HttpRequest): request = arg break if request is None: raise ValueError('No request given. The app_workspace decorator only works on controllers.') try: codename = 'app_workspace_quota' rq = ResourceQuota.objects.get(codename=codename) except ResourceQuota.DoesNotExist: log.warning('ResourceQuota with codename {} does not exist.'.format(codename)) # Get the active app app = get_active_app(request, get_class=True) if not passes_quota(app, codename): raise PermissionDenied(rq.help) the_workspace = _get_app_workspace(app) return controller(*args, the_workspace, **kwargs)
def tethys_apps_context(request): """ Add the current Tethys app metadata to the template context. Args: request: Django request object. """ # Setup variables context = {'tethys_app': None} # Get the app app = get_active_app(request=request) if app is not None: context['tethys_app'] = { 'id': app.id, 'name': app.name, 'index': app.index, 'icon': app.icon, 'color': app.color, 'tags': app.tags, 'description': app.description } if hasattr(app, 'feedback_emails') and len(app.feedback_emails) > 0: context['tethys_app']['feedback_emails'] = app.feedback_emails if hasattr(app, 'enable_feedback'): context['tethys_app']['enable_feedback'] = app.enable_feedback return context
def test_get_active_app_url(self, mock_app): # Mock up for TethysApp mock_app.objects.get.return_value = mock.MagicMock() # Result should be mock for mock_app.objects.get.return_value result = utilities.get_active_app(url='/apps/foo/bar') self.assertEqual(mock_app.objects.get(), result)
def test_get_active_app_request(self, mock_app): # Mock up for TethysApp, and request mock_app.objects.get.return_value = mock.MagicMock() mock_request = mock.MagicMock() mock_request.path = '/apps/foo/bar' # Result should be mock for mock_app.objects.get.return_value result = utilities.get_active_app(request=mock_request) self.assertEqual(mock_app.objects.get(), result)
def test_get_active_app_class(self, mock_app, mock_harvester): # Mock up for TethysApp app = mock.MagicMock() mock_app.objects.get.return_value = app mock_harvester().apps = [app] # Result should be mock for mock_app.objects.get.return_value result = utilities.get_active_app(url='/apps/foo/bar', get_class=True) self.assertEqual(mock_app.objects.get(), result)
def test_get_active_app_request_bad_path(self, mock_app): # Mock up for TethysApp mock_app.objects.get.return_value = mock.MagicMock() mock_request = mock.MagicMock() # Path does not contain apps mock_request.path = '/foo/bar' # Because 'app' not in request path, return None result = utilities.get_active_app(request=mock_request) self.assertEqual(None, result)
def send_beta_feedback_email(request): """ Processes and send the beta form data submitted by beta testers """ # Form parameters post = request.POST # Get url and parts url = post.get('betaFormUrl') # Get app app = get_active_app(url=url) if app is None or not hasattr(app, 'feedback_emails'): json = { 'success': False, 'error': 'App not found or feedback_emails not defined in app.py' } return JsonResponse(json) # Formulate email subject = 'User Feedback for {0}'.format(app.name.encode('utf-8')) message = 'User: {0}\n'\ 'User Local Time: {1}\n'\ 'UTC Offset in Hours: {2}\n'\ 'App URL: {3}\n'\ 'User Agent: {4}\n'\ 'Vendor: {5}\n'\ 'Comments:\n' \ '{6}'.\ format( post.get('betaUser'), post.get('betaSubmitLocalTime'), post.get('betaSubmitUTCOffset'), post.get('betaFormUrl'), post.get('betaFormUserAgent'), post.get('betaFormVendor'), post.get('betaUserComments') ) try: send_mail(subject, message, from_email=None, recipient_list=app.feedback_emails) except Exception as e: json = { 'success': False, 'error': 'Failed to send email: ' + e.message } return JsonResponse(json) json = {'success': True, 'result': 'Emails sent to specified developers'} return JsonResponse(json)
def test_get_active_app_request_exception2(self, mock_app, mock_log_warning): from django.core.exceptions import MultipleObjectsReturned # Mock up for TethysApp to raise exception, and request mock_app.objects.get.side_effect = MultipleObjectsReturned mock_request = mock.MagicMock() mock_request.path = '/apps/foo/bar' # Result should be None due to the exception result = utilities.get_active_app(request=mock_request) self.assertEqual(None, result) mock_log_warning.assert_called_once_with('Multiple apps found with root url "foo".')
def tethys_apps_context(request): """ Add the current Tethys app metadata to the template context. Args: request: Django request object. """ # Setup variables context = {'tethys_app': None} # Get the app app = get_active_app(request=request) if app is not None: context['tethys_app'] = { 'id': app.id, 'name': app.name, 'index': app.index, 'icon': app.icon, 'color': app.color, 'tags': app.tags, 'description': app.description, 'namespace': app.namespace } if hasattr(app, 'feedback_emails') and len(app.feedback_emails) > 0: context['tethys_app']['feedback_emails'] = app.feedback_emails if hasattr(app, 'enable_feedback'): context['tethys_app']['enable_feedback'] = app.enable_feedback # Dependency Versions context.update({ 'tethys': { 'jquery': { 'version': '3.4.1', 'integrity': 'sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=', }, 'bootstrap': { 'version': '3.4.1', 'css_integrity': 'sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu', 'js_integrity': 'sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd' }, } }) return context
def send_beta_feedback_email(request): """ Processes and send the beta form data submitted by beta testers """ # Form parameters post = request.POST # Get url and parts url = post.get('betaFormUrl') # Get app app = get_active_app(url=url) if app is None or not hasattr(app, 'feedback_emails'): json = {'success': False, 'error': 'App not found or feedback_emails not defined in app.py'} return JsonResponse(json) # Formulate email subject = 'User Feedback for {0}'.format(app.name.encode('utf-8')) message = 'User: {0}\n'\ 'User Local Time: {1}\n'\ 'UTC Offset in Hours: {2}\n'\ 'App URL: {3}\n'\ 'User Agent: {4}\n'\ 'Vendor: {5}\n'\ 'Comments:\n' \ '{6}'.\ format( post.get('betaUser'), post.get('betaSubmitLocalTime'), post.get('betaSubmitUTCOffset'), post.get('betaFormUrl'), post.get('betaFormUserAgent'), post.get('betaFormVendor'), post.get('betaUserComments') ) try: send_mail(subject, message, from_email=None, recipient_list=app.feedback_emails) except Exception as e: json = {'success': False, 'error': 'Failed to send email: ' + str(e)} return JsonResponse(json) json = {'success': True, 'result': 'Emails sent to specified developers'} return JsonResponse(json)
def test_user_can_access_app(self, mock_settings): mock_settings.ENABLE_OPEN_PORTAL = False user = self.user app = utilities.get_active_app(url='/apps/test-app') # test no permission result1 = utilities.user_can_access_app(user, app) self.assertFalse(result1) # test permission assign_perm(f'{app.package}:access_app', user, app) result2 = utilities.user_can_access_app(user, app) self.assertTrue(result2) # test open portal mode case mock_settings.ENABLE_OPEN_PORTAL = True result3 = utilities.user_can_access_app(user, app) self.assertTrue(result3)
def __call__(self, request): response = self.get_response(request) app = get_active_app(request) if app is None: return response else: if not app.enabled: if request.user.is_staff: return handler_404( request, PermissionDenied, "This app is disabled. A user with admin permissions " "can enable this app from the app settings page.") else: return handler_404(request, PermissionDenied) elif user_can_access_app(request.user, app): return response else: return handler_404(request, PermissionDenied)
def has_permission(request, perm, user=None): """ Returns True if the user of the given request has the given permission for the app. If a user object is provided, it is tested instead of the request user. The Request object is still required to derive the app context of the permission check. Args: request (Request): The current request object. perm (string): The name of the permission (e.g. 'create_things'). user (django.contrib.auth.models.User): A user object to test instead of the user provided in the request. **Example:** :: from tethys_sdk.permissions import has_permission def my_controller(request): \""" Example controller \""" can_create_projects = has_permission(request, 'create_projects') if can_create_projects: ... """ from tethys_apps.utilities import get_active_app app = get_active_app(request) if user is None: user = request.user namespaced_perm = 'tethys_apps.' + app.package + ':' + perm # Check permission if user.has_perm(namespaced_perm, app): return True return False
def wrapper(*args, **kwargs): try: request = None for index, arg in enumerate(args): if isinstance(arg, HttpRequest): request = arg break if request is None: raise ValueError('Invalid request') rq = ResourceQuota.objects.get(codename=codename) if rq.applies_to == 'django.contrib.auth.models.User': entity = request.user elif rq.applies_to == 'tethys_apps.models.TethysApp': entity = get_active_app(request) if not entity: raise ValueError( 'Request could not be used to find app') else: raise ValueError( 'ResourceQuota that applies_to {} is not supported'. format(rq.applies_to)) if not passes_quota(entity, codename): raise PermissionDenied(rq.help) except ValueError as e: log.warning(str(e)) except ResourceQuota.DoesNotExist: log.warning( 'ResourceQuota with codename {} does not exist.'.format( codename)) return controller(*args, **kwargs)