We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
The /permissions endpoint is broken
To reproduce just access https://kinto-ota.dev.mozaws.net/v1/permissions

```
  File "/home/ubuntu/venvs/kinto/local/lib/python2.7/site-packages/kinto/core/permission/re
dis.py", line 103, in get_accessible_objects
    _, object_id, permission = key.decode('utf-8').split(':')
ValueError: too many values to unpack
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kinto/core/permission/redis.py`
Content:
```
1 from __future__ import absolute_import
2 
3 from collections import defaultdict
4 
5 from kinto.core.permission import PermissionBase
6 from kinto.core.storage.redis import create_from_config, wrap_redis_error
7 
8 
9 class Permission(PermissionBase):
10     """Permission backend implementation using Redis.
11 
12     Enable in configuration::
13 
14         kinto.permission_backend = kinto.core.permission.redis
15 
16     *(Optional)* Instance location URI can be customized::
17 
18         kinto.permission_url = redis://localhost:6379/2
19 
20     A threaded connection pool is enabled by default::
21 
22         kinto.permission_pool_size = 50
23 
24     :noindex:
25     """
26 
27     def __init__(self, client, *args, **kwargs):
28         super(Permission, self).__init__(*args, **kwargs)
29         self._client = client
30 
31     @property
32     def settings(self):
33         return dict(self._client.connection_pool.connection_kwargs)
34 
35     def initialize_schema(self):
36         # Nothing to do.
37         pass
38 
39     def _decode_set(self, results):
40         return set([r.decode('utf-8') for r in results])
41 
42     @wrap_redis_error
43     def flush(self):
44         self._client.flushdb()
45 
46     @wrap_redis_error
47     def add_user_principal(self, user_id, principal):
48         user_key = 'user:%s' % user_id
49         self._client.sadd(user_key, principal)
50 
51     @wrap_redis_error
52     def remove_user_principal(self, user_id, principal):
53         user_key = 'user:%s' % user_id
54         self._client.srem(user_key, principal)
55         if self._client.scard(user_key) == 0:
56             self._client.delete(user_key)
57 
58     def remove_principal(self, principal):
59         with self._client.pipeline() as pipe:
60             user_keys = self._client.scan_iter(match='user:*')
61             for user_key in user_keys:
62                 pipe.srem(user_key, principal)
63             pipe.execute()
64 
65     @wrap_redis_error
66     def get_user_principals(self, user_id):
67         user_key = 'user:%s' % user_id
68         return self._decode_set(self._client.smembers(user_key))
69 
70     @wrap_redis_error
71     def add_principal_to_ace(self, object_id, permission, principal):
72         permission_key = 'permission:%s:%s' % (object_id, permission)
73         self._client.sadd(permission_key, principal)
74 
75     @wrap_redis_error
76     def remove_principal_from_ace(self, object_id, permission, principal):
77         permission_key = 'permission:%s:%s' % (object_id, permission)
78         self._client.srem(permission_key, principal)
79         if self._client.scard(permission_key) == 0:
80             self._client.delete(permission_key)
81 
82     @wrap_redis_error
83     def get_object_permission_principals(self, object_id, permission):
84         permission_key = 'permission:%s:%s' % (object_id, permission)
85         members = self._client.smembers(permission_key)
86         return self._decode_set(members)
87 
88     @wrap_redis_error
89     def get_accessible_objects(self, principals, bound_permissions=None):
90         principals = set(principals)
91 
92         if bound_permissions:
93             keys = ['permission:%s:%s' % op for op in bound_permissions]
94         else:
95             keys = ['permission:*']
96 
97         perms_by_id = dict()
98         for key_pattern in keys:
99             matched = self._client.scan_iter(match=key_pattern)
100             for key in matched:
101                 authorized = self._decode_set(self._client.smembers(key))
102                 if len(authorized & principals) > 0:
103                     _, object_id, permission = key.decode('utf-8').split(':')
104                     perms_by_id.setdefault(object_id, set()).add(permission)
105 
106         return perms_by_id
107 
108     @wrap_redis_error
109     def get_authorized_principals(self, bound_permissions):
110         keys = ['permission:%s:%s' % (o, p) for (o, p) in bound_permissions]
111         if keys:
112             return self._decode_set(self._client.sunion(*list(keys)))
113         return set()
114 
115     @wrap_redis_error
116     def get_objects_permissions(self, objects_ids, permissions=None):
117         objects_perms = []
118         for object_id in objects_ids:
119             if permissions is not None:
120                 keys = ['permission:%s:%s' % (object_id, permission)
121                         for permission in permissions]
122             else:
123                 keys = [key.decode('utf-8') for key in self._client.scan_iter(
124                     match='permission:%s:*' % object_id)]
125 
126             with self._client.pipeline() as pipe:
127                 for permission_key in keys:
128                     pipe.smembers(permission_key)
129 
130                 results = pipe.execute()
131 
132             permissions = defaultdict(set)
133             for i, result in enumerate(results):
134                 permission = keys[i].split(':', 2)[-1]
135                 permissions[permission] = self._decode_set(result)
136             objects_perms.append(permissions)
137         return objects_perms
138 
139     @wrap_redis_error
140     def replace_object_permissions(self, object_id, permissions):
141         keys = ['permission:%s:%s' % (object_id, permission)
142                 for permission in permissions]
143         with self._client.pipeline() as pipe:
144             for key in keys:
145                 pipe.delete(key)
146                 permission = key.split(':', 2)[-1]
147                 principals = permissions[permission]
148                 if len(principals) > 0:
149                     pipe.sadd(key, *principals)
150             pipe.execute()
151 
152     @wrap_redis_error
153     def delete_object_permissions(self, *object_id_list):
154         with self._client.pipeline() as pipe:
155             for object_id in object_id_list:
156                 keys = list(self._client.scan_iter(
157                     match='permission:%s:*' % object_id))
158                 if len(keys) > 0:
159                     pipe.delete(*keys)
160             pipe.execute()
161 
162 
163 def load_from_config(config):
164     client = create_from_config(config, prefix='permission_')
165     return Permission(client)
166
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kinto/core/permission/redis.py b/kinto/core/permission/redis.py
--- a/kinto/core/permission/redis.py
+++ b/kinto/core/permission/redis.py
@@ -100,8 +100,8 @@
             for key in matched:
                 authorized = self._decode_set(self._client.smembers(key))
                 if len(authorized & principals) > 0:
-                    _, object_id, permission = key.decode('utf-8').split(':')
-                    perms_by_id.setdefault(object_id, set()).add(permission)
+                    _, obj_id, permission = key.decode('utf-8').split(':', 2)
+                    perms_by_id.setdefault(obj_id, set()).add(permission)
 
         return perms_by_id

{"golden_diff": "diff --git a/kinto/core/permission/redis.py b/kinto/core/permission/redis.py\n--- a/kinto/core/permission/redis.py\n+++ b/kinto/core/permission/redis.py\n@@ -100,8 +100,8 @@\n             for key in matched:\n                 authorized = self._decode_set(self._client.smembers(key))\n                 if len(authorized & principals) > 0:\n-                    _, object_id, permission = key.decode('utf-8').split(':')\n-                    perms_by_id.setdefault(object_id, set()).add(permission)\n+                    _, obj_id, permission = key.decode('utf-8').split(':', 2)\n+                    perms_by_id.setdefault(obj_id, set()).add(permission)\n \n         return perms_by_id\n", "issue": "The /permissions endpoint is broken\nTo reproduce just access https://kinto-ota.dev.mozaws.net/v1/permissions\n\n```\n  File \"/home/ubuntu/venvs/kinto/local/lib/python2.7/site-packages/kinto/core/permission/re\ndis.py\", line 103, in get_accessible_objects\n    _, object_id, permission = key.decode('utf-8').split(':')\nValueError: too many values to unpack\n```\n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nfrom collections import defaultdict\n\nfrom kinto.core.permission import PermissionBase\nfrom kinto.core.storage.redis import create_from_config, wrap_redis_error\n\n\nclass Permission(PermissionBase):\n    \"\"\"Permission backend implementation using Redis.\n\n    Enable in configuration::\n\n        kinto.permission_backend = kinto.core.permission.redis\n\n    *(Optional)* Instance location URI can be customized::\n\n        kinto.permission_url = redis://localhost:6379/2\n\n    A threaded connection pool is enabled by default::\n\n        kinto.permission_pool_size = 50\n\n    :noindex:\n    \"\"\"\n\n    def __init__(self, client, *args, **kwargs):\n        super(Permission, self).__init__(*args, **kwargs)\n        self._client = client\n\n    @property\n    def settings(self):\n        return dict(self._client.connection_pool.connection_kwargs)\n\n    def initialize_schema(self):\n        # Nothing to do.\n        pass\n\n    def _decode_set(self, results):\n        return set([r.decode('utf-8') for r in results])\n\n    @wrap_redis_error\n    def flush(self):\n        self._client.flushdb()\n\n    @wrap_redis_error\n    def add_user_principal(self, user_id, principal):\n        user_key = 'user:%s' % user_id\n        self._client.sadd(user_key, principal)\n\n    @wrap_redis_error\n    def remove_user_principal(self, user_id, principal):\n        user_key = 'user:%s' % user_id\n        self._client.srem(user_key, principal)\n        if self._client.scard(user_key) == 0:\n            self._client.delete(user_key)\n\n    def remove_principal(self, principal):\n        with self._client.pipeline() as pipe:\n            user_keys = self._client.scan_iter(match='user:*')\n            for user_key in user_keys:\n                pipe.srem(user_key, principal)\n            pipe.execute()\n\n    @wrap_redis_error\n    def get_user_principals(self, user_id):\n        user_key = 'user:%s' % user_id\n        return self._decode_set(self._client.smembers(user_key))\n\n    @wrap_redis_error\n    def add_principal_to_ace(self, object_id, permission, principal):\n        permission_key = 'permission:%s:%s' % (object_id, permission)\n        self._client.sadd(permission_key, principal)\n\n    @wrap_redis_error\n    def remove_principal_from_ace(self, object_id, permission, principal):\n        permission_key = 'permission:%s:%s' % (object_id, permission)\n        self._client.srem(permission_key, principal)\n        if self._client.scard(permission_key) == 0:\n            self._client.delete(permission_key)\n\n    @wrap_redis_error\n    def get_object_permission_principals(self, object_id, permission):\n        permission_key = 'permission:%s:%s' % (object_id, permission)\n        members = self._client.smembers(permission_key)\n        return self._decode_set(members)\n\n    @wrap_redis_error\n    def get_accessible_objects(self, principals, bound_permissions=None):\n        principals = set(principals)\n\n        if bound_permissions:\n            keys = ['permission:%s:%s' % op for op in bound_permissions]\n        else:\n            keys = ['permission:*']\n\n        perms_by_id = dict()\n        for key_pattern in keys:\n            matched = self._client.scan_iter(match=key_pattern)\n            for key in matched:\n                authorized = self._decode_set(self._client.smembers(key))\n                if len(authorized & principals) > 0:\n                    _, object_id, permission = key.decode('utf-8').split(':')\n                    perms_by_id.setdefault(object_id, set()).add(permission)\n\n        return perms_by_id\n\n    @wrap_redis_error\n    def get_authorized_principals(self, bound_permissions):\n        keys = ['permission:%s:%s' % (o, p) for (o, p) in bound_permissions]\n        if keys:\n            return self._decode_set(self._client.sunion(*list(keys)))\n        return set()\n\n    @wrap_redis_error\n    def get_objects_permissions(self, objects_ids, permissions=None):\n        objects_perms = []\n        for object_id in objects_ids:\n            if permissions is not None:\n                keys = ['permission:%s:%s' % (object_id, permission)\n                        for permission in permissions]\n            else:\n                keys = [key.decode('utf-8') for key in self._client.scan_iter(\n                    match='permission:%s:*' % object_id)]\n\n            with self._client.pipeline() as pipe:\n                for permission_key in keys:\n                    pipe.smembers(permission_key)\n\n                results = pipe.execute()\n\n            permissions = defaultdict(set)\n            for i, result in enumerate(results):\n                permission = keys[i].split(':', 2)[-1]\n                permissions[permission] = self._decode_set(result)\n            objects_perms.append(permissions)\n        return objects_perms\n\n    @wrap_redis_error\n    def replace_object_permissions(self, object_id, permissions):\n        keys = ['permission:%s:%s' % (object_id, permission)\n                for permission in permissions]\n        with self._client.pipeline() as pipe:\n            for key in keys:\n                pipe.delete(key)\n                permission = key.split(':', 2)[-1]\n                principals = permissions[permission]\n                if len(principals) > 0:\n                    pipe.sadd(key, *principals)\n            pipe.execute()\n\n    @wrap_redis_error\n    def delete_object_permissions(self, *object_id_list):\n        with self._client.pipeline() as pipe:\n            for object_id in object_id_list:\n                keys = list(self._client.scan_iter(\n                    match='permission:%s:*' % object_id))\n                if len(keys) > 0:\n                    pipe.delete(*keys)\n            pipe.execute()\n\n\ndef load_from_config(config):\n    client = create_from_config(config, prefix='permission_')\n    return Permission(client)\n", "path": "kinto/core/permission/redis.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nfrom collections import defaultdict\n\nfrom kinto.core.permission import PermissionBase\nfrom kinto.core.storage.redis import create_from_config, wrap_redis_error\n\n\nclass Permission(PermissionBase):\n    \"\"\"Permission backend implementation using Redis.\n\n    Enable in configuration::\n\n        kinto.permission_backend = kinto.core.permission.redis\n\n    *(Optional)* Instance location URI can be customized::\n\n        kinto.permission_url = redis://localhost:6379/2\n\n    A threaded connection pool is enabled by default::\n\n        kinto.permission_pool_size = 50\n\n    :noindex:\n    \"\"\"\n\n    def __init__(self, client, *args, **kwargs):\n        super(Permission, self).__init__(*args, **kwargs)\n        self._client = client\n\n    @property\n    def settings(self):\n        return dict(self._client.connection_pool.connection_kwargs)\n\n    def initialize_schema(self):\n        # Nothing to do.\n        pass\n\n    def _decode_set(self, results):\n        return set([r.decode('utf-8') for r in results])\n\n    @wrap_redis_error\n    def flush(self):\n        self._client.flushdb()\n\n    @wrap_redis_error\n    def add_user_principal(self, user_id, principal):\n        user_key = 'user:%s' % user_id\n        self._client.sadd(user_key, principal)\n\n    @wrap_redis_error\n    def remove_user_principal(self, user_id, principal):\n        user_key = 'user:%s' % user_id\n        self._client.srem(user_key, principal)\n        if self._client.scard(user_key) == 0:\n            self._client.delete(user_key)\n\n    def remove_principal(self, principal):\n        with self._client.pipeline() as pipe:\n            user_keys = self._client.scan_iter(match='user:*')\n            for user_key in user_keys:\n                pipe.srem(user_key, principal)\n            pipe.execute()\n\n    @wrap_redis_error\n    def get_user_principals(self, user_id):\n        user_key = 'user:%s' % user_id\n        return self._decode_set(self._client.smembers(user_key))\n\n    @wrap_redis_error\n    def add_principal_to_ace(self, object_id, permission, principal):\n        permission_key = 'permission:%s:%s' % (object_id, permission)\n        self._client.sadd(permission_key, principal)\n\n    @wrap_redis_error\n    def remove_principal_from_ace(self, object_id, permission, principal):\n        permission_key = 'permission:%s:%s' % (object_id, permission)\n        self._client.srem(permission_key, principal)\n        if self._client.scard(permission_key) == 0:\n            self._client.delete(permission_key)\n\n    @wrap_redis_error\n    def get_object_permission_principals(self, object_id, permission):\n        permission_key = 'permission:%s:%s' % (object_id, permission)\n        members = self._client.smembers(permission_key)\n        return self._decode_set(members)\n\n    @wrap_redis_error\n    def get_accessible_objects(self, principals, bound_permissions=None):\n        principals = set(principals)\n\n        if bound_permissions:\n            keys = ['permission:%s:%s' % op for op in bound_permissions]\n        else:\n            keys = ['permission:*']\n\n        perms_by_id = dict()\n        for key_pattern in keys:\n            matched = self._client.scan_iter(match=key_pattern)\n            for key in matched:\n                authorized = self._decode_set(self._client.smembers(key))\n                if len(authorized & principals) > 0:\n                    _, obj_id, permission = key.decode('utf-8').split(':', 2)\n                    perms_by_id.setdefault(obj_id, set()).add(permission)\n\n        return perms_by_id\n\n    @wrap_redis_error\n    def get_authorized_principals(self, bound_permissions):\n        keys = ['permission:%s:%s' % (o, p) for (o, p) in bound_permissions]\n        if keys:\n            return self._decode_set(self._client.sunion(*list(keys)))\n        return set()\n\n    @wrap_redis_error\n    def get_objects_permissions(self, objects_ids, permissions=None):\n        objects_perms = []\n        for object_id in objects_ids:\n            if permissions is not None:\n                keys = ['permission:%s:%s' % (object_id, permission)\n                        for permission in permissions]\n            else:\n                keys = [key.decode('utf-8') for key in self._client.scan_iter(\n                    match='permission:%s:*' % object_id)]\n\n            with self._client.pipeline() as pipe:\n                for permission_key in keys:\n                    pipe.smembers(permission_key)\n\n                results = pipe.execute()\n\n            permissions = defaultdict(set)\n            for i, result in enumerate(results):\n                permission = keys[i].split(':', 2)[-1]\n                permissions[permission] = self._decode_set(result)\n            objects_perms.append(permissions)\n        return objects_perms\n\n    @wrap_redis_error\n    def replace_object_permissions(self, object_id, permissions):\n        keys = ['permission:%s:%s' % (object_id, permission)\n                for permission in permissions]\n        with self._client.pipeline() as pipe:\n            for key in keys:\n                pipe.delete(key)\n                permission = key.split(':', 2)[-1]\n                principals = permissions[permission]\n                if len(principals) > 0:\n                    pipe.sadd(key, *principals)\n            pipe.execute()\n\n    @wrap_redis_error\n    def delete_object_permissions(self, *object_id_list):\n        with self._client.pipeline() as pipe:\n            for object_id in object_id_list:\n                keys = list(self._client.scan_iter(\n                    match='permission:%s:*' % object_id))\n                if len(keys) > 0:\n                    pipe.delete(*keys)\n            pipe.execute()\n\n\ndef load_from_config(config):\n    client = create_from_config(config, prefix='permission_')\n    return Permission(client)\n", "path": "kinto/core/permission/redis.py"}]}