def register(config, unused_plugins): """Create accounts on the server. :param config: Configuration object :type config: interfaces.IConfig :param unused_plugins: List of plugins (deprecated) :type unused_plugins: `list` of `str` :returns: `None` or a string indicating and error :rtype: None or str """ # Portion of _determine_account logic to see whether accounts already # exist or not. account_storage = account.AccountFileStorage(config) accounts = account_storage.find_all() if accounts: # TODO: add a flag to register a duplicate account (this will # also require extending _determine_account's behavior # or else extracting the registration code from there) return ("There is an existing account; registration of a " "duplicate account with this command is currently " "unsupported.") # _determine_account will register an account _determine_account(config) return None
def _determine_account(config): """Determine which account to use. If ``config.account`` is ``None``, it will be updated based on the user input. Same for ``config.email``. :param config: Configuration object :type config: interfaces.IConfig :returns: Account and optionally ACME client API (biproduct of new registration). :rtype: tuple of :class:`certbot._internal.account.Account` and :class:`acme.client.Client` :raises errors.Error: If unable to register an account with ACME server """ def _tos_cb(terms_of_service): if config.tos: return True msg = ("Please read the Terms of Service at {0}. You " "must agree in order to register with the ACME " "server at {1}".format(terms_of_service, config.server)) obj = zope.component.getUtility(interfaces.IDisplay) result = obj.yesno(msg, "Agree", "Cancel", cli_flag="--agree-tos", force_interactive=True) if not result: raise errors.Error("Registration cannot proceed without accepting " "Terms of Service.") return None account_storage = account.AccountFileStorage(config) acme = None if config.account is not None: acc = account_storage.load(config.account) else: accounts = account_storage.find_all() if len(accounts) > 1: acc = display_ops.choose_account(accounts) elif len(accounts) == 1: acc = accounts[0] else: # no account registered yet if config.email is None and not config.register_unsafely_without_email: config.email = display_ops.get_email() try: acc, acme = client.register(config, account_storage, tos_cb=_tos_cb) except errors.MissingCommandlineFlag: raise except errors.Error: logger.debug("", exc_info=True) raise errors.Error( "Unable to register an account with ACME server") config.account = acc.id return acc, acme
def unregister(config, unused_plugins): """Deactivate account on server :param config: Configuration object :type config: interfaces.IConfig :param unused_plugins: List of plugins (deprecated) :type unused_plugins: `list` of `str` :returns: `None` :rtype: None """ account_storage = account.AccountFileStorage(config) accounts = account_storage.find_all() reporter_util = zope.component.getUtility(interfaces.IReporter) if not accounts: return "Could not find existing account to deactivate." yesno = zope.component.getUtility(interfaces.IDisplay).yesno prompt = ("Are you sure you would like to irrevocably deactivate " "your account?") wants_deactivate = yesno(prompt, yes_label='Deactivate', no_label='Abort', default=True) if not wants_deactivate: return "Deactivation aborted." acc, acme = _determine_account(config) cb_client = client.Client(config, acc, None, None, acme=acme) # delete on boulder cb_client.acme.deactivate_registration(acc.regr) account_files = account.AccountFileStorage(config) # delete local account files account_files.delete(config.account) reporter_util.add_message("Account deactivated.", reporter_util.MEDIUM_PRIORITY) return None
def update_account(config, unused_plugins): """Modify accounts on the server. :param config: Configuration object :type config: interfaces.IConfig :param unused_plugins: List of plugins (deprecated) :type unused_plugins: `list` of `str` :returns: `None` or a string indicating and error :rtype: None or str """ # Portion of _determine_account logic to see whether accounts already # exist or not. account_storage = account.AccountFileStorage(config) accounts = account_storage.find_all() reporter_util = zope.component.getUtility(interfaces.IReporter) add_msg = lambda m: reporter_util.add_message( m, reporter_util.MEDIUM_PRIORITY) if not accounts: return "Could not find an existing account to update." if config.email is None and not config.register_unsafely_without_email: config.email = display_ops.get_email(optional=False) acc, acme = _determine_account(config) cb_client = client.Client(config, acc, None, None, acme=acme) # Empty list of contacts in case the user is removing all emails acc_contacts = () # type: Iterable[str] if config.email: acc_contacts = ['mailto:' + email for email in config.email.split(',')] # We rely on an exception to interrupt this process if it didn't work. prev_regr_uri = acc.regr.uri acc.regr = cb_client.acme.update_registration( acc.regr.update(body=acc.regr.body.update(contact=acc_contacts))) # A v1 account being used as a v2 account will result in changing the uri to # the v2 uri. Since it's the same object on disk, put it back to the v1 uri # so that we can also continue to use the account object with acmev1. acc.regr = acc.regr.update(uri=prev_regr_uri) account_storage.update_regr(acc, cb_client.acme) if config.email is None: add_msg( "Any contact information associated with this account has been removed." ) else: eff.prepare_subscription(config, acc) add_msg("Your e-mail address was updated to {0}.".format(config.email)) return None