From 7470bc8db6264da74cbd2d6ebd4969bc32d4366f Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Sun, 5 Jul 2015 08:31:48 +0000 Subject: [PATCH 1/2] RegistrationResource: return any phone/email from phones/emails or None. --- acme/messages.py | 24 ++++++++++++++++++------ acme/messages_test.py | 7 +++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/acme/messages.py b/acme/messages.py index c224e9bde..4d82a7723 100644 --- a/acme/messages.py +++ b/acme/messages.py @@ -182,15 +182,27 @@ class Registration(ResourceBody): @property def phone(self): - """Phone.""" - assert len(self.phones) == 1 - return self.phones[0] + """Phone. + + Picks any phone from `phones` or ``None`` if not available. + + """ + try: + return self.phones[0] + except IndexError: + return None @property def email(self): - """Email.""" - assert len(self.emails) == 1 - return self.emails[0] + """Email. + + Picks any email from `emails` or ``None`` if not available. + + """ + try: + return self.emails[0] + except IndexError: + return None class RegistrationResource(ResourceWithURI): diff --git a/acme/messages_test.py b/acme/messages_test.py index 59b1685dc..4f99b538d 100644 --- a/acme/messages_test.py +++ b/acme/messages_test.py @@ -122,6 +122,7 @@ class RegistrationTest(unittest.TestCase): self.reg = Registration( key=key, contact=contact, recovery_token=recovery_token, agreement=agreement) + self.reg_none = Registration() self.jobj_to = { 'contact': contact, @@ -149,9 +150,15 @@ class RegistrationTest(unittest.TestCase): def test_phone(self): self.assertEqual('1234', self.reg.phone) + def test_phone_none(self): + self.assertTrue(self.reg_none.phone is None) + def test_email(self): self.assertEqual('admin@foo.com', self.reg.email) + def test_email_none(self): + self.assertTrue(self.reg_none.email is None) + def test_to_partial_json(self): self.assertEqual(self.jobj_to, self.reg.to_partial_json()) From 0d087788da53f4a118930ff365875e11ee914293 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Sat, 4 Jul 2015 06:22:11 +0000 Subject: [PATCH 2/2] Accept new_reg in acme.client.Client.register. --- acme/client.py | 9 ++++----- acme/client_test.py | 4 ++-- examples/acme_client.py | 2 +- letsencrypt/network.py | 9 +++------ letsencrypt/tests/network_test.py | 13 ++++++++----- 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/acme/client.py b/acme/client.py index 67d4f1a69..064bd8cd2 100644 --- a/acme/client.py +++ b/acme/client.py @@ -64,8 +64,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes new_authzr_uri=new_authzr_uri, terms_of_service=terms_of_service) - def register(self, contact=messages.Registration._fields[ - 'contact'].default): + def register(self, new_reg=None): """Register. :param contact: Contact list, as accepted by `.Registration` @@ -77,14 +76,14 @@ class Client(object): # pylint: disable=too-many-instance-attributes :raises .UnexpectedUpdate: """ - new_reg = messages.Registration(contact=contact) + new_reg = messages.Registration() if new_reg is None else new_reg response = self.net.post(self.new_reg_uri, new_reg) assert response.status_code == httplib.CREATED # TODO: handle errors regr = self._regr_from_response(response) - if (regr.body.key != self.key.public_key() - or regr.body.contact != contact): + if (regr.body.key != self.key.public_key() or + regr.body.contact != new_reg.contact): raise errors.UnexpectedUpdate(regr) return regr diff --git a/acme/client_test.py b/acme/client_test.py index b25a1866c..bbed2ed87 100644 --- a/acme/client_test.py +++ b/acme/client_test.py @@ -82,14 +82,14 @@ class ClientTest(unittest.TestCase): 'terms-of-service': {'url': self.regr.terms_of_service}, }) - self.assertEqual(self.regr, self.client.register(self.contact)) + self.assertEqual(self.regr, self.client.register(self.regr.body)) # TODO: test POST call arguments # TODO: split here and separate test reg_wrong_key = self.regr.body.update(key=KEY2.public_key()) self.response.json.return_value = reg_wrong_key.to_json() self.assertRaises( - errors.UnexpectedUpdate, self.client.register, self.contact) + errors.UnexpectedUpdate, self.client.register, self.regr.body) def test_register_missing_next(self): self.response.status_code = httplib.CREATED diff --git a/examples/acme_client.py b/examples/acme_client.py index e07031fbe..0d906d539 100644 --- a/examples/acme_client.py +++ b/examples/acme_client.py @@ -26,7 +26,7 @@ key = jose.JWKRSA(key=rsa.generate_private_key( backend=default_backend())) acme = client.Client(NEW_REG_URL, key) -regr = acme.register(contact=()) +regr = acme.register() logging.info('Auto-accepting TOS: %s', regr.terms_of_service) acme.update_registration(regr.update( body=regr.body.update(agreement=regr.terms_of_service))) diff --git a/letsencrypt/network.py b/letsencrypt/network.py index 0f4d9d29b..a890c94e2 100644 --- a/letsencrypt/network.py +++ b/letsencrypt/network.py @@ -1,5 +1,6 @@ """Networking for ACME protocol.""" from acme import client +from acme import messages class Network(client.Client): @@ -17,10 +18,6 @@ class Network(client.Client): :rtype: :class:`letsencrypt.account.Account` """ - details = ( - "mailto:" + account.email if account.email is not None else None, - "tel:" + account.phone if account.phone is not None else None, - ) - account.regr = self.register(contact=tuple( - det for det in details if det is not None)) + account.regr = self.register(messages.Registration.from_data( + email=account.email, phone=account.phone)) return account diff --git a/letsencrypt/tests/network_test.py b/letsencrypt/tests/network_test.py index 6acb11315..aed681871 100644 --- a/letsencrypt/tests/network_test.py +++ b/letsencrypt/tests/network_test.py @@ -5,6 +5,7 @@ import unittest import mock +from acme import messages from letsencrypt import account @@ -17,7 +18,6 @@ class NetworkTest(unittest.TestCase): new_reg_uri=None, key=None, alg=None, verify_ssl=None) self.config = mock.Mock(accounts_dir=tempfile.mkdtemp()) - self.contact = ('mailto:cert-admin@example.com', 'tel:+12025551212') def tearDown(self): shutil.rmtree(self.config.accounts_dir) @@ -30,7 +30,10 @@ class NetworkTest(unittest.TestCase): self.net.register_from_account(acc) - self.net.register.assert_called_with(contact=self.contact) + self.net.register.assert_called_once() + self.assertEqual( + set(self.net.register.mock_calls[0][1][0].contact), + set(('mailto:cert-admin@example.com', 'tel:+12025551212'))) def test_register_from_account_partial_info(self): self.net.register = mock.Mock() @@ -39,11 +42,11 @@ class NetworkTest(unittest.TestCase): acc2 = account.Account(self.config, 'key') self.net.register_from_account(acc) - self.net.register.assert_called_with( - contact=('mailto:cert-admin@example.com',)) + self.net.register.assert_called_with(messages.Registration( + contact=('mailto:cert-admin@example.com',))) self.net.register_from_account(acc2) - self.net.register.assert_called_with(contact=()) + self.net.register.assert_called_with(messages.Registration()) if __name__ == '__main__':