Skip to content

Commit

Permalink
Merge pull request Kinto#701 from Kinto/prepare-3.2.1
Browse files Browse the repository at this point in the history
Prepare 3.2.1
  • Loading branch information
leplatrem authored Jul 5, 2016
2 parents 8532d6c + 8637213 commit a5c8ada
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 37 deletions.
27 changes: 20 additions & 7 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@ Changelog

This document describes changes between each past release.

3.2.1 (unreleased)
==================

**Bug fixes**

- Fix HTTP API version number exposed (1.7)
- Fix crash in authorization policy when requesting ``GET /buckets/collections`` (fixes #695)
- Fix crash with PostgreSQL storage backend when provided id in POST is an integer (#688).
Regression introduced in 3.2.0 with #655.
- Fix crash with PostgreSQL storage backend is configured as read-only and reaching
the records endpoint of an unknown collection (fixes #693, related #558)


3.2.0 (2016-06-14)
==================

**Protocol**

- Allow record IDs to be any string instead of just UUIDs (fixes #655).

Protocol is now at version **1.7**. See `API changelog <http://kinto.readthedocs.io/en/latest/api/>`_.
Protocol is now at version **1.7**. See `API changelog <https://kinto.readthedocs.io/en/latest/api/>`_.

**New features**

Expand Down Expand Up @@ -52,7 +65,7 @@ Protocol is now at version **1.7**. See `API changelog <http://kinto.readthedocs

- Added the ``GET /contribute.json`` endpoint for open-source information (fixes #607)

Protocol is now at version **1.6**. See `API changelog <http://kinto.readthedocs.io/en/latest/api/>`_.
Protocol is now at version **1.6**. See `API changelog <https://kinto.readthedocs.io/en/latest/api/>`_.


**Bug fixes**
Expand Down Expand Up @@ -161,7 +174,7 @@ Protocol is now at version **1.6**. See `API changelog <http://kinto.readthedocs
- Document how to configure the postgresql backend (#533)
- Document how to upgrade Kinto (#537, #538)

Protocol is now in version **1.5**. See `API changelog <http://kinto.readthedocs.io/en/latest/api/>`_.
Protocol is now in version **1.5**. See `API changelog <https://kinto.readthedocs.io/en/latest/api/>`_.


2.0.0 (2016-03-08)
Expand All @@ -184,7 +197,7 @@ Protocol is now in version **1.5**. See `API changelog <http://kinto.readthedocs
- Add the ``flush_endpoint``, ``schema`` and ``default_bucket`` to the capabilities
if enabled in settings (#270)

Protocol is now in version **1.4**. See `API changelog <http://kinto.readthedocs.io/en/latest/api/>`_.
Protocol is now in version **1.4**. See `API changelog <https://kinto.readthedocs.io/en/latest/api/>`_.

**Breaking changes**

Expand Down Expand Up @@ -214,7 +227,7 @@ Protocol is now in version **1.4**. See `API changelog <http://kinto.readthedocs
- Monitor time of events listeners execution (mozilla-services/cliquet#503)
- Added a new ``AfterResourceChanged`` event, that is sent only when the commit
in database is done and successful.
`See more details <http://cliquet.readthedocs.io/en/latest/reference/notifications.html>`_.
`See more details <https://cliquet.readthedocs.io/en/latest/reference/notifications.html>`_.
- Track execution time on StatsD for each authentication sub-policy (mozilla-services/cliquet#639)
- Default console log renderer now has colours (mozilla-service/cliquet#671)
- Output Kinto version with ``kinto --version`` (thanks @ayusharma)
Expand Down Expand Up @@ -302,7 +315,7 @@ Protocol is now in version **1.4**. See `API changelog <http://kinto.readthedocs
root URL (#628). Clients can rely on this to detect optional features on the
server (e.g. enabled plugins)

Protocol is now version 1.3. See `API changelog <http://kinto.readthedocs.io/en/latest/api/>`_.
Protocol is now version 1.3. See `API changelog <https://kinto.readthedocs.io/en/latest/api/>`_.

**New features**

Expand Down Expand Up @@ -757,7 +770,7 @@ Settings
to use PostgreSQL instead of *Redis* (see default ``config/kinto.ini``)
- ``cliquet.basic_auth_enabled`` is now deprecated (`see *Cliquet*
docs to enable authentication backends
<http://cliquet.readthedocs.io/en/latest/reference/configuration.html#basic-auth>`_)
<https://cliquet.readthedocs.io/en/latest/reference/configuration.html#basic-auth>`_)


**Internal changes**
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
# The short X.Y version.
version = '3.2'
# The full version, including alpha/beta/rc tags.
release = '3.2.0'
release = '3.2.1'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand Down
2 changes: 1 addition & 1 deletion kinto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
__version__ = pkg_resources.get_distribution(__package__).version

# Implemented HTTP API Version
HTTP_API_VERSION = '1.6'
HTTP_API_VERSION = '1.7'

# Main kinto logger
logger = logging.getLogger(__name__)
Expand Down
30 changes: 12 additions & 18 deletions kinto/authorization.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from kinto.core import authorization as core_authorization
import re

from pyramid.security import IAuthorizationPolicy, Authenticated
from zope.interface import implementer

from kinto.core import authorization as core_authorization

# Vocab really matters when you deal with permissions. Let's do a quick recap
# of the terms used here:
Expand Down Expand Up @@ -69,23 +71,15 @@

def get_object_type(object_uri):
"""Return the type of an object from its id."""

obj_parts = object_uri.split('/')
if len(obj_parts) % 2 == 0:
object_uri = '/'.join(obj_parts[:-1])

# Order matters here. More precise is tested first.
if 'records' in object_uri:
obj_type = 'record'
elif 'collections' in object_uri:
obj_type = 'collection'
elif 'groups' in object_uri:
obj_type = 'group'
elif 'buckets' in object_uri:
obj_type = 'bucket'
else:
obj_type = None
return obj_type
if re.match(r'/buckets/(.+)/collections/(.+)/records/(.+)?', object_uri):
return 'record'
if re.match(r'/buckets/(.+)/collections/(.+)?', object_uri):
return 'collection'
if re.match(r'/buckets/(.+)/groups/(.+)?', object_uri):
return 'group'
if re.match(r'/buckets/(.+)?', object_uri):
return 'bucket'
return None


def build_permission_tuple(obj_type, unbound_permission, obj_parts):
Expand Down
3 changes: 2 additions & 1 deletion kinto/core/resource/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ def _raise_400_if_invalid_id(self, record_id):
:raises: :class:`pyramid.httpexceptions.HTTPBadRequest`
"""
if not self.model.id_generator.match(six.text_type(record_id)):
is_string = isinstance(record_id, six.string_types)
if not is_string or not self.model.id_generator.match(record_id):
error_details = {
'location': 'path',
'description': "Invalid record id"
Expand Down
7 changes: 7 additions & 0 deletions kinto/tests/core/resource/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,13 @@ def test_id_is_validated_on_post(self):
headers=self.headers,
status=400)

with mock.patch.object(self.app.app.registry.id_generator, 'match',
return_value=True):
self.app.post_json(self.collection_url,
{'data': record},
headers=self.headers,
status=400)

def test_id_is_preserved_on_post(self):
record = MINIMALIST_RECORD.copy()
record_id = record['id'] = '472be9ec-26fe-461b-8282-9c4e4b207ab3'
Expand Down
5 changes: 5 additions & 0 deletions kinto/tests/test_authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ def test_build_perm_set_uri_can_construct_parents_set_uris(self):
'bucket', 'write', obj_parts),
(self.bucket_uri, 'write'))

def test_build_perm_set_supports_buckets_named_collections(self):
uri = '/buckets/collections'
self.assertEquals(build_permissions_set(uri, 'write'),
set([(uri, 'write')]))

def test_build_permission_tuple_fail_construct_children_set_uris(self):
obj_parts = self.bucket_uri.split('/')
# Cannot build record_uri from bucket obj_parts
Expand Down
9 changes: 9 additions & 0 deletions kinto/tests/test_views_records.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ def test_unknown_collection_raises_404(self):
other_collection = self.collection_url.replace('barley', 'pills')
self.app.get(other_collection, headers=self.headers, status=404)

def test_unknown_collection_does_not_query_timestamp(self):
other_collection = self.collection_url.replace('barley', 'pills')
patch = mock.patch.object(self.app.app.registry.storage,
'collection_timestamp')
self.addCleanup(patch.stop)
mocked = patch.start()
self.app.get(other_collection, headers=self.headers, status=404)
self.assertFalse(mocked.called)

def test_parent_collection_is_fetched_only_once_in_batch(self):
batch = {'requests': []}
nb_create = 25
Expand Down
15 changes: 7 additions & 8 deletions kinto/views/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,22 @@ class Record(resource.ShareableResource):
mapping = RecordSchema()
schema_field = 'schema'

def __init__(self, *args, **kwargs):
super(Record, self).__init__(*args, **kwargs)

self.model.id_generator = RelaxedUUID()

def __init__(self, request, **kwargs):
# Before all, first check that the parent collection exists.
# Check if already fetched before (in batch).
collections = self.request.bound_data.setdefault('collections', {})
collection_uri = self.get_parent_id(self.request)
collections = request.bound_data.setdefault('collections', {})
collection_uri = self.get_parent_id(request)
if collection_uri not in collections:
# Unknown yet, fetch from storage.
collection_parent_id = '/buckets/%s' % self.bucket_id
collection = object_exists_or_404(self.request,
collection = object_exists_or_404(request,
collection_id='collection',
parent_id=collection_parent_id,
object_id=self.collection_id)
collections[collection_uri] = collection

super(Record, self).__init__(request, **kwargs)
self.model.id_generator = RelaxedUUID()
self._collection = collections[collection_uri]

def get_parent_id(self, request):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def read_file(filename):


setup(name='kinto',
version='3.2.0',
version='3.2.1',
description='Kinto Web Service - Store, Sync, Share, and Self-Host.',
long_description=README + "\n\n" + CHANGELOG + "\n\n" + CONTRIBUTORS,
license='Apache License (2.0)',
Expand Down

0 comments on commit a5c8ada

Please sign in to comment.