Ejemplo n.º 1
0
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
        authorizations have "valid" status.
    :ivar datetime.datetime expires: When the order expires.
    :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)
    expires = fields.RFC3339Field('expires', omitempty=True)
    error = jose.Field('error', omitempty=True, decoder=Error.from_json)

    @identifiers.decoder
    def identifiers(value):  # pylint: disable=missing-docstring,no-self-argument
        return tuple(Identifier.from_json(identifier) for identifier in value)
Ejemplo n.º 2
0
class ChallengeBody(ResourceBody):
    """Challenge Resource Body.

    .. todo::
       Confusingly, this has a similar name to `.challenges.Challenge`,
       as well as `.achallenges.AnnotatedChallenge`. Please use names
       such as ``challb`` to distinguish instances of this class from
       ``achall``.

    :ivar acme.challenges.Challenge: Wrapped challenge.
        Conveniently, all challenge fields are proxied, i.e. you can
        call ``challb.x`` to get ``challb.chall.x`` contents.
    :ivar acme.messages.Status status:
    :ivar datetime.datetime validated:
    :ivar messages.Error error:

    """
    __slots__ = ('chall', )
    # ACMEv1 has a "uri" field in challenges. ACMEv2 has a "url" field. This
    # challenge object supports either one, but should be accessed through the
    # name "uri". In Client.answer_challenge, whichever one is set will be
    # used.
    _uri = jose.Field('uri', omitempty=True, default=None)
    _url = jose.Field('url', omitempty=True, default=None)
    status = jose.Field('status',
                        decoder=Status.from_json,
                        omitempty=True,
                        default=STATUS_PENDING)
    validated = fields.RFC3339Field('validated', omitempty=True)
    error = jose.Field('error',
                       decoder=Error.from_json,
                       omitempty=True,
                       default=None)

    def __init__(self, **kwargs):
        kwargs = dict((self._internal_name(k), v) for k, v in kwargs.items())
        super(ChallengeBody, self).__init__(**kwargs)

    def encode(self, name):
        return super(ChallengeBody, self).encode(self._internal_name(name))

    def to_partial_json(self):
        jobj = super(ChallengeBody, self).to_partial_json()
        jobj.update(self.chall.to_partial_json())
        return jobj

    @classmethod
    def fields_from_json(cls, jobj):
        jobj_fields = super(ChallengeBody, cls).fields_from_json(jobj)
        jobj_fields['chall'] = challenges.Challenge.from_json(jobj)
        return jobj_fields

    @property
    def uri(self):
        """The URL of this challenge."""
        return self._url or self._uri

    def __getattr__(self, name):
        return getattr(self.chall, name)

    def __iter__(self):
        # When iterating over fields, use the external name 'uri' instead of
        # the internal '_uri'.
        for name in super(ChallengeBody, self).__iter__():
            yield name[1:] if name == '_uri' else name

    def _internal_name(self, name):
        return '_' + name if name == 'uri' else name