Repository: CMSgov/bluebutton-web-server

Issue:
When editing an application user can select capabilities not allowed by his groups



Discussion:
Can you or did you fix this?

I'm going to fix this asap.


Resolving patch:
diff --git a/apps/dot_ext/views/application.py b/apps/dot_ext/views/application.py
--- a/apps/dot_ext/views/application.py
+++ b/apps/dot_ext/views/application.py
@@ -6,6 +6,8 @@
 
 from oauth2_provider.models import get_application_model
 
+from ..forms import CustomRegisterApplicationForm
+
 
 class ApplicationOwnerIsUserMixin(LoginRequiredMixin):
     """
@@ -27,15 +29,15 @@ def get_form_class(self):
         """
         Returns the form class for the application model
         """
-        
+
         mff = modelform_factory(
             get_application_model(),
             fields=('name', 'client_id', 'client_secret', 'client_type',
                     'authorization_grant_type', 'scope', 'redirect_uris', )
         )
         return mff
-    
-    
+
+
 
     def form_valid(self, form):
         form.instance.user = self.request.user
@@ -73,3 +75,15 @@ class ApplicationUpdate(ApplicationOwnerIsUserMixin, UpdateView):
     """
     context_object_name = 'application'
     template_name = "application_form.html"
+
+    fields = None
+    form_class = CustomRegisterApplicationForm
+
+    def get_form_kwargs(self):
+        """
+        Add `user` to kwargs because it is required by the constructor of
+        CustomRegisterApplicationForm class.
+        """
+        kwargs = super(ApplicationUpdate, self).get_form_kwargs()
+        kwargs['user'] = self.request.user
+        return kwargs


Test patch:
diff --git a/apps/dot_ext/tests.py b/apps/dot_ext/tests.py
--- a/apps/dot_ext/tests.py
+++ b/apps/dot_ext/tests.py
@@ -1,3 +1,27 @@
+from __future__ import absolute_import
+from __future__ import unicode_literals
+
+from django.core.urlresolvers import reverse
 from django.test import TestCase
 
-# Create your tests here.
+from ..test import BaseApiTest
+
+
+class TestApplicationUpdateView(BaseApiTest):
+    def test_update_form_show_allowed_scopes(self):
+        """
+        """
+        read_group = self._create_group('read')
+        read_capability = self._create_capability('Read-Scope', [], read_group)
+        write_group = self._create_group('write')
+        write_capability = self._create_capability('Write-Scope', [], write_group)
+        # create user and add it to the read group
+        user = self._create_user('john', '123456')
+        user.groups.add(read_group)
+        # create an application
+        app = self._create_application('john_app', user=user)
+        # render the edit view for the app
+        self.client.login(username=user.username, password='123456')
+        response = self.client.get(reverse('dote_update', args=[app.pk]))
+        self.assertContains(response, 'Read-Scope')
+        self.assertNotContains(response, 'Write-Scope')
diff --git a/apps/test.py b/apps/test.py
--- a/apps/test.py
+++ b/apps/test.py
@@ -6,6 +6,7 @@
 from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User, Group
 from django.test import TestCase
+from django.utils.text import slugify
 
 from apps.capabilities.models import ProtectedCapability
 from apps.dot_ext.models import Application
@@ -25,7 +26,15 @@ def _create_user(self, username, password, **extra_fields):
         user = User.objects.create_user(username, password=password, **extra_fields)
         return user
 
-    def _create_application(self, name, client_type=None, grant_type=None, capability=None):
+    def _create_group(self, name):
+        """
+        Helper method that creates a group instance
+        with `name`.
+        """
+        group, _ = Group.objects.get_or_create(name=name)
+        return group
+
+    def _create_application(self, name, client_type=None, grant_type=None, capability=None, user=None):
 
         """
         Helper method that creates an application instance
@@ -37,7 +46,7 @@ def _create_application(self, name, client_type=None, grant_type=None, capabilit
         client_type = client_type or Application.CLIENT_PUBLIC
         grant_type = grant_type or Application.GRANT_PASSWORD
         # This is the user to whom the application is bound.
-        dev_user = self._create_user('dev', '123456')
+        dev_user = user or self._create_user('dev', '123456')
         application = Application.objects.create(
             name=name, user=dev_user, client_type=client_type,
             authorization_grant_type=grant_type)
@@ -46,14 +55,15 @@ def _create_application(self, name, client_type=None, grant_type=None, capabilit
             application.scope.add(capability)
         return application
 
-    def _create_capability(self, name, urls):
+    def _create_capability(self, name, urls, group=None):
         """
         Helper method that creates a ProtectedCapability instance
         that controls the access for the set of `urls`.
         """
-        group, _ = Group.objects.get_or_create(name='test')
+        group = group or self._create_group('test')
         capability = ProtectedCapability.objects.create(
-            title=name, protected_resources=json.dumps(urls), group=group)
+            title=name, slug=slugify(name),
+            protected_resources=json.dumps(urls), group=group)
         return capability
 
     def _get_access_token(self, username, password, application=None, **extra_fields):