Merge pull request #592 from kuba/acme-reg

acme: registration improvements
This commit is contained in:
James Kasten
2015-07-08 13:53:20 -07:00
7 changed files with 43 additions and 25 deletions
+4 -5
View File
@@ -64,8 +64,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes
new_authzr_uri=new_authzr_uri, new_authzr_uri=new_authzr_uri,
terms_of_service=terms_of_service) terms_of_service=terms_of_service)
def register(self, contact=messages.Registration._fields[ def register(self, new_reg=None):
'contact'].default):
"""Register. """Register.
:param contact: Contact list, as accepted by `.Registration` :param contact: Contact list, as accepted by `.Registration`
@@ -77,14 +76,14 @@ class Client(object): # pylint: disable=too-many-instance-attributes
:raises .UnexpectedUpdate: :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) response = self.net.post(self.new_reg_uri, new_reg)
assert response.status_code == httplib.CREATED # TODO: handle errors assert response.status_code == httplib.CREATED # TODO: handle errors
regr = self._regr_from_response(response) regr = self._regr_from_response(response)
if (regr.body.key != self.key.public_key() if (regr.body.key != self.key.public_key() or
or regr.body.contact != contact): regr.body.contact != new_reg.contact):
raise errors.UnexpectedUpdate(regr) raise errors.UnexpectedUpdate(regr)
return regr return regr
+2 -2
View File
@@ -82,14 +82,14 @@ class ClientTest(unittest.TestCase):
'terms-of-service': {'url': self.regr.terms_of_service}, '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: test POST call arguments
# TODO: split here and separate test # TODO: split here and separate test
reg_wrong_key = self.regr.body.update(key=KEY2.public_key()) reg_wrong_key = self.regr.body.update(key=KEY2.public_key())
self.response.json.return_value = reg_wrong_key.to_json() self.response.json.return_value = reg_wrong_key.to_json()
self.assertRaises( self.assertRaises(
errors.UnexpectedUpdate, self.client.register, self.contact) errors.UnexpectedUpdate, self.client.register, self.regr.body)
def test_register_missing_next(self): def test_register_missing_next(self):
self.response.status_code = httplib.CREATED self.response.status_code = httplib.CREATED
+18 -6
View File
@@ -182,15 +182,27 @@ class Registration(ResourceBody):
@property @property
def phone(self): def phone(self):
"""Phone.""" """Phone.
assert len(self.phones) == 1
return self.phones[0] Picks any phone from `phones` or ``None`` if not available.
"""
try:
return self.phones[0]
except IndexError:
return None
@property @property
def email(self): def email(self):
"""Email.""" """Email.
assert len(self.emails) == 1
return self.emails[0] Picks any email from `emails` or ``None`` if not available.
"""
try:
return self.emails[0]
except IndexError:
return None
class RegistrationResource(ResourceWithURI): class RegistrationResource(ResourceWithURI):
+7
View File
@@ -122,6 +122,7 @@ class RegistrationTest(unittest.TestCase):
self.reg = Registration( self.reg = Registration(
key=key, contact=contact, recovery_token=recovery_token, key=key, contact=contact, recovery_token=recovery_token,
agreement=agreement) agreement=agreement)
self.reg_none = Registration()
self.jobj_to = { self.jobj_to = {
'contact': contact, 'contact': contact,
@@ -149,9 +150,15 @@ class RegistrationTest(unittest.TestCase):
def test_phone(self): def test_phone(self):
self.assertEqual('1234', self.reg.phone) self.assertEqual('1234', self.reg.phone)
def test_phone_none(self):
self.assertTrue(self.reg_none.phone is None)
def test_email(self): def test_email(self):
self.assertEqual('admin@foo.com', self.reg.email) 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): def test_to_partial_json(self):
self.assertEqual(self.jobj_to, self.reg.to_partial_json()) self.assertEqual(self.jobj_to, self.reg.to_partial_json())
+1 -1
View File
@@ -26,7 +26,7 @@ key = jose.JWKRSA(key=rsa.generate_private_key(
backend=default_backend())) backend=default_backend()))
acme = client.Client(NEW_REG_URL, key) acme = client.Client(NEW_REG_URL, key)
regr = acme.register(contact=()) regr = acme.register()
logging.info('Auto-accepting TOS: %s', regr.terms_of_service) logging.info('Auto-accepting TOS: %s', regr.terms_of_service)
acme.update_registration(regr.update( acme.update_registration(regr.update(
body=regr.body.update(agreement=regr.terms_of_service))) body=regr.body.update(agreement=regr.terms_of_service)))
+3 -6
View File
@@ -1,5 +1,6 @@
"""Networking for ACME protocol.""" """Networking for ACME protocol."""
from acme import client from acme import client
from acme import messages
class Network(client.Client): class Network(client.Client):
@@ -17,10 +18,6 @@ class Network(client.Client):
:rtype: :class:`letsencrypt.account.Account` :rtype: :class:`letsencrypt.account.Account`
""" """
details = ( account.regr = self.register(messages.Registration.from_data(
"mailto:" + account.email if account.email is not None else None, email=account.email, phone=account.phone))
"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))
return account return account
+8 -5
View File
@@ -5,6 +5,7 @@ import unittest
import mock import mock
from acme import messages
from letsencrypt import account from letsencrypt import account
@@ -17,7 +18,6 @@ class NetworkTest(unittest.TestCase):
new_reg_uri=None, key=None, alg=None, verify_ssl=None) new_reg_uri=None, key=None, alg=None, verify_ssl=None)
self.config = mock.Mock(accounts_dir=tempfile.mkdtemp()) self.config = mock.Mock(accounts_dir=tempfile.mkdtemp())
self.contact = ('mailto:cert-admin@example.com', 'tel:+12025551212')
def tearDown(self): def tearDown(self):
shutil.rmtree(self.config.accounts_dir) shutil.rmtree(self.config.accounts_dir)
@@ -30,7 +30,10 @@ class NetworkTest(unittest.TestCase):
self.net.register_from_account(acc) 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): def test_register_from_account_partial_info(self):
self.net.register = mock.Mock() self.net.register = mock.Mock()
@@ -39,11 +42,11 @@ class NetworkTest(unittest.TestCase):
acc2 = account.Account(self.config, 'key') acc2 = account.Account(self.config, 'key')
self.net.register_from_account(acc) self.net.register_from_account(acc)
self.net.register.assert_called_with( self.net.register.assert_called_with(messages.Registration(
contact=('mailto:cert-admin@example.com',)) contact=('mailto:cert-admin@example.com',)))
self.net.register_from_account(acc2) self.net.register_from_account(acc2)
self.net.register.assert_called_with(contact=()) self.net.register.assert_called_with(messages.Registration())
if __name__ == '__main__': if __name__ == '__main__':