def login_account(config, machine_auth, username=None, password=None): """ Log in a user into the two1 account Args: config (Config): config object used for getting .two1 information username (str): optional command line arg to skip username prompt password (str): optional command line are to skip password prompt """ # prints the sign up page link when a username is not set and not on a BC if not config.username and not bitcoin_computer.has_mining_chip(): logger.info(uxstring.UxString.signin_title) # uses specifies username or asks for a different one username = username or get_username_interactive() password = password or get_password_interactive() # use existing username in config rest_client = _rest_client.TwentyOneRestClient(two1.TWO1_HOST, machine_auth, username) # get the payout address and the pubkey from the machine auth wallet machine_auth_pubkey_b64 = base64.b64encode( machine_auth.public_key.compressed_bytes).decode() payout_address = machine_auth.wallet.current_address logger.info(uxstring.UxString.login_in_progress.format(username)) try: rest_client.login(payout_address=payout_address, password=password) # handles 401 gracefully except exceptions.ServerRequestError as ex: if ex.status_code == 403 and "error" in ex.data and ex.data[ "error"] == "TO408": email = ex.data["email"] raise exceptions.UnloggedException( click.style(uxstring.UxString.unconfirmed_email.format(email), fg="blue")) elif ex.status_code == 403 or ex.status_code == 404: raise exceptions.UnloggedException( uxstring.UxString.incorrect_password) else: raise ex logger.info(uxstring.UxString.payout_address.format(payout_address)) logger.info(uxstring.UxString.get_started) # Save the new username and auth key config.set("username", username) config.set("mining_auth_pubkey", machine_auth_pubkey_b64) config.save()
def account_post(self, payout_address, email, password, fullname): path = "/pool/account/{}/".format(self.username) encoded_password = base64.encodebytes(bytes(password, 'utf-8')).decode() body = { "full_name": fullname, "email": email, "password": encoded_password, "payout_address": payout_address, "public_key": self._wallet_pk, "device_uuid": self._device_id } data = json.dumps(body) try: ret = self._request(sign_username=self.username, method="POST", path=path, data=data) except exceptions.ServerRequestError as e: if e.status_code == 409: raise exceptions.UnloggedException( uxstring.UxString.existing_account.format( e.data["username"])) else: raise e return ret
def account_post(self, payout_address, email, password, fullname): path = "/pool/account/{}/".format(self.username) encoded_password = base64.encodebytes(bytes(password, 'utf-8')).decode() body = { "full_name": fullname, "email": email, "password": encoded_password, "payout_address": payout_address, "public_key": self._wallet_pk, "device_uuid": self._device_id } data = json.dumps(body) try: ret = self._request(sign_username=self.username, method="POST", path=path, data=data) except exceptions.ServerRequestError as e: if e.status_code == 409: raise exceptions.UnloggedException((click.style( "There is already a username associated with your current wallet. Use ", fg="red") + click.style( "21 login -u {}", bold=True, fg="red") + click.style( " to login.", fg="red")).format( e.data["username"])) else: raise e return ret
def set_password(config, machine_auth): """ Upadets the 21 user account password from command line Args: config (Config): config object used for getting .two1 information client (two1.server.rest_client.TwentyOneRestClient) an object for sending authenticated requests to the TwentyOne backend. """ if not config.username: logger.info(uxstring.UxString.login_required) return # use existing username in config rest_client = _rest_client.TwentyOneRestClient(two1.TWO1_HOST, machine_auth, config.username) try: password = click.prompt(uxstring.UxString.set_new_password.format(config.username), hide_input=True, confirmation_prompt=True, type=Password()) try: rest_client.update_password(password) except exceptions.ServerRequestError as ex: if 400 <= ex.status_code < 500: raise exceptions.UnloggedException(ex.data.get('status')) else: raise except click.exceptions.Abort: pass
def create_account_on_bc(config, machine_auth): """ Creates an account for the current machine auth wallet Args: config (Config): config object used for getting .two1 information machine_auth (MachineAuthWallet): machine auth wallet used for authentication """ # get the payout address and the pubkey from the machine auth wallet machine_auth_pubkey_b64 = base64.b64encode(machine_auth.public_key.compressed_bytes).decode() payout_address = machine_auth.wallet.current_address # Don't attempt to create an account if the user indicates they # already have an account (defaults to No) if click.confirm(uxstring.UxString.already_have_account): logger.info(uxstring.UxString.please_login) sys.exit() logger.info(uxstring.UxString.missing_account) email = None username = None fullname = None while True: if not fullname: fullname = click.prompt(uxstring.UxString.enter_name) if not email: email = click.prompt(uxstring.UxString.enter_email, type=EmailAddress()) # prompts for a username and password if not username: try: logger.info("") username = click.prompt(uxstring.UxString.enter_username, type=Username()) logger.info("") logger.info(uxstring.UxString.creating_account.format(username)) password = click.prompt(uxstring.UxString.set_new_password.format(username), hide_input=True, confirmation_prompt=True, type=Password()) except click.Abort: return try: # change the username of the given username rest_client = _rest_client.TwentyOneRestClient(two1.TWO1_HOST, machine_auth, username) rest_client.account_post(payout_address, email, password, fullname) # Do not continue creating an account because the UUID is invalid except exceptions.BitcoinComputerNeededError: raise except exceptions.ServerRequestError as ex: # handle various 400 errors from the server if ex.status_code == 400: if "error" in ex.data: error_code = ex.data["error"] # email exists if error_code == "TO401": logger.info(uxstring.UxString.email_exists.format(email)) email = None continue # username exists elif error_code == "TO402": logger.info(uxstring.UxString.username_exists.format(username)) username = None continue # unexpected 400 error else: raise exceptions.Two1Error( str(next(iter(ex.data.values()), "")) + "({})".format(ex.status_code)) # handle an invalid username format elif ex.status_code == 404: logger.info(uxstring.UxString.Error.invalid_username) # handle an error where a bitcoin computer is necessary elif ex.status_code == 403: r = ex.data if "detail" in r and "TO200" in r["detail"]: raise exceptions.UnloggedException(uxstring.UxString.max_accounts_reached) else: logger.info(uxstring.UxString.Error.account_failed) username = None # created account successfully else: logger.info(uxstring.UxString.payout_address.format(payout_address)) # save new username and password config.set("username", username) config.set("mining_auth_pubkey", machine_auth_pubkey_b64) config.save() break