mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 13:59:02 -04:00
acme.messages.OrderResource: Make roundtrippable through JSON (#9617)
Right now if you to_json() an `OrderResource` and later deserialize it, the `AuthorizationResource` objects don't come back through the round-trip (they just get de-jsonified as frozendicts and worse, they can't even be passed to `AuthorizationResource.from_json` because frozendicts aren't dicts). In addition, the `csr_pem` field gets encoded as an array of integers, which definitely does not get de-jsonified into what we want. Fix these by adding an encoder to `authorizations` and encoder and decoder to `csr_pem`.
This commit is contained in:
parent
c07b5efb7f
commit
5d5dc429c4
4 changed files with 50 additions and 2 deletions
|
|
@ -23,6 +23,7 @@ Authors
|
|||
* [amplifi](https://github.com/amplifi)
|
||||
* [Andrew Murray](https://github.com/radarhere)
|
||||
* [Andrzej Górski](https://github.com/andrzej3393)
|
||||
* [Anna Glasgall](https://github.com/aglasgall)
|
||||
* [Anselm Levskaya](https://github.com/levskaya)
|
||||
* [Antoine Jacoutot](https://github.com/ajacoutot)
|
||||
* [April King](https://github.com/april)
|
||||
|
|
|
|||
|
|
@ -654,12 +654,28 @@ class OrderResource(ResourceWithURI):
|
|||
:vartype alternative_fullchains_pem: `list` of `str`
|
||||
"""
|
||||
body: Order = jose.field('body', decoder=Order.from_json)
|
||||
csr_pem: bytes = jose.field('csr_pem', omitempty=True)
|
||||
csr_pem: bytes = jose.field('csr_pem', omitempty=True,
|
||||
# This looks backwards, but it's not -
|
||||
# we want the deserialized value to be
|
||||
# `bytes`, but anything we put into
|
||||
# JSON needs to be `str`, so we encode
|
||||
# to decode and decode to
|
||||
# encode. Otherwise we end up with an
|
||||
# array of ints on serialization
|
||||
decoder=lambda s: s.encode("utf-8"),
|
||||
encoder=lambda b: b.decode("utf-8"))
|
||||
|
||||
authorizations: List[AuthorizationResource] = jose.field('authorizations')
|
||||
fullchain_pem: str = jose.field('fullchain_pem', omitempty=True)
|
||||
alternative_fullchains_pem: List[str] = jose.field('alternative_fullchains_pem',
|
||||
omitempty=True)
|
||||
|
||||
# Mypy does not understand the josepy magic happening here, and falsely claims
|
||||
# that authorizations is redefined. Let's ignore the type check here.
|
||||
@authorizations.decoder # type: ignore
|
||||
def authorizations(value: List[Dict[str, Any]]) -> Tuple[AuthorizationResource, ...]: # pylint: disable=no-self-argument,missing-function-docstring
|
||||
return tuple(AuthorizationResource.from_json(authz) for authz in value)
|
||||
|
||||
|
||||
class NewOrder(Order):
|
||||
"""New order."""
|
||||
|
|
|
|||
|
|
@ -492,6 +492,36 @@ class OrderResourceTest(unittest.TestCase):
|
|||
'authorizations': None,
|
||||
}
|
||||
|
||||
def test_json_de_serializable(self):
|
||||
from acme.messages import ChallengeBody
|
||||
from acme.messages import STATUS_PENDING
|
||||
challbs = (
|
||||
ChallengeBody(
|
||||
uri='http://challb1', status=STATUS_PENDING,
|
||||
chall=challenges.HTTP01(token=b'IlirfxKKXAsHtmzK29Pj8A')),
|
||||
ChallengeBody(uri='http://challb2', status=STATUS_PENDING,
|
||||
chall=challenges.DNS(
|
||||
token=b'DGyRejmCefe7v4NfDGDKfA')),
|
||||
)
|
||||
|
||||
from acme.messages import Authorization
|
||||
from acme.messages import AuthorizationResource
|
||||
from acme.messages import Identifier
|
||||
from acme.messages import IDENTIFIER_FQDN
|
||||
identifier = Identifier(typ=IDENTIFIER_FQDN, value='example.com')
|
||||
authz = AuthorizationResource(uri="http://authz1",
|
||||
body=Authorization(
|
||||
identifier=identifier,
|
||||
challenges=challbs))
|
||||
from acme.messages import Order
|
||||
body = Order(identifiers=(identifier,), status=STATUS_PENDING,
|
||||
authorizations=tuple(challb.uri for challb in challbs))
|
||||
from acme.messages import OrderResource
|
||||
orderr = OrderResource(uri="http://order1", body=body,
|
||||
csr_pem=b'test blob',
|
||||
authorizations=(authz,))
|
||||
self.assertEqual(orderr,
|
||||
OrderResource.from_json(orderr.to_json()))
|
||||
|
||||
class NewOrderTest(unittest.TestCase):
|
||||
"""Tests for acme.messages.NewOrder."""
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/).
|
|||
|
||||
### Added
|
||||
|
||||
*
|
||||
* `acme.messages.OrderResource` now supports being round-tripped
|
||||
through JSON
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue