def _human_readable_acls(store_client: storeapi.StoreClient) -> str: acl = store_client.acl() snap_names = [] snap_ids = acl["snap_ids"] if snap_ids is not None: try: for snap_id in snap_ids: snap_names.append(store_client.get_snap_name_for_id(snap_id)) except TypeError: raise RuntimeError(f"invalid snap_ids: {snap_ids!r}") acl["snap_names"] = snap_names else: acl["snap_names"] = None human_readable_acl: Dict[str, Union[str, List[str], None]] = { "expires": str(acl["expires"]) } for key in ("snap_names", "channels", "permissions"): human_readable_acl[key] = acl[key] if not acl[key]: human_readable_acl[key] = "No restriction" return dedent( """\ snaps: {snap_names} channels: {channels} permissions: {permissions} expires: {expires} """.format( **human_readable_acl ) )
def _human_readable_acls(store: storeapi.StoreClient) -> str: acl = store.acl() snap_names = [] if acl["snap_ids"]: for snap_id in acl["snap_ids"]: snap_names.append(store.get_snap_name_for_id(snap_id)) acl["snap_names"] = snap_names human_readable_acl = { "expires": str(acl["expires"]) } # type: Dict[str, Union[str, List[str]]] for key in ("snap_names", "channels", "permissions"): human_readable_acl[key] = acl[key] if not acl[key]: human_readable_acl[key] = "No restriction" return dedent( """\ snaps: {snap_names} channels: {channels} permissions: {permissions} expires: {expires} """.format( **human_readable_acl ) )
def _try_login(email: str, password: str, *, store: storeapi.StoreClient = None, save: bool = True, packages: Iterable[Dict[str, str]] = None, acls: Iterable[str] = None, channels: Iterable[str] = None, config_fd: TextIO = None) -> None: try: store.login(email, password, packages=packages, acls=acls, channels=channels, config_fd=config_fd, save=save) if not config_fd: print() logger.info(storeapi.constants.TWO_FACTOR_WARNING) except storeapi.errors.StoreTwoFactorAuthenticationRequired: one_time_password = input('Second-factor auth: ') store.login(email, password, one_time_password=one_time_password, acls=acls, packages=packages, channels=channels, config_fd=config_fd, save=save) # Continue if agreement and namespace conditions are met. _check_dev_agreement_and_namespace_statuses(store)
def _new_snap(store: storeapi.StoreClient) -> str: acl = store.acl() snap_names = [] if not (snap_id in acl['snap_ids']): snap_names.append('Heesen') else: for snap_id in acl['snap_ids']: snap_names.append(store.get_snap_name_for_id(snap_id)) acl['snap_names'] = snap_names @mock.patch.object(storeapi._sca_client.SCAClient, 'get_account_information') @mock.patch.object(storeapi.StoreClient, 'login') @mock.patch.object(storeapi.StoreClient, 'acl') def test_successful_export(self, mock_acl, mock_login, mock_get_account_information): self.mock_input.return_value = '*****@*****.**' mock_acl.return_value = { 'snap_ids': ['edge123'], 'channels': None, 'permissions': None, } result = self.run_command(['export-login', 'exported']) self.assertThat(result.exit_code, Equals(0)) self.assertThat(result.output, Contains(storeapi.constants.TWO_FACTOR_WARNING)) self.assertThat(result.output, Contains('Login successfully exported')) self.assertThat(result.output, MatchesRegex(r".*snaps:.*?['edge123']", re.DOTALL)) self.assertThat( result.output, MatchesRegex(r'.*channels:.*?No restriction', re.DOTALL)) self.assertThat( result.output, MatchesRegex(r'.*permissions:.*?No restriction', re.DOTALL)) self.mock_input.assert_called_once_with('Email: ') mock_login.assert_called_once_with('*****@*****.**', mock.ANY, acls=None, packages=None, channels=None, save=False, config_fd=None) mock_acl.assert_called_once_with()
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=email, password=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.http_clients.errors.StoreTwoFactorAuthenticationRequired: one_time_password = echo.prompt("Second-factor auth") store.login( email=email, password=password, otp=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 _human_readable_acls(store: storeapi.StoreClient) -> str: acl = store.acl() snap_names = [] if acl['snap_ids']: for snap_id in acl['snap_ids']: snap_names.append(store.get_snap_name_for_id(snap_id)) acl['snap_names'] = snap_names human_readable_acl = {} # type: Dict[str, Union[str, List[str]]] for key in ('snap_names', 'channels', 'permissions'): human_readable_acl[key] = acl[key] if not acl[key]: human_readable_acl[key] = 'No restriction' return dedent("""\ snaps: {snap_names} channels: {channels} permissions: {permissions} """.format(**human_readable_acl))
def _store_session(macaroon_location): store = StoreClient() with open(macaroon_location) as macaroon: log.debug('Logging onto Snap store with macaroon file "{}"...'.format(macaroon.name)) # XXX Bad API. email and password are mandatory in the function signature, but they are # read from the macaroon when config_fd is provided store.login(email='', password='', config_fd=macaroon) log.info('Logged on Snap store') try: yield store finally: log.debug('Logging off Snap store...') store.logout() log.info('Logged off Snap store')