From d19698251da19f363d94ece9e5ee9dcc425afad2 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Tue, 31 Jul 2018 17:08:39 +0300 Subject: [PATCH 1/8] Do not send status or resource fields in newOrder payloads for ACMEv2 --- acme/acme/client.py | 4 ++-- acme/acme/messages.py | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/acme/acme/client.py b/acme/acme/client.py index bd86657b9..60a67a038 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -646,7 +646,7 @@ class ClientV2(ClientBase): value=name)) order = messages.NewOrder(identifiers=identifiers) response = self._post(self.directory['newOrder'], order) - body = messages.Order.from_json(response.json()) + body = messages.OrderBase.from_json(response.json()) authorizations = [] for url in body.authorizations: authorizations.append(self._authzr_from_response(self.net.get(url), uri=url)) @@ -715,7 +715,7 @@ class ClientV2(ClientBase): while datetime.datetime.now() < deadline: time.sleep(1) response = self.net.get(orderr.uri) - body = messages.Order.from_json(response.json()) + body = messages.OrderBase.from_json(response.json()) if body.error is not None: raise errors.IssuanceError(body.error) if body.certificate is not None: diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 5be458580..86585ccb9 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -509,11 +509,10 @@ class Revocation(jose.JSONObjectWithFields): reason = jose.Field('reason') -class Order(ResourceBody): +class OrderBase(ResourceBody): """Order Resource Body. :ivar list of .Identifier: List of identifiers for the certificate. - :ivar acme.messages.Status status: :ivar list of str authorizations: URLs of authorizations. :ivar str certificate: URL to download certificate as a fullchain PEM. :ivar str finalize: URL to POST to to request issuance once all @@ -522,8 +521,6 @@ class Order(ResourceBody): :ivar .Error error: Any error that occurred during finalization, if applicable. """ identifiers = jose.Field('identifiers', omitempty=True) - status = jose.Field('status', decoder=Status.from_json, - omitempty=True, default=STATUS_PENDING) authorizations = jose.Field('authorizations', omitempty=True) certificate = jose.Field('certificate', omitempty=True) finalize = jose.Field('finalize', omitempty=True) @@ -534,6 +531,16 @@ class Order(ResourceBody): def identifiers(value): # pylint: disable=missing-docstring,no-self-argument return tuple(Identifier.from_json(identifier) for identifier in value) + +class Order(OrderBase): + """Order Resource Body for ACMEv1 + + :ivar acme.messages.Status status: + """ + status = jose.Field('status', decoder=Status.from_json, + omitempty=True, default=STATUS_PENDING) + + class OrderResource(ResourceWithURI): """Order Resource. @@ -549,8 +556,8 @@ class OrderResource(ResourceWithURI): authorizations = jose.Field('authorizations') fullchain_pem = jose.Field('fullchain_pem', omitempty=True) + @Directory.register -class NewOrder(Order): - """New order.""" - resource_type = 'new-order' - resource = fields.Resource(resource_type) +class NewOrder(OrderBase): + """New order for ACMEv2""" + resource_type = "new-order" From 8b3629ebd49b647967dde9e279ad252583f6b881 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Tue, 31 Jul 2018 19:55:19 +0300 Subject: [PATCH 2/8] Fix tests --- acme/acme/client_test.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index 4f8a1abe2..3cdcdf041 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -695,9 +695,8 @@ class ClientV2Test(ClientTestBase): self.authzr2 = messages.AuthorizationResource( body=self.authz2, uri=self.authzr_uri2) - self.order = messages.Order( + self.order = messages.OrderBase( identifiers=(self.authz.identifier, self.authz2.identifier), - status=messages.STATUS_PENDING, authorizations=(self.authzr.uri, self.authzr_uri2), finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize') self.orderr = messages.OrderResource( From c131f4211de987cdd7738a90c091fb25dce54351 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Wed, 1 Aug 2018 12:10:01 +0300 Subject: [PATCH 3/8] Revert "Fix tests" This reverts commit 8b3629ebd49b647967dde9e279ad252583f6b881. --- acme/acme/client_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index 3cdcdf041..4f8a1abe2 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -695,8 +695,9 @@ class ClientV2Test(ClientTestBase): self.authzr2 = messages.AuthorizationResource( body=self.authz2, uri=self.authzr_uri2) - self.order = messages.OrderBase( + self.order = messages.Order( identifiers=(self.authz.identifier, self.authz2.identifier), + status=messages.STATUS_PENDING, authorizations=(self.authzr.uri, self.authzr_uri2), finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize') self.orderr = messages.OrderResource( From b1b46508045d90715e3043ad9e373ba43edf9a8f Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Wed, 1 Aug 2018 12:10:55 +0300 Subject: [PATCH 4/8] Revert "Do not send status or resource fields in newOrder payloads for ACMEv2" This reverts commit d19698251da19f363d94ece9e5ee9dcc425afad2. --- acme/acme/client.py | 4 ++-- acme/acme/messages.py | 23 ++++++++--------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/acme/acme/client.py b/acme/acme/client.py index 60a67a038..bd86657b9 100644 --- a/acme/acme/client.py +++ b/acme/acme/client.py @@ -646,7 +646,7 @@ class ClientV2(ClientBase): value=name)) order = messages.NewOrder(identifiers=identifiers) response = self._post(self.directory['newOrder'], order) - body = messages.OrderBase.from_json(response.json()) + body = messages.Order.from_json(response.json()) authorizations = [] for url in body.authorizations: authorizations.append(self._authzr_from_response(self.net.get(url), uri=url)) @@ -715,7 +715,7 @@ class ClientV2(ClientBase): while datetime.datetime.now() < deadline: time.sleep(1) response = self.net.get(orderr.uri) - body = messages.OrderBase.from_json(response.json()) + body = messages.Order.from_json(response.json()) if body.error is not None: raise errors.IssuanceError(body.error) if body.certificate is not None: diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 86585ccb9..5be458580 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -509,10 +509,11 @@ class Revocation(jose.JSONObjectWithFields): reason = jose.Field('reason') -class OrderBase(ResourceBody): +class Order(ResourceBody): """Order Resource Body. :ivar list of .Identifier: List of identifiers for the certificate. + :ivar acme.messages.Status status: :ivar list of str authorizations: URLs of authorizations. :ivar str certificate: URL to download certificate as a fullchain PEM. :ivar str finalize: URL to POST to to request issuance once all @@ -521,6 +522,8 @@ class OrderBase(ResourceBody): :ivar .Error error: Any error that occurred during finalization, if applicable. """ identifiers = jose.Field('identifiers', omitempty=True) + status = jose.Field('status', decoder=Status.from_json, + omitempty=True, default=STATUS_PENDING) authorizations = jose.Field('authorizations', omitempty=True) certificate = jose.Field('certificate', omitempty=True) finalize = jose.Field('finalize', omitempty=True) @@ -531,16 +534,6 @@ class OrderBase(ResourceBody): def identifiers(value): # pylint: disable=missing-docstring,no-self-argument return tuple(Identifier.from_json(identifier) for identifier in value) - -class Order(OrderBase): - """Order Resource Body for ACMEv1 - - :ivar acme.messages.Status status: - """ - status = jose.Field('status', decoder=Status.from_json, - omitempty=True, default=STATUS_PENDING) - - class OrderResource(ResourceWithURI): """Order Resource. @@ -556,8 +549,8 @@ class OrderResource(ResourceWithURI): authorizations = jose.Field('authorizations') fullchain_pem = jose.Field('fullchain_pem', omitempty=True) - @Directory.register -class NewOrder(OrderBase): - """New order for ACMEv2""" - resource_type = "new-order" +class NewOrder(Order): + """New order.""" + resource_type = 'new-order' + resource = fields.Resource(resource_type) From 8943dffe0d804eba8da99a77c5b8b4b72cce8991 Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Wed, 1 Aug 2018 12:17:23 +0300 Subject: [PATCH 5/8] Removed status and resource fields from NewOrder object --- acme/acme/client_test.py | 1 - acme/acme/messages.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index 4f8a1abe2..965ece55d 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -697,7 +697,6 @@ class ClientV2Test(ClientTestBase): self.order = messages.Order( identifiers=(self.authz.identifier, self.authz2.identifier), - status=messages.STATUS_PENDING, authorizations=(self.authzr.uri, self.authzr_uri2), finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize') self.orderr = messages.OrderResource( diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 5be458580..405fe7d9a 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -513,7 +513,6 @@ class Order(ResourceBody): """Order Resource Body. :ivar list of .Identifier: List of identifiers for the certificate. - :ivar acme.messages.Status status: :ivar list of str authorizations: URLs of authorizations. :ivar str certificate: URL to download certificate as a fullchain PEM. :ivar str finalize: URL to POST to to request issuance once all @@ -522,8 +521,6 @@ class Order(ResourceBody): :ivar .Error error: Any error that occurred during finalization, if applicable. """ identifiers = jose.Field('identifiers', omitempty=True) - status = jose.Field('status', decoder=Status.from_json, - omitempty=True, default=STATUS_PENDING) authorizations = jose.Field('authorizations', omitempty=True) certificate = jose.Field('certificate', omitempty=True) finalize = jose.Field('finalize', omitempty=True) @@ -553,4 +550,3 @@ class OrderResource(ResourceWithURI): class NewOrder(Order): """New order.""" resource_type = 'new-order' - resource = fields.Resource(resource_type) From a3a3840e91d4ee086dd183400cbcd39ebd307938 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Thu, 18 Oct 2018 10:19:57 -0700 Subject: [PATCH 6/8] replace status field --- acme/acme/client_test.py | 1 + acme/acme/messages.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index 965ece55d..4f8a1abe2 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -697,6 +697,7 @@ class ClientV2Test(ClientTestBase): self.order = messages.Order( identifiers=(self.authz.identifier, self.authz2.identifier), + status=messages.STATUS_PENDING, authorizations=(self.authzr.uri, self.authzr_uri2), finalize='https://www.letsencrypt-demo.org/acme/acct/1/order/1/finalize') self.orderr = messages.OrderResource( diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 405fe7d9a..df295bf2b 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -513,6 +513,7 @@ class Order(ResourceBody): """Order Resource Body. :ivar list of .Identifier: List of identifiers for the certificate. + :ivar acme.messages.Status status: :ivar list of str authorizations: URLs of authorizations. :ivar str certificate: URL to download certificate as a fullchain PEM. :ivar str finalize: URL to POST to to request issuance once all @@ -521,6 +522,8 @@ class Order(ResourceBody): :ivar .Error error: Any error that occurred during finalization, if applicable. """ identifiers = jose.Field('identifiers', omitempty=True) + status = jose.Field('status', decoder=Status.from_json, + omitempty=True, default=STATUS_PENDING) authorizations = jose.Field('authorizations', omitempty=True) certificate = jose.Field('certificate', omitempty=True) finalize = jose.Field('finalize', omitempty=True) From ee02ed65afe907a767e18b1536b5cde806a2cdd6 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Thu, 18 Oct 2018 10:26:37 -0700 Subject: [PATCH 7/8] remove default status from Order so that the status field isn't filled in upon boulder deserialization --- acme/acme/messages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme/acme/messages.py b/acme/acme/messages.py index df295bf2b..7e86b0c3b 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -523,7 +523,7 @@ class Order(ResourceBody): """ identifiers = jose.Field('identifiers', omitempty=True) status = jose.Field('status', decoder=Status.from_json, - omitempty=True, default=STATUS_PENDING) + omitempty=True) authorizations = jose.Field('authorizations', omitempty=True) certificate = jose.Field('certificate', omitempty=True) finalize = jose.Field('finalize', omitempty=True) From 6500b9095e4e7b4d7b02cb39d7c78d322339dd11 Mon Sep 17 00:00:00 2001 From: Erica Portnoy Date: Thu, 18 Oct 2018 10:37:56 -0700 Subject: [PATCH 8/8] Add test to confirm that status isn't set on neworder object --- acme/acme/messages_test.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/acme/acme/messages_test.py b/acme/acme/messages_test.py index 0e2d8c62d..876fbe825 100644 --- a/acme/acme/messages_test.py +++ b/acme/acme/messages_test.py @@ -424,6 +424,19 @@ class OrderResourceTest(unittest.TestCase): 'authorizations': None, }) +class NewOrderTest(unittest.TestCase): + """Tests for acme.messages.NewOrder.""" + + def setUp(self): + from acme.messages import NewOrder + self.reg = NewOrder( + identifiers=mock.sentinel.identifiers) + + def test_to_partial_json(self): + self.assertEqual(self.reg.to_json(), { + 'identifiers': mock.sentinel.identifiers, + }) + if __name__ == '__main__': unittest.main() # pragma: no cover