From 3d6343562fdb3550e5cdac0239ce3a3cf655a9c5 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Fri, 2 Mar 2018 12:10:10 +0100 Subject: [PATCH 1/3] Strip spaces from resources (fixes #148) --- CHANGELOG.rst | 1 + README.rst | 12 ++++++------ kinto_signer/utils.py | 6 +++--- tests/test_plugin_setup.py | 4 +--- tests/test_signoff_flow.py | 2 +- tests/test_utils.py | 14 ++++++++++++-- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b0df69bf..ebe8015d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,7 @@ This document describes changes between each past release. **New features** +- Allow spaces in resources configurations (fixes #148) - Allow configuration of ``reviewers_group``, ``editors_group``, ``to_review_enabled``, ``group_check_enabled`` by bucket - Allow placeholders ``{bucket_id}`` and ``{collection_id}`` in ``reviewers_group``, ``editors_group``, diff --git a/README.rst b/README.rst index 6933dd39..1266f1c8 100644 --- a/README.rst +++ b/README.rst @@ -103,9 +103,9 @@ Here is an example of what a configuration could look like: kinto.includes = kinto_signer kinto.signer.resources = - /buckets/source;/bucket/destination - /buckets/source/collections/collection1;/buckets/destination/collections/collection2 - /buckets/bid/collections/cid;/buckets/bid/collections/cid2 + /buckets/source ; /bucket/destination + /buckets/source/collections/collection1 ; /buckets/destination/collections/collection2 + /buckets/bid/collections/cid ; /buckets/bid/collections/cid2 +---------------------------------+--------------------------------------------------------------------------+ | Setting name | What does it do? | @@ -216,8 +216,8 @@ collection will be enabled. .. code-block:: ini kinto.signer.resources = - /buckets/staging;/buckets/preview;/buckets/blog - /buckets/bid/collections/c1;/buckets/bid/collections/c2;/buckets/bid/collections/c3 + /buckets/staging ; /buckets/preview ; /buckets/blog + /buckets/bid/collections/c1 ; /buckets/bid/collections/c2 ; /buckets/bid/collections/c3 .. image:: workflow.png @@ -255,7 +255,7 @@ Suppose we defined the following resources in the configuration: .. code-block:: ini - kinto.signer.resources = /buckets/source;/buckets/destination + kinto.signer.resources = /buckets/source ; /buckets/destination First, if necessary, we create the appropriate Kinto objects, for example, with ``httpie``: diff --git a/kinto_signer/utils.py b/kinto_signer/utils.py index 991e292f..5b9e34df 100644 --- a/kinto_signer/utils.py +++ b/kinto_signer/utils.py @@ -3,7 +3,6 @@ from kinto.views import NameGenerator from enum import Enum -from pyramid.settings import aslist from pyramid.exceptions import ConfigurationError @@ -54,13 +53,14 @@ def _get_resource(resource): def parse_resources(raw_resources): resources = OrderedDict() - for res in aslist(raw_resources): + lines = [l.strip() for l in raw_resources.strip().splitlines()] + for res in lines: error_msg = "Malformed resource: %%s (in %r). See kinto-signer README." % res if ";" not in res: raise ConfigurationError(error_msg % "not separated with ';'") try: - triplet = res.strip(';').split(';') + triplet = [r.strip() for r in res.strip(';').split(';')] if len(triplet) == 2: source_uri, destination_uri = triplet preview_uri = None diff --git a/tests/test_plugin_setup.py b/tests/test_plugin_setup.py index 0c61a293..0dee9382 100644 --- a/tests/test_plugin_setup.py +++ b/tests/test_plugin_setup.py @@ -196,9 +196,7 @@ def test_a_statsd_timer_is_used_for_signature_if_configured(self): def test_includeme_raises_value_error_if_unknown_placeholder(self): settings = { - "signer.resources": ( - "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1", - ), + "signer.resources": "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1", "signer.editors_group": "{datetime}_group", "signer.ecdsa.public_key": "/path/to/key", "signer.ecdsa.private_key": "/path/to/private", diff --git a/tests/test_signoff_flow.py b/tests/test_signoff_flow.py index 8003a7ee..44e4b4d3 100644 --- a/tests/test_signoff_flow.py +++ b/tests/test_signoff_flow.py @@ -385,7 +385,7 @@ def get_app_settings(cls, extras=None): cls.source_collection1 = "/buckets/alice/collections/cid1" cls.source_collection2 = "/buckets/alice/collections/cid2" - settings['kinto.signer.resources'] = "%s;%s %s;%s" % ( + settings['kinto.signer.resources'] = "%s;%s\n%s;%s" % ( cls.source_collection1, cls.source_collection1.replace("alice", "destination"), cls.source_collection2, diff --git a/tests/test_utils.py b/tests/test_utils.py index dc39ec6a..301cefaa 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -76,6 +76,16 @@ def test_returned_resources_match_the_legacy_format(self): } } + def test_spaces_are_supported(self): + raw_resources = """ + /buckets/bid1/collections/scid1 ; /buckets/bid1/collections/dcid1 + /buckets/bid2/collections/scid2 ; /buckets/bid2/collections/dcid2 + """ + resources = utils.parse_resources(raw_resources) + assert len(resources) == 2 + assert resources['/buckets/bid1/collections/scid1']['source']['bucket'] == 'bid1' + assert resources['/buckets/bid2/collections/scid2']['source']['bucket'] == 'bid2' + def test_multiple_resources_are_supported(self): raw_resources = """ /buckets/sbid1/collections/scid1;/buckets/dbid1/collections/dcid1 @@ -211,14 +221,14 @@ def test_cannot_repeat_resources(self): # Source in other's preview. raw_resources = """ /buckets/stage;/buckets/preview;/buckets/prod - /buckets/bid1;/buckets/stage;/buckets/bid2 + /buckets/bid1 ;/buckets/stage ;/buckets/bid2 """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) # Source in other's destination. raw_resources = """ - /buckets/bid/collections/cid;/buckets/bid/collections/cid2;/buckets/bid/collections/cid3 + /buckets/bid/collections/cid ;/buckets/bid/collections/cid2;/buckets/bid/collections/cid3 /buckets/bid/collections/cida;/buckets/bid/collections/cidb;/buckets/bid/collections/cid """ with self.assertRaises(ConfigurationError): From 7f5b917ebcb446b03ada1212c66b7ed57b36ba85 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Mon, 5 Mar 2018 16:34:03 +0100 Subject: [PATCH 2/3] Separate resources with arrows (fixes #88) --- CHANGELOG.rst | 2 +- README.rst | 12 ++--- kinto_signer/utils.py | 5 +- tests/config/signer.ini | 8 +-- tests/test_events.py | 4 +- tests/test_plugin_setup.py | 24 ++++----- tests/test_signoff_flow.py | 8 +-- tests/test_utils.py | 104 +++++++++++++++++++++---------------- 8 files changed, 92 insertions(+), 75 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ebe8015d..c936b900 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,7 +14,7 @@ This document describes changes between each past release. **New features** -- Allow spaces in resources configurations (fixes #148) +- Allow spaces in resources configurations, and separate URIs with ``->`` for better readability (fixes #148, fixes #88) - Allow configuration of ``reviewers_group``, ``editors_group``, ``to_review_enabled``, ``group_check_enabled`` by bucket - Allow placeholders ``{bucket_id}`` and ``{collection_id}`` in ``reviewers_group``, ``editors_group``, diff --git a/README.rst b/README.rst index 1266f1c8..ffae744c 100644 --- a/README.rst +++ b/README.rst @@ -103,9 +103,9 @@ Here is an example of what a configuration could look like: kinto.includes = kinto_signer kinto.signer.resources = - /buckets/source ; /bucket/destination - /buckets/source/collections/collection1 ; /buckets/destination/collections/collection2 - /buckets/bid/collections/cid ; /buckets/bid/collections/cid2 + /buckets/source -> /bucket/destination + /buckets/source/collections/collection1 -> /buckets/destination/collections/collection2 + /buckets/bid/collections/cid -> /buckets/bid/collections/cid2 +---------------------------------+--------------------------------------------------------------------------+ | Setting name | What does it do? | @@ -216,8 +216,8 @@ collection will be enabled. .. code-block:: ini kinto.signer.resources = - /buckets/staging ; /buckets/preview ; /buckets/blog - /buckets/bid/collections/c1 ; /buckets/bid/collections/c2 ; /buckets/bid/collections/c3 + /buckets/staging -> /buckets/preview -> /buckets/blog + /buckets/bid/collections/c1 -> /buckets/bid/collections/c2 -> /buckets/bid/collections/c3 .. image:: workflow.png @@ -255,7 +255,7 @@ Suppose we defined the following resources in the configuration: .. code-block:: ini - kinto.signer.resources = /buckets/source ; /buckets/destination + kinto.signer.resources = /buckets/source -> /buckets/destination First, if necessary, we create the appropriate Kinto objects, for example, with ``httpie``: diff --git a/kinto_signer/utils.py b/kinto_signer/utils.py index 5b9e34df..598cf472 100644 --- a/kinto_signer/utils.py +++ b/kinto_signer/utils.py @@ -56,11 +56,12 @@ def parse_resources(raw_resources): lines = [l.strip() for l in raw_resources.strip().splitlines()] for res in lines: error_msg = "Malformed resource: %%s (in %r). See kinto-signer README." % res - if ";" not in res: + if "->" not in res and ";" not in res: raise ConfigurationError(error_msg % "not separated with ';'") try: - triplet = [r.strip() for r in res.strip(';').split(';')] + triplet = [r.strip() + for r in res.replace(';', ' ').replace('->', ' ').split()] if len(triplet) == 2: source_uri, destination_uri = triplet preview_uri = None diff --git a/tests/config/signer.ini b/tests/config/signer.ini index 960d6366..6dafb759 100644 --- a/tests/config/signer.ini +++ b/tests/config/signer.ini @@ -16,10 +16,10 @@ signer.group_check_enabled = true signer.to_review_enabled = true kinto.signer.resources = - /buckets/alice/collections/source;/buckets/alice/collections/destination - /buckets/alice/collections/from;/buckets/alice/collections/preview;/buckets/alice/collections/to - /buckets/bob/collections/source;/buckets/bob/collections/destination - /buckets/stage;/buckets/preview;/buckets/prod + /buckets/alice/collections/source -> /buckets/alice/collections/destination + /buckets/alice/collections/from -> /buckets/alice/collections/preview -> /buckets/alice/collections/to + /buckets/bob/collections/source-> /buckets/bob/collections/destination + /buckets/stage -> /buckets/preview -> /buckets/prod kinto.signer.signer_backend = kinto_signer.signer.autograph kinto.signer.autograph.server_url = http://localhost:8000 diff --git a/tests/test_events.py b/tests/test_events.py index d2343b88..0a48c4b0 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -36,7 +36,7 @@ def get_app_settings(cls, extras=None): cls.source_collection = "/buckets/alice/collections/scid" cls.destination_collection = "/buckets/destination/collections/dcid" - settings['kinto.signer.resources'] = '%s;%s' % ( + settings['kinto.signer.resources'] = '%s -> %s' % ( cls.source_collection, cls.destination_collection) @@ -223,7 +223,7 @@ def get_app_settings(cls, extras=None): cls.source_collection = "/buckets/alice/collections/scid" cls.destination_collection = "/buckets/destination/collections/dcid" - settings['kinto.signer.resources'] = '%s;%s' % ( + settings['kinto.signer.resources'] = '%s -> %s' % ( cls.source_collection, cls.destination_collection) diff --git a/tests/test_plugin_setup.py b/tests/test_plugin_setup.py index 0dee9382..57b31a2b 100644 --- a/tests/test_plugin_setup.py +++ b/tests/test_plugin_setup.py @@ -115,7 +115,7 @@ def test_includeme_raises_value_error_if_no_resource_defined(self): def test_defines_a_signer_per_bucket(self): settings = { "signer.resources": ( - "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1\n" + "/buckets/sb1/collections/sc1 -> /buckets/db1/collections/dc1\n" ), "signer.sb1.signer_backend": "kinto_signer.signer.local_ecdsa", "signer.sb1.ecdsa.public_key": "/path/to/key", @@ -128,8 +128,8 @@ def test_defines_a_signer_per_bucket(self): def test_defines_a_signer_per_bucket_and_collection(self): settings = { "signer.resources": ( - "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1\n" - "/buckets/sb1/collections/sc2;/buckets/db1/collections/dc2" + "/buckets/sb1/collections/sc1 -> /buckets/db1/collections/dc1\n" + "/buckets/sb1/collections/sc2 -> /buckets/db1/collections/dc2" ), "signer.sb1.signer_backend": "kinto_signer.signer.local_ecdsa", "signer.sb1.ecdsa.public_key": "/path/to/key", @@ -149,8 +149,8 @@ def test_defines_a_signer_per_bucket_and_collection(self): def test_falls_back_to_global_settings_if_not_defined(self): settings = { "signer.resources": ( - "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1\n" - "/buckets/sb1/collections/sc2;/buckets/db1/collections/dc2" + "/buckets/sb1/collections/sc1 -> /buckets/db1/collections/dc1\n" + "/buckets/sb1/collections/sc2 -> /buckets/db1/collections/dc2" ), "signer.signer_backend": "kinto_signer.signer.autograph", "signer.autograph.server_url": "http://localhost", @@ -175,7 +175,7 @@ def test_a_statsd_timer_is_used_for_signature_if_configured(self): settings = { "statsd_url": "udp://127.0.0.1:8125", "signer.resources": ( - "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1" + "/buckets/sb1/collections/sc1 -> /buckets/db1/collections/dc1" ), "signer.ecdsa.public_key": "/path/to/key", "signer.ecdsa.private_key": "/path/to/private", @@ -196,7 +196,7 @@ def test_a_statsd_timer_is_used_for_signature_if_configured(self): def test_includeme_raises_value_error_if_unknown_placeholder(self): settings = { - "signer.resources": "/buckets/sb1/collections/sc1;/buckets/db1/collections/dc1", + "signer.resources": "/buckets/sb1/collections/sc1 -> /buckets/db1/collections/dc1", "signer.editors_group": "{datetime}_group", "signer.ecdsa.public_key": "/path/to/key", "signer.ecdsa.private_key": "/path/to/private", @@ -215,14 +215,14 @@ def setUp(self): def test_nothing_happens_when_resource_is_not_configured(self): evt = mock.MagicMock(payload={"bucket_id": "a", "collection_id": "b"}) - sign_collection_data(evt, resources=utils.parse_resources("c/d;e/f")) + sign_collection_data(evt, resources=utils.parse_resources("c/d -> e/f")) assert not self.updater_mocked.called def test_nothing_happens_when_status_is_not_to_sign(self): evt = mock.MagicMock(payload={"bucket_id": "a", "collection_id": "b"}, impacted_records=[{ "new": {"id": "b", "status": "signed"}}]) - sign_collection_data(evt, resources=utils.parse_resources("a/b;c/d")) + sign_collection_data(evt, resources=utils.parse_resources("a/b -> c/d")) assert not self.updater_mocked.sign_and_update_destination.called def test_updater_is_called_when_resource_and_status_matches(self): @@ -235,7 +235,7 @@ def test_updater_is_called_when_resource_and_status_matches(self): "/buckets/a/collections/b": mock.sentinel.signer } evt.request.route_path.return_value = "/v1/buckets/a/collections/b" - sign_collection_data(evt, resources=utils.parse_resources("a/b;c/d")) + sign_collection_data(evt, resources=utils.parse_resources("a/b -> c/d")) self.updater_mocked.assert_called_with( signer=mock.sentinel.signer, storage=mock.sentinel.storage, @@ -256,13 +256,13 @@ def test_kinto_attachment_property_is_set_to_allow_metadata_updates(self): "/buckets/a/collections/b": mock.sentinel.signer } evt.request.route_path.return_value = "/v1/buckets/a/collections/b" - sign_collection_data(evt, resources=utils.parse_resources("a/b;c/d")) + sign_collection_data(evt, resources=utils.parse_resources("a/b -> c/d")) assert evt.request._attachment_auto_save is True def test_updater_does_not_fail_when_payload_is_inconsistent(self): # This happens with events on default bucket for kinto < 3.3 evt = mock.MagicMock(payload={"subpath": "collections/boom"}) - sign_collection_data(evt, resources=utils.parse_resources("a/b;c/d")) + sign_collection_data(evt, resources=utils.parse_resources("a/b -> c/d")) class BatchTest(BaseWebTest, unittest.TestCase): diff --git a/tests/test_signoff_flow.py b/tests/test_signoff_flow.py index 44e4b4d3..e9142f58 100644 --- a/tests/test_signoff_flow.py +++ b/tests/test_signoff_flow.py @@ -74,7 +74,7 @@ def get_app_settings(cls, extras=None): cls.destination_bucket = "/buckets/alice" cls.destination_collection = cls.destination_bucket + "/collections/dcid" - settings['kinto.signer.resources'] = '%s;%s' % ( + settings['kinto.signer.resources'] = '%s -> %s' % ( cls.source_collection, cls.destination_collection) return settings @@ -385,7 +385,7 @@ def get_app_settings(cls, extras=None): cls.source_collection1 = "/buckets/alice/collections/cid1" cls.source_collection2 = "/buckets/alice/collections/cid2" - settings['kinto.signer.resources'] = "%s;%s\n%s;%s" % ( + settings['kinto.signer.resources'] = "%s -> %s\n%s -> %s" % ( cls.source_collection1, cls.source_collection1.replace("alice", "destination"), cls.source_collection2, @@ -454,7 +454,7 @@ def get_app_settings(cls, extras=None): cls.preview_collection = cls.preview_bucket + "/collections/pcid" settings['signer.to_review_enabled'] = 'true' - settings['kinto.signer.resources'] = '%s;%s;%s' % ( + settings['kinto.signer.resources'] = '%s -> %s -> %s' % ( cls.source_collection, cls.preview_collection, cls.destination_collection) @@ -502,7 +502,7 @@ def get_app_settings(cls, extras=None): cls.destination_bucket = "/buckets/prod" cls.destination_collection = cls.destination_bucket + "/collections/cid" - settings['kinto.signer.resources'] = ';'.join([ + settings['kinto.signer.resources'] = ' -> '.join([ cls.source_bucket, cls.preview_bucket, cls.destination_bucket]) diff --git a/tests/test_utils.py b/tests/test_utils.py index 301cefaa..06c35fbf 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -8,41 +8,40 @@ class ParseResourcesTest(unittest.TestCase): - def test_missing_semicolumn_raises_an_exception(self): + def test_missing_arrow_raises_an_exception(self): raw_resources = """ - foo - bar + foo bar """ with pytest.raises(ConfigurationError): utils.parse_resources(raw_resources) def test_non_local_first_argument_raises_an_exception(self): raw_resources = """ - foo;bar - bar;baz + foo -> bar + bar -> baz """ with pytest.raises(ConfigurationError): utils.parse_resources(raw_resources) def test_malformed_url_raises_an_exception(self): raw_resources = """ - /buckets/sbid/scid;/buckets/dbid/collections/dcid + /buckets/sbid/scid -> /buckets/dbid/collections/dcid """ with pytest.raises(ConfigurationError): utils.parse_resources(raw_resources) def test_outnumbered_urls_raises_an_exception(self): raw_resources = ( - "/buckets/sbid/scid;" - "/buckets/dbid/collections/dcid;" - "/buckets/dbid/collections/dcid;" - "/buckets/sbid/scid;") + "/buckets/sbid/scid -> " + "/buckets/dbid/collections/dcid -> " + "/buckets/dbid/collections/dcid -> " + "/buckets/sbid/scid") with pytest.raises(ConfigurationError): utils.parse_resources(raw_resources) def test_returned_resources_match_the_expected_format(self): raw_resources = """ - /buckets/sbid/collections/scid;/buckets/dbid/collections/dcid + /buckets/sbid/collections/scid -> /buckets/dbid/collections/dcid """ resources = utils.parse_resources(raw_resources) assert resources == { @@ -60,7 +59,24 @@ def test_returned_resources_match_the_expected_format(self): def test_returned_resources_match_the_legacy_format(self): raw_resources = """ - sbid/scid;dbid/dcid + sbid/scid -> dbid/dcid + """ + resources = utils.parse_resources(raw_resources) + assert resources == { + '/buckets/sbid/collections/scid': { + 'source': { + 'bucket': 'sbid', + 'collection': 'scid' + }, + 'destination': { + 'bucket': 'dbid', + 'collection': 'dcid' + } + } + } + + raw_resources = """ + sbid/scid ; dbid/dcid """ resources = utils.parse_resources(raw_resources) assert resources == { @@ -78,8 +94,8 @@ def test_returned_resources_match_the_legacy_format(self): def test_spaces_are_supported(self): raw_resources = """ - /buckets/bid1/collections/scid1 ; /buckets/bid1/collections/dcid1 - /buckets/bid2/collections/scid2 ; /buckets/bid2/collections/dcid2 + /buckets/bid1/collections/scid1 -> /buckets/bid1/collections/dcid1 + /buckets/bid2/collections/scid2 -> /buckets/bid2/collections/dcid2 """ resources = utils.parse_resources(raw_resources) assert len(resources) == 2 @@ -88,17 +104,17 @@ def test_spaces_are_supported(self): def test_multiple_resources_are_supported(self): raw_resources = """ - /buckets/sbid1/collections/scid1;/buckets/dbid1/collections/dcid1 - /buckets/sbid2/collections/scid2;/buckets/dbid2/collections/dcid2 + /buckets/sbid1/collections/scid1 -> /buckets/dbid1/collections/dcid1 + /buckets/sbid2/collections/scid2 -> /buckets/dbid2/collections/dcid2 """ resources = utils.parse_resources(raw_resources) assert len(resources) == 2 def test_a_preview_collection_is_supported(self): raw_resources = ( - "/buckets/stage/collections/cid;" - "/buckets/preview/collections/cid;" - "/buckets/prod/collections/cid;" + "/buckets/stage/collections/cid -> " + "/buckets/preview/collections/cid -> " + "/buckets/prod/collections/cid -> " ) resources = utils.parse_resources(raw_resources) assert resources == { @@ -120,21 +136,21 @@ def test_a_preview_collection_is_supported(self): def test_resources_should_be_space_separated(self): raw_resources = ( - "/buckets/sbid1/collections/scid;/buckets/dbid1/collections/dcid," - "/buckets/sbid2/collections/scid;/buckets/dbid2/collections/dcid" + "/buckets/sbid1/collections/scid -> /buckets/dbid1/collections/dcid," + "/buckets/sbid2/collections/scid -> /buckets/dbid2/collections/dcid" ) with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) raw_resources = ( - "sbid1/scid;dbid1/dcid,sbid2/scid;dbid2/dcid" + "sbid1/scid -> dbid1/dcid,sbid2/scid -> dbid2/dcid" ) with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) def test_resources_must_be_valid_names(self): raw_resources = ( - "/buckets/sbi+d1/collections/scid;/buckets/dbid1/collections/dci,d" + "/buckets/sbi+d1/collections/scid -> /buckets/dbid1/collections/dci,d" ) with self.assertRaises(ConfigurationError) as e: utils.parse_resources(raw_resources) @@ -142,7 +158,7 @@ def test_resources_must_be_valid_names(self): 'bucket or collection id is invalid') def test_resources_can_be_defined_per_bucket(self): - raw_resources = "/buckets/stage;/buckets/preview;/buckets/prod" + raw_resources = "/buckets/stage -> /buckets/preview -> /buckets/prod" resources = utils.parse_resources(raw_resources) assert resources == { '/buckets/stage': { @@ -162,82 +178,82 @@ def test_resources_can_be_defined_per_bucket(self): } def test_cannot_mix_per_bucket_and_per_collection(self): - raw_resources = "/buckets/stage;/buckets/prod/collections/boom" + raw_resources = "/buckets/stage -> /buckets/prod/collections/boom" with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) - raw_resources = ("/buckets/stage/collections/boom;" - "/buckets/preview/collections/boom;" + raw_resources = ("/buckets/stage/collections/boom -> " + "/buckets/preview/collections/boom -> " "/buckets/prod") with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) - raw_resources = "/buckets/stage;/buckets/preview/collections/boom;/buckets/prod" + raw_resources = "/buckets/stage -> /buckets/preview/collections/boom -> /buckets/prod" with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) - raw_resources = "/buckets/stage/collections/boom;/buckets/prod" + raw_resources = "/buckets/stage/collections/boom -> /buckets/prod" with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) def test_cannot_repeat_source_preview_or_destination(self): - raw_resources = "/buckets/stage;/buckets/stage;/buckets/prod" + raw_resources = "/buckets/stage -> /buckets/stage -> /buckets/prod" with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) - raw_resources = "/buckets/stage;/buckets/preview;/buckets/stage" + raw_resources = "/buckets/stage -> /buckets/preview -> /buckets/stage" with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) - raw_resources = "/buckets/stage;/buckets/preview;/buckets/preview" + raw_resources = "/buckets/stage -> /buckets/preview -> /buckets/preview" with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) def test_cannot_repeat_resources(self): # Repeated source. raw_resources = """ - /buckets/stage;/buckets/preview1;/buckets/prod1 - /buckets/stage;/buckets/preview2;/buckets/prod2 + /buckets/stage -> /buckets/preview1 -> /buckets/prod1 + /buckets/stage -> /buckets/preview2 -> /buckets/prod2 """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) # Repeated reviews. raw_resources = """ - /buckets/stage1;/buckets/preview;/buckets/prod1 - /buckets/stage2;/buckets/preview;/buckets/prod2 + /buckets/stage1 -> /buckets/preview -> /buckets/prod1 + /buckets/stage2 -> /buckets/preview -> /buckets/prod2 """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) # Repeated destination. raw_resources = """ - /buckets/stage1;/buckets/prod - /buckets/stage2;/buckets/preview;/buckets/prod + /buckets/stage1 -> /buckets/prod + /buckets/stage2 -> /buckets/preview -> /buckets/prod """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) # Source in other's preview. raw_resources = """ - /buckets/stage;/buckets/preview;/buckets/prod - /buckets/bid1 ;/buckets/stage ;/buckets/bid2 + /buckets/stage -> /buckets/preview -> /buckets/prod + /buckets/bid1 -> /buckets/stage -> /buckets/bid2 """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) # Source in other's destination. raw_resources = """ - /buckets/bid/collections/cid ;/buckets/bid/collections/cid2;/buckets/bid/collections/cid3 - /buckets/bid/collections/cida;/buckets/bid/collections/cidb;/buckets/bid/collections/cid + /buckets/b/collections/c -> /buckets/b/collections/c2 -> /buckets/b/collections/c3 + /buckets/b/collections/ca -> /buckets/b/collections/cb -> /buckets/b/collections/c """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) # Preview in other's destination. raw_resources = """ - /buckets/bid/collections/cid0;/buckets/bid/collections/cid1;/buckets/bid/collections/cid2 - /buckets/bid/collections/cida;/buckets/bid/collections/cidb;/buckets/bid/collections/cid1 + /buckets/b/collections/c0 -> /buckets/b/collections/c1 -> /buckets/b/collections/c2 + /buckets/b/collections/ca -> /buckets/b/collections/cb -> /buckets/b/collections/c1 """ with self.assertRaises(ConfigurationError): utils.parse_resources(raw_resources) From 44b237319811ae8308e227b3234286743151ecbf Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Mon, 5 Mar 2018 16:47:16 +0100 Subject: [PATCH 3/3] leftover --- kinto_signer/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kinto_signer/utils.py b/kinto_signer/utils.py index 598cf472..a2fded00 100644 --- a/kinto_signer/utils.py +++ b/kinto_signer/utils.py @@ -57,7 +57,7 @@ def parse_resources(raw_resources): for res in lines: error_msg = "Malformed resource: %%s (in %r). See kinto-signer README." % res if "->" not in res and ";" not in res: - raise ConfigurationError(error_msg % "not separated with ';'") + raise ConfigurationError(error_msg % "not separated with '->'") try: triplet = [r.strip()