def login_21():
    """ Restore wallet to disk and log in to 21.
    """
    mnemonic = os.environ["TWO1_WALLET_MNEMONIC"]

    provider = TwentyOneProvider()
    wallet = Two1Wallet.import_from_mnemonic(provider, mnemonic)

    if not os.path.exists(os.path.dirname(Two1Wallet.DEFAULT_WALLET_PATH)):
        os.makedirs(os.path.dirname(Two1Wallet.DEFAULT_WALLET_PATH))
    wallet.to_file(Two1Wallet.DEFAULT_WALLET_PATH)

    # login
    config = Config()
    machine_auth = machine_auth_wallet.MachineAuthWallet(wallet)

    username = os.environ["TWO1_USERNAME"]
    password = os.environ["TWO1_PASSWORD"]

    rest_client = _rest_client.TwentyOneRestClient(two1.TWO1_HOST,
                                                   machine_auth, username)

    machine_auth_pubkey_b64 = base64.b64encode(
        machine_auth.public_key.compressed_bytes).decode()
    payout_address = machine_auth.wallet.current_address

    rest_client.login(payout_address=payout_address, password=password)

    config.set("username", username)
    config.set("mining_auth_pubkey", machine_auth_pubkey_b64)
    config.save()
Beispiel #2
0
 def __init__(self):
     super().__init__()
     self._logger = logging.getLogger('hello.publish')
     logging.basicConfig(stream=sys.stdout, level=logging.INFO)
     self._username = settings.TWO1_USERNAME
     self._client = rest_client.TwentyOneRestClient(username=self._username,
                                                    wallet=settings.WALLET)
Beispiel #3
0
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
Beispiel #4
0
def test_request_error_paths(mock_wallet, request_side_effect, status_code,
                             data, raised_exception):
    # creates a machine_auth from a mock wallet
    machine_auth = machine_auth_wallet.MachineAuthWallet(mock_wallet)
    rc = rest_client.TwentyOneRestClient("", machine_auth)

    with mock.patch("two1.server.rest_client.requests.Session.request"
                    ) as mock_request:
        if request_side_effect:
            mock_request.side_effect = request_side_effect
            with pytest.raises(raised_exception):
                rc._request()
        else:
            response = MockHttpResponse(status_code=status_code, data=data)
            mock_request.return_value = response
            if raised_exception:
                with pytest.raises(raised_exception) as ex_info:
                    rc._request()

                if data:
                    try:
                        json.loads(data)
                    except ValueError:
                        try:
                            json.loads(data)
                        except ValueError:
                            assert 'error' in ex_info.value.message
                        else:
                            assert 'error' in ex_info.value.data
                    else:
                        assert json.loads(data) == ex_info.value.data
            else:
                assert rc._request() == response
Beispiel #5
0
def get_user_credentials(two1_dir="~/.two1/two1.json"):
    """ Collect user credentials at CLI.
    """

    with open(os.path.expanduser(two1_dir), "r") as f:
        username = json.load(f)["username"]
    try:
        w = wallet.Wallet()
    except:
        logger.info(
            click.style(
                "A technical error occured. Please try the previous command again.",
                fg="magenta"))
        sys.exit()
    machine_auth = machine_auth_wallet.MachineAuthWallet(w)
    rest_client = _rest_client.TwentyOneRestClient(TWO1_HOST, machine_auth,
                                                   username)
    address = w.current_address

    correct_password = False
    pw = click.prompt(click.style("Please enter your 21 password",
                                  fg=PROMPT_COLOR),
                      hide_input=True)

    while not correct_password:
        try:
            rest_client.login(payout_address=address, password=pw)
            correct_password = True
        except:
            pw = click.prompt(click.style(
                "Incorrect 21 password. Please try again", fg="magenta"),
                              hide_input=True)

    return username, pw
Beispiel #6
0
 def __init__(self):
     """
     Constructor for the Rev class.
     """
     self.config = two1_config.Config(two1.TWO1_CONFIG_FILE, None)
     self.wallet = wallet_utils.get_or_create_wallet(self.config.wallet_path)
     self.machine_auth = machine_auth_wallet.MachineAuthWallet(self.wallet)
     self.client = rest_client.TwentyOneRestClient(two1.TWO1_HOST, self.machine_auth, self.config.username)
Beispiel #7
0
def create_default_rest_client():
    """Return a rest client using default parameters."""
    import two1
    from two1 import wallet
    from two1.commands.util import config
    from two1.server import machine_auth_wallet, rest_client
    auth = machine_auth_wallet.MachineAuthWallet(wallet.Wallet())
    return rest_client.TwentyOneRestClient(two1.TWO1_HOST, auth,
                                           config.Config().username)
