def login( *, store: storeapi.StoreClient, packages: Iterable[Dict[str, str]] = None, save: bool = True, acls: Iterable[str] = None, channels: Iterable[str] = None, expires: str = None, config_fd: TextIO = None, ) -> bool: if not store: store = storeapi.StoreClient() email = "" password = "" if not config_fd: echo.wrapped("Enter your Ubuntu One e-mail address and password.") echo.wrapped( "If you do not have an Ubuntu One account, you can create one " "at https://snapcraft.io/account" ) email = echo.prompt("Email") if os.getenv("SNAPCRAFT_TEST_INPUT"): # Integration tests do not work well with hidden input. echo.warning("Password will be visible.") hide_input = False else: hide_input = True password = echo.prompt("Password", hide_input=hide_input) try: _try_login( email, password, store=store, packages=packages, acls=acls, channels=channels, expires=expires, config_fd=config_fd, save=save, ) # Let StoreAuthenticationError pass through so we get decent error messages except storeapi.errors.InvalidCredentialsError: return _fail_login(storeapi.constants.INVALID_CREDENTIALS) except storeapi.errors.StoreAccountInformationError: return _fail_login(storeapi.constants.ACCOUNT_INFORMATION_ERROR) except storeapi.errors.NeedTermsSignedError as e: return _fail_login(e.message) # type: ignore return True
def test_echo_prompt_default(self, tty_mock): echo.prompt("message", default="the new default") self.click_prompt.mock.assert_called_once_with( "message", default="the new default", hide_input=False, confirmation_prompt=False, type=None, value_proc=None, prompt_suffix=": ", show_default=True, err=False, )
def login( *, store: storeapi.StoreClient, packages: Iterable[Dict[str, str]] = None, save: bool = True, acls: Iterable[str] = None, channels: Iterable[str] = None, expires: str = None, config_fd: TextIO = None, ) -> bool: if not store: store = storeapi.StoreClient() email = "" password = "" if not config_fd: echo.wrapped("Enter your Ubuntu One e-mail address and password.") echo.wrapped( "If you do not have an Ubuntu One account, you can create one " "at https://snapcraft.io/account" ) email = echo.prompt("Email") if os.getenv("SNAPCRAFT_TEST_INPUT"): # Integration tests do not work well with hidden input. echo.warning("Password will be visible.") hide_input = False else: hide_input = True password = echo.prompt("Password", hide_input=hide_input) _try_login( email, password, store=store, packages=packages, acls=acls, channels=channels, expires=expires, config_fd=config_fd, save=save, ) return True
def prompt_for_value(self, ctx): default = self.get_default(ctx) # If this is a prompt for a flag we need to handle this # differently. if self.is_bool_flag: return confirm(self.prompt, default) return prompt( self.prompt, default=default, type=self.type, hide_input=self.hide_input, show_choices=self.show_choices, confirmation_prompt=self.confirmation_prompt, value_proc=lambda x: self.process_value(ctx, x), )
def _try_login( email: str, password: str, *, store: storeapi.StoreClient, save: bool = True, packages: Iterable[Dict[str, str]] = None, acls: Iterable[str] = None, channels: Iterable[str] = None, expires: str = None, config_fd: TextIO = None, ) -> None: try: store.login( email, password, packages=packages, acls=acls, channels=channels, expires=expires, config_fd=config_fd, save=save, ) if not config_fd: print() echo.wrapped(storeapi.constants.TWO_FACTOR_WARNING) except storeapi.errors.StoreTwoFactorAuthenticationRequired: one_time_password = echo.prompt("Second-factor auth") store.login( email, password, one_time_password=one_time_password, acls=acls, packages=packages, channels=channels, expires=expires, config_fd=config_fd, save=save, ) # Continue if agreement and namespace conditions are met. _check_dev_agreement_and_namespace_statuses(store)
def _check_dev_agreement_and_namespace_statuses(store) -> None: """ Check the agreement and namespace statuses of the dev. Fail if either of those conditions is not met. Re-raise `StoreAccountInformationError` if we get an error and the error is not either of these. """ # Check account information for the `developer agreement` status. try: store.get_account_information() except storeapi.errors.StoreAccountInformationError as e: if storeapi.constants.MISSING_AGREEMENT == e.error: # type: ignore # A precaution if store does not return new style error. url = _get_url_from_error(e) or urljoin( storeapi.constants.STORE_DASHBOARD_URL, "/dev/tos" ) choice = echo.prompt(storeapi.constants.AGREEMENT_INPUT_MSG.format(url)) if choice in {"y", "Y"}: try: store.sign_developer_agreement(latest_tos_accepted=True) except: # noqa LP: #1733003 raise storeapi.errors.NeedTermsSignedError( storeapi.constants.AGREEMENT_SIGN_ERROR.format(url) ) else: raise storeapi.errors.NeedTermsSignedError( storeapi.constants.AGREEMENT_ERROR ) # Now check account information for the `namespace` status. try: store.get_account_information() except storeapi.errors.StoreAccountInformationError as e: if storeapi.constants.MISSING_NAMESPACE in e.error: # type: ignore # A precaution if store does not return new style error. url = _get_url_from_error(e) or urljoin( storeapi.constants.STORE_DASHBOARD_URL, "/dev/account" ) raise storeapi.errors.NeedTermsSignedError( storeapi.constants.NAMESPACE_ERROR.format(url) ) else: raise
def _select_key(keys): if len(keys) > 1: print("Select a key:") print() tabulated_keys = tabulate( [(i + 1, key["name"], key["sha3-384"]) for i, key in enumerate(keys)], headers=["Number", "Name", "SHA3-384 fingerprint"], tablefmt="plain", ) print(tabulated_keys) print() while True: try: keynum = int(echo.prompt("Key number: ")) - 1 except ValueError: continue if keynum >= 0 and keynum < len(keys): return keys[keynum] else: return keys[0]
def test_echo_prompt_is_not_tty(self, tty_mock): echo.prompt("message") self.click_prompt.mock.assert_not_called()