예제 #1
0
    def __init__(self,
                 server_url=None,
                 machine_auth=None,
                 username=None,
                 version="0",
                 wallet=None):
        if machine_auth is not None and wallet is not None:
            raise ValueError(
                'You cannot provide both a machine_auth and a wallet.')
        elif machine_auth is None and wallet is not None:
            self.auth = machine_auth_wallet.MachineAuthWallet(wallet)
        elif machine_auth is not None and wallet is None:
            self.auth = machine_auth
        else:
            raise ValueError(
                'You must provide either a machine_auth or a wallet.')

        self.server_url = server_url if server_url is not None else two1.TWO1_HOST
        self.version = version
        if username:
            self.username = username.lower()
        self._session = None
        self._device_id = two1.TWO1_DEVICE_ID or "FREE_CLIENT"
        cb = self.auth.public_key.compressed_bytes
        self._wallet_pk = base64.b64encode(cb).decode()
예제 #2
0
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()
예제 #3
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
예제 #4
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
예제 #5
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)
예제 #6
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)
예제 #7
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
예제 #8
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
예제 #9
0
def login(ctx, setpassword, username, password):
    """Login to your 21.co account.

\b
Usage
_____
21 login                  # Interactive login
21 login -u user -p pass  # Headless login
21 login -sp              # Set password for currently logged-in user
"""
    config = ctx.obj['config']

    # A user needs to have a machine auth wallet in order to login to anything
    wallet = wallet_util.get_or_create_wallet(config.wallet_path)
    machine_auth = machine_auth_wallet.MachineAuthWallet(wallet)

    if setpassword:
        return set_password(config, machine_auth)
    else:
        return login_account(config, machine_auth, username, password)
예제 #10
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]