def test_get_and_use_session_token_url(self): privkey = ("a28ea1a6f11fb1c755b1d102990d64d6" + "b4468c10705bbcbdfca8bc4497cf8da8") # test support for the development UI port as well (3000) auth_header = get_auth_header(port=3000) request = { 'app_domain': 'http://test.com', 'app_public_key': blockstack_client.keys.get_pubkey_hex(privkey), 'methods': ['wallet_read', 'user_read'], } signer = jsontokens.TokenSigner() package = signer.sign(request, privkey) url = "/v1/auth?authRequest={}".format(package) data = self.get_request(url, headers=auth_header, status_code=200) self.assertIn('token', data) session = data['token'] auth_header = get_auth_header(session) # test wrong origin data = self.get_request('/v1/wallet/payment_address', headers=auth_header, status_code=403) # test correct origin auth_header['Origin'] = 'http://test.com' data = self.get_request('/v1/wallet/payment_address', headers=auth_header, status_code=200)
def test_get_and_use_session_token(self): privkey = ("a28ea1a6f11fb1c755b1d102990d64d6" + "b4468c10705bbcbdfca8bc4497cf8da8") auth_header = get_auth_header() request = { 'app_domain': 'test.com', 'app_public_key': blockstack_client.keys.get_pubkey_hex(privkey), 'methods': ['wallet_read'], } signer = jsontokens.TokenSigner() package = signer.sign(request, privkey) url = "/v1/auth?authRequest={}".format(package) data = self.get_request(url, headers=auth_header, status_code=200) self.assertIn('token', data) session = data['token'] auth_header = get_auth_header(session) data = self.get_request('/v1/wallet/payment_address', headers=auth_header, status_code=200) data = self.get_request('/v1/users/muneeb.id', headers=auth_header, status_code=403)
def app_make_session(blockchain_id, app_public_key, app_domain, methods, app_public_keys, requester_device_id, master_data_privkey, session_lifetime=None, config_path=CONFIG_PATH): """ Make a session JWT for this application. Verify with user private key Sign with master private key Return {'session': session jwt, 'session_token': session token} on success Return {'error': ...} on error """ conf = get_config(path=config_path) assert conf if session_lifetime is None: session_lifetime = conf.get('default_session_lifetime', 1e80) # ysi-storage.js assumes it needs to use an # uncompressed address. let's do that if we need to app_datastore_public_key = keylib.key_formatting.decompress(app_public_key) app_user_id = data.datastore_get_id(app_datastore_public_key) api_endpoint_host = conf.get('api_endpoint_host', DEFAULT_API_HOST) api_endpoint_port = conf.get('api_endpoint_port', DEFAULT_API_PORT) api_endpoint = '{}:{}'.format(api_endpoint_host, api_endpoint_port) ses = { 'version': 1, 'blockchain_id': blockchain_id, 'app_domain': app_domain, 'methods': methods, 'app_public_keys': app_public_keys, 'app_user_id': app_user_id, 'api_endpoint': api_endpoint, 'device_id': requester_device_id, 'storage': { 'classes': classify_storage_drivers(), 'preferences': {} }, 'timestamp': int(time.time()), 'expires': int(time.time() + session_lifetime), } jsonschema.validate(ses, APP_SESSION_SCHEMA) signer = jsontokens.TokenSigner() session_token = signer.sign(ses, master_data_privkey) session = jsontokens.decode_token(session_token) return {'session': session, 'session_token': session_token}
def app_make_session( app_domain, methods, master_data_privkey_hex, app_user_id=None, app_user_privkey=None, session_lifetime=None, blockchain_ids=None, config_path=CONFIG_PATH ): """ Make a session JWT for this application. Verify with user private key Sign with master private key Return {'session': session jwt, 'session_token': session token} on success Return {'error': ...} on error """ if session_lifetime is None: conf = get_config(path=config_path) assert conf session_lifetime = conf.get('default_session_lifetime', 1e80) if app_user_id is None: if app_user_privkey is None: if master_data_privkey_hex is not None: assert app_domain is not None, "need app domain to derive app key" app_user_privkey = data.datastore_get_privkey(master_data_privkey_hex, app_domain, config_path=config_path) else: # TODO: load from disk raise NotImplemented("Local app user private keys are not supported at this time") app_user_pubkey = get_pubkey_hex(app_user_privkey) app_user_id = data.datastore_get_id(app_user_pubkey) ses = { 'app_domain': app_domain, 'methods': methods, 'app_user_id': app_user_id, 'timestamp': int(time.time()), 'expires': int(time.time() + session_lifetime), } if blockchain_ids is not None: ses['blockchain_ids'] = blockchain_ids jsonschema.validate(ses, APP_SESSION_SCHEMA) signer = jsontokens.TokenSigner() session_token = signer.sign( ses, master_data_privkey_hex ) session = jsontokens.decode_token(session_token) return {'session': session, 'session_token': session_token}
def bsk_get_session(api_password, port=6270): """ Connect to the local ysi node. Get back a session. Return the session (a JWT string) on success Raise on error """ # will call `GET http://localhost:{port}/v1/auth?authRequest={auth JWT}` # will get back a session JWT # request permission to access the API auth_request = { 'app_domain': APPLICATION_NAME, 'methods': APPLICATION_METHODS, 'app_public_key': bsk.get_pubkey_hex(APPLICATION_KEY) } # authentication: basic {password} headers = {'Authorization': 'basic {}'.format(api_password)} # make the authentication token signer = jsontokens.TokenSigner() auth_token = signer.sign(auth_request, APPLICATION_KEY) # ask for a session token url = bsk_get_url('/v1/auth?authRequest={}'.format(auth_token), port=port) req = requests.get(url, headers=headers) if req.status_code == 200: # good to go! # expect {'token': ses token} JSON response payload = req.json() session = payload['token'] return session else: # whoops! raise Exception("HTTP status {} from Blockstack on {}".format( req.status_code, url))