Repository: Kinto/kinto

Issue:
Return 400 if a group contains system.Everyone or a group URL
Unless I'm mistaken:
- We don't support groups for anonymous requests
- We don't support recursivity in groups definitions

So we should reject with `400` if such groups definitons are created



Discussion:
Hi @leplatrem this seems easy, but can you provide little more information regarding where we need to add this check and raise 400?

You have to add à custom validator on the group schema members field, and everything will be taken care of by kinto.core

I advise you to start by writing a group view test that will fail at first, and then make the changes so that the validator comes in the game :)


Resolving patch:
diff --git a/kinto/views/groups.py b/kinto/views/groups.py
--- a/kinto/views/groups.py
+++ b/kinto/views/groups.py
@@ -5,9 +5,15 @@
 from pyramid.events import subscriber
 
 
+def validate_member(node, member):
+    if member.startswith('/buckets/') or member == 'system.Everyone':
+        raise colander.Invalid(node, "%r is not a valid user ID." % member)
+
+
 class GroupSchema(resource.ResourceSchema):
     members = colander.SchemaNode(colander.Sequence(),
-                                  colander.SchemaNode(colander.String()))
+                                  colander.SchemaNode(colander.String(),
+                                                      validator=validate_member))
 
 
 @resource.register(name='group',


Test patch:
diff --git a/tests/test_views_groups.py b/tests/test_views_groups.py
--- a/tests/test_views_groups.py
+++ b/tests/test_views_groups.py
@@ -1,10 +1,12 @@
-from kinto.core.testing import unittest
+import unittest
+from kinto.core.errors import ERRORS
+from kinto.core.testing import FormattedErrorMixin
 
 from .support import (BaseWebTest, MINIMALIST_BUCKET,
                       MINIMALIST_GROUP)
 
 
-class GroupViewTest(BaseWebTest, unittest.TestCase):
+class GroupViewTest(FormattedErrorMixin, BaseWebTest, unittest.TestCase):
 
     collection_url = '/buckets/beers/groups'
     record_url = '/buckets/beers/groups/moderators'
@@ -104,6 +106,30 @@ def test_recreate_group_after_deletion_returns_a_201(self):
                           headers=self.headers,
                           status=201)
 
+    def test_group_doesnt_accept_system_Everyone(self):
+        group = MINIMALIST_GROUP.copy()
+        group['data'] = {'members': ['system.Everyone']}
+        response = self.app.put_json('/buckets/beers/groups/moderator',
+                                     group,
+                                     headers=self.headers,
+                                     status=400)
+        self.assertFormattedError(
+            response, 400, ERRORS.INVALID_PARAMETERS,
+            "Invalid parameters",
+            "'system.Everyone' is not a valid user ID.")
+
+    def test_group_doesnt_accept_groups_inside_groups(self):
+        group = MINIMALIST_GROUP.copy()
+        group['data'] = {'members': ['/buckets/beers/groups/administrators']}
+        response = self.app.put_json('/buckets/beers/groups/moderator',
+                                     group,
+                                     headers=self.headers,
+                                     status=400)
+        self.assertFormattedError(
+            response, 400, ERRORS.INVALID_PARAMETERS,
+            "Invalid parameters",
+            "'/buckets/beers/groups/administrators' is not a valid user ID.")
+
 
 class GroupManagementTest(BaseWebTest, unittest.TestCase):