def test_auth_response_token_encoding(self):
        # without username, testing basics
        auth_response = AuthResponse(self.private_key_hex, RYAN_PROFILE)
        auth_response_token = auth_response.token()

        decoded_token = AuthResponse.decode(auth_response_token)
        payload = decoded_token['payload']
        self.assertEqual(payload['public_keys'][0], self.public_key_hex)
        self.assertEqual(get_address_from_did(payload['iss']),
                         self.public_key.address())
        self.assertEqual(payload['profile'], self.profile)
        self.assertEqual(payload['username'], None)

        self.assertTrue(AuthResponse.verify(auth_response_token))

        # with username
        with requests_mock.mock() as m:
            m.get(LOCALHOST_CORE_API + NAME_LOOKUP_URL + self.username,
                  text=json.dumps({'address': self.public_key.address()}))
            auth_response = AuthResponse(self.private_key_hex, RYAN_PROFILE,
                                         self.username)
            auth_response_token = auth_response.token()

            self.assertTrue(
                do_public_keys_match_username(
                    auth_response_token, Tokenizer(),
                    AuthResponse.decode(auth_response_token)))
            self.assertTrue(AuthResponse.verify(auth_response_token))
def do_public_keys_match_issuer(token, tokenizer, decoded_token):
    # extract the public key from the token
    try:
        payload = decoded_token['payload']
        if not payload['public_keys']:
            return not payload.get('iss', None)
        if len(payload['public_keys']) != 1:
            raise NotImplementedError('Multiple public keys are not supported')
        address_from_pub_key = BitcoinPublicKey(str(payload['public_keys'][0])).address()
        address_from_iss = get_address_from_did(payload['iss'])
        return address_from_pub_key == address_from_iss
    except (KeyError, ValueError):
        traceback.print_exc()
        return False
    def test_auth_request_token_encoding(self):
        # valid AuthRequest
        auth_request = AuthRequest(self.private_key_hex, self.domain_name)
        auth_request_token = auth_request.token()

        decoded_token = AuthRequest.decode(auth_request_token)
        payload = decoded_token['payload']
        self.assertEqual(payload['public_keys'][0], self.public_key_hex)
        self.assertEqual(get_address_from_did(payload['iss']), self.public_key.address())
        self.assertEqual(payload['scopes'], [])
        self.assertEqual(payload['manifest_uri'], self.domain_name + '/manifest.json')

        self.assertTrue(AuthRequest.verify(auth_request_token))

        # invalid AuthRequest
        auth_request = AuthRequest(self.private_key_hex, self.domain_name)
        auth_request_token = auth_request.token()[:-1]

        self.assertFalse(AuthRequest.verify(auth_request_token))
def do_public_keys_match_username(token, tokenizer, decoded_token):
    try:
        payload = decoded_token['payload']
    except KeyError:
        traceback.print_exc()
        return False

    if not payload.get('username', None):
        return True

    username = payload['username']

    # get publicly available address and address from payload
    # first try from localhost
    url = LOCALHOST_CORE_API + NAME_LOOKUP_URL + username
    try:
        response = requests.get(url).json()
    except (requests.exceptions.RequestException, ValueError):
        # ValueError for non-json responses
        response = None

    # if failed try from public Core API
    if not response:
        url = EXTERNAL_CORE_API + NAME_LOOKUP_URL + username
        try:
            response = requests.get(url).json()
        except (requests.exceptions.RequestException, ValueError):
            # ValueError for non-json responses
            response = None

    if not response:
        return False

    try:
        address_from_issuer = get_address_from_did(payload.get('iss', ''))
    except ValueError:
        traceback.print_exc()
        return False

    return 'address' in response and address_from_issuer and \
           response['address'] == address_from_issuer
def do_public_keys_match_username(token, tokenizer, decoded_token):
    try:
        payload = decoded_token['payload']
    except KeyError:
        traceback.print_exc()
        return False

    if not payload.get('username', None) or not NAME_LOOKUP_URL:
        return True

    username = payload['username']
    url = NAME_LOOKUP_URL.rstrip('/') + '/' + username

    # get publicly available address and address from payload
    response = requests.get(url).json()
    try:
        address_from_issuer = get_address_from_did(payload.get('iss', ''))
    except ValueError:
        traceback.print_exc()
        return False

    return 'address' in response and address_from_issuer and \
           response['address'] == address_from_issuer