diff --git a/blockchainauth/auth_request.py b/blockchainauth/auth_request.py index 320787b..3a35bb2 100644 --- a/blockchainauth/auth_request.py +++ b/blockchainauth/auth_request.py @@ -7,8 +7,11 @@ :license: MIT, see LICENSE for more details. """ -import uuid +from jwt import DecodeError +import requests +import requests.exceptions import time +import uuid from cryptography.hazmat.backends import default_backend from pybitcoin import BitcoinPrivateKey from blockchainauth.auth_message import AuthMessage @@ -31,7 +34,7 @@ class AuthRequest(AuthMessage): ] def __init__(self, private_key, domain_name, manifest_uri=None, redirect_uri=None, - scopes=None, expires_after=None, crypto_backend=default_backend()): + scopes=None, expires_after=None, crypto_backend=default_backend(), **kwargs): """ private_key should be provided in HEX, WIF or binary format domain_name should be a valid domain manifest_uri should be a valid URI @@ -79,5 +82,19 @@ def _payload(self): payload['iss'] = make_did_from_address(address) return payload + @classmethod + def fetch_app_manifest(cls, token): + # decode the token + try: + decoded_token = cls.decode(token) + except DecodeError: + return None + + try: + return requests.get(decoded_token['payload']['manifest_uri']).json() + except (requests.exceptions.RequestException, ValueError): + # ValueError for non-json responses + return None + def redirect_url(self): return 'blockstack:' + self.token() diff --git a/blockchainauth/verification.py b/blockchainauth/verification.py index 1b88465..64be386 100644 --- a/blockchainauth/verification.py +++ b/blockchainauth/verification.py @@ -7,12 +7,15 @@ """ import requests +import requests.exceptions import time import traceback from pybitcoin import BitcoinPublicKey from blockchainauth.dids import get_address_from_did -NAME_LOOKUP_URL = 'https://explorer-api.appartisan.com/get_name_blockchain_record/' +LOCALHOST_CORE_API = 'http://localhost:6270' +EXTERNAL_CORE_API = 'https://core.blockstack.org' +NAME_LOOKUP_URL = '/v1/names/' def do_signatures_match_public_keys(token, tokenizer, decoded_token): @@ -55,14 +58,32 @@ def do_public_keys_match_username(token, tokenizer, decoded_token): traceback.print_exc() return False - if not payload.get('username', None) or not NAME_LOOKUP_URL: + if not payload.get('username', None): return True username = payload['username'] - url = NAME_LOOKUP_URL.rstrip('/') + '/' + username # get publicly available address and address from payload - response = requests.get(url).json() + # 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: diff --git a/setup.py b/setup.py index 47304bf..bc4d78d 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name='blockchainauth', - version='0.3.1', + version='0.3.2', url='https://github.com/blockstack/blockchain-auth-python', license='MIT', author='Blockstack Developers', diff --git a/tests/unit_tests.py b/tests/unit_tests.py index 1a6952c..b23fef6 100644 --- a/tests/unit_tests.py +++ b/tests/unit_tests.py @@ -19,7 +19,7 @@ REQUEST_SAMPLE_ENCODED_TOKEN, REQUEST_SAMPLE_DECODED_TOKEN,\ RESPONSE_SAMPLE_ENCODED_TOKEN, RESPONSE_SAMPLE_DECODED_TOKEN, RYAN_PROFILE from blockchainauth.tokenizer import Tokenizer -from blockchainauth.verification import do_public_keys_match_username, NAME_LOOKUP_URL +from blockchainauth.verification import do_public_keys_match_username, LOCALHOST_CORE_API, NAME_LOOKUP_URL class AuthRequestTest(unittest.TestCase): @@ -96,7 +96,7 @@ def test_auth_response_token_encoding(self): # with username with requests_mock.mock() as m: - m.get(NAME_LOOKUP_URL.rstrip('/') + '/' + self.username, + 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()