Beispiel #8
0
def parse_config(
    config_file=two1.TWO1_CONFIG_FILE,
    config_dict=None,
    need_wallet_and_account=True,
    check_update=False,
    debug=False,
):
    """Get configuration information that is used to drive all 21 commands.

    This function is very useful for testing as it builds up several
    key variables (like the client, wallet, username, and the like)
    that are used in many commands. The way it does this is by taking
    in the config_file (typically .two1/two1.json) and the config_dict
    (a list of key-value pairs to override the config_file, typically
    an empty dictionary), and then running the logic below.

    It returns obj which is a dictionary that has Config, Wallet,
    MachineAuth, and TwentyOneRestClient instances underneath it, as
    well as a string with the username. The obj is passed down by
    click to various other commands.

    You can use this function in any test to instantiate the user's
    wallet, username, and other variables.
    """
    try:
        config = two1_config.Config(config_file,
                                    config_dict,
                                    check_update=check_update)
    except exceptions.FileDecodeError as e:
        raise click.ClickException(
            uxstring.UxString.Error.file_decode.format((str(e))))

    wallet, machine_auth, username, client = None, None, None, None
    if need_wallet_and_account:
        try:
            wallet = wallet_utils.get_or_create_wallet(config.wallet_path)
        except blockchain_exceptions.DataProviderError as err:
            raise exceptions.Two1Error(
                'You have experienced a data provider error: %s ' % err.args)
        machine_auth = machine_auth_wallet.MachineAuthWallet(wallet)
        username = account_utils.get_or_create_username(config, machine_auth)
        client = rest_client.TwentyOneRestClient(two1.TWO1_HOST, machine_auth,
                                                 config.username)
        config.username = username

    obj = dict(
        config=config,
        wallet=wallet,
        machine_auth=machine_auth,
        username=username,
        client=client,
        debug=debug,
    )
    return obj
Beispiel #9
0
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()
Beispiel #10
0
def get_rest_client():
    """ Helper method to create rest_client.
    """
    with open(os.path.expanduser("~/.two1/two1.json"), "r") as f:
        username = json.load(f)["username"]

    try:
        w = wallet.Wallet()
    except:
        logger.info(click.style("A technical error occured. Please try the previous command again.", fg="magenta"))
        sys.exit()

    machine_auth = machine_auth_wallet.MachineAuthWallet(w)
    rest_client = _rest_client.TwentyOneRestClient(TWO1_HOST, machine_auth, username)
    return rest_client
 def __init__(self, wallet, username=None, client=None):
     """Initialize the bittransfer with wallet and username."""
     from two1.server.machine_auth_wallet import MachineAuthWallet
     from two1.server import rest_client
     super().__init__()
     if isinstance(wallet, MachineAuthWallet):
         self.wallet = wallet
     else:
         self.wallet = MachineAuthWallet(wallet)
     if username is None:
         self.username = config.Config().username
     else:
         self.username = username
     if client is None:
         self.client = rest_client.TwentyOneRestClient(
             two1.TWO1_HOST, self.wallet, self.username)
     else:
         self.client = client
Beispiel #12
0
def test_check_headers(mock_wallet, device_id, data):
    # Creates a machine_auth from a mock wallet
    machine_auth = machine_auth_wallet.MachineAuthWallet(mock_wallet)
    rc = rest_client.TwentyOneRestClient("", machine_auth)

    # Forces the rest client _device_id to be parameterized
    if device_id:
        rc._device_id = device_id

    # Gets the encoded amchine auth pub key
    wallet_pk = base64.b64encode(
        machine_auth.public_key.compressed_bytes).decode()

    # Expected header format to be called as an input param into request
    expected_headers = {
        'User-Agent':
        "21/{}".format(two1.TWO1_VERSION),
        'From':
        "{}@{}".format(wallet_pk, device_id if device_id else "FREE_CLIENT")
    }

    # Function only adds content type when there is content
    if data:
        expected_headers['Content-Type'] = 'application/json'

    with mock.patch("two1.server.rest_client.requests.Session.request"
                    ) as mock_request:
        mock_request.return_value = MockHttpResponse(status_code=200,
                                                     data=None)
        rc._request(data=data)
        call_args = mock_request.call_args
        kwargs = call_args[1]
        assert 'headers' in kwargs
        for key, value in expected_headers.items():
            assert key in kwargs['headers']
            assert value == kwargs['headers'][key]
Beispiel #13
0
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
Beispiel #14
0
# Setup the dashboard
from two1.commands import status
from two1.commands import log
from two1.commands import flush
from two1.commands import mine
from two1.wallet import Wallet
from two1.server.machine_auth_wallet import MachineAuthWallet
from two1.server import rest_client
from two1.commands.config import Config
from two1 import TWO1_HOST

wallet = Wallet()
host = TWO1_HOST
conf = Config()
username = Config().username
client = rest_client.TwentyOneRestClient(host, MachineAuthWallet(wallet),
                                         username)
admin = Admin(app, name='Admin', template_mode='bootstrap3')


class DashboardView(BaseView):
    @expose('/', methods=('GET', 'POST'))
    def dashboard(self):
        flush_message = ""
        status_mining = status.status_mining(client)

        if request.method == 'POST':
            print(request.form)
            if request.form['submit'] == 'Flush Earnings':
                flush_message = self.doFlush()
            else:
                if status_mining[
Beispiel #15
0
 def __init__(self):
     super().__init__()
     self._logger = logging.getLogger('deep21.publish')
     self._username = settings.TWO1_USERNAME
     self._client = rest_client.TwentyOneRestClient(username=self._username, wallet=settings.WALLET)