def test_implicit_grant(client, init_db): # simulate the authorization approval - with client: # use the session_transaction to enable modification of the session object: # cf., https://flask.palletsprojects.com/en/1.1.x/testing/#accessing-and-modifying-sessions with client.session_transaction() as sess: sess['username'] = TEST_USERNAME # once we leave the context, session updates applied via sess object are available - response = client.post('http://*****:*****@{TEST_TENANT_ID}'
def test_custom_claims_show_up_after_refresh(client): # First, get an access token payload = { "token_tenant_id": "admin", "account_type": "service", "token_username": "******", "generate_refresh_token": True, "claims": { "test_claim": "here it is!" }, "target_site_id": "admin" } response = client.post("http://localhost:5000/v3/tokens", data=json.dumps(payload), content_type='application/json', headers=get_basic_auth_header()) # Check that the first access token has the custom claim assert response.status_code == 200 access_token = response.json['result']['access_token']['access_token'] access_token_data = auth.validate_token(access_token) assert access_token_data['test_claim'] == "here it is!" # Then refresh the token refresh_token = response.json['result']['refresh_token']['refresh_token'] payload2 = {"refresh_token": refresh_token} response2 = client.put("http://localhost:5000/v3/tokens", data=json.dumps(payload2), content_type='application/json') # Check the new access token assert response2.status_code == 200 access_token2 = response2.json['result']['access_token']['access_token'] # Make sure the custom claim is still there access_token_data2 = auth.validate_token(access_token2) assert access_token_data2['test_claim'] == "here it is!"
def validate_access_token(response): """ Validate the a response has an access token and it is properly formatted. """ assert 'access_token' in response.json['result']['access_token'] assert 'expires_at' in response.json['result']['access_token'] assert 'expires_in' in response.json['result']['access_token'] assert 'jti' in response.json['result']['access_token'] claims = validate_token(response.json['result']['access_token']['access_token']) assert claims['tapis/tenant_id'] == TEST_TENANT_ID assert claims['tapis/username'] == TEST_USERNAME assert claims['sub'] == f'{TEST_USERNAME}@{TEST_TENANT_ID}' return claims
def validate_refresh_token(response): """ Validate that a response has a refresh token and it is properly formatted. """ assert 'refresh_token' in response.json['result']['refresh_token'] assert 'expires_at' in response.json['result']['refresh_token'] assert 'expires_in' in response.json['result']['refresh_token'] assert 'jti' in response.json['result']['refresh_token'] claims = validate_token(response.json['result']['refresh_token']['refresh_token']) assert claims['tapis/token_type'] == 'refresh' assert claims['tapis/tenant_id'] == TEST_TENANT_ID # the refresh token embeds the access token claims within: assert 'tapis/access_token' in claims print(claims['tapis/access_token']) assert claims['tapis/access_token']['sub'] == f'{TEST_USERNAME}@{TEST_TENANT_ID}' return claims
def put(self): logger.debug("top of PUT /tokens") validator = RequestValidator(utils.spec) validated = validator.validate(FlaskOpenAPIRequest(request)) if validated.errors: raise errors.ResourceError(msg=f'Invalid PUT data: {validated.errors}.') refresh_token = validated.body.refresh_token logger.debug(f"type(refresh_token) = {type(refresh_token)}") try: refresh_token_data = auth.validate_token(refresh_token) except errors.AuthenticationError: raise errors.ResourceError(msg=f'Invalid PUT data: {request}.') # get the original access_token data from within the decoded refresh_token token_data = refresh_token_data['tapis/access_token'] token_data.pop('tapis/token_type') token_data['exp'] = TapisAccessToken.compute_exp(token_data['ttl']) token_data['jti'] = str(uuid.uuid4()) # create a dictionary of data that can be used to instantiate access and refresh tokens; the constructors # require variable names that do not include the Tapis prefix, so we need to remove that - new_token_data = { 'jti': token_data.pop('jti'), 'iss': token_data.pop('iss'), 'sub': token_data.pop('sub'), 'tenant_id': token_data.pop('tapis/tenant_id'), 'username': token_data.pop('tapis/username'), 'account_type': token_data.pop('tapis/account_type'), 'ttl': token_data.pop('ttl'), 'exp': token_data.pop('exp'), 'delegation': token_data.pop('tapis/delegation'), 'delegation_sub': token_data.pop('tapis/delegation_sub', None), 'extra_claims': token_data } access_token = TapisAccessToken(**new_token_data) access_token.sign_token() # add the original refresh token's initial_ttl claim as the ttl for the new refresh token new_token_data['refresh_token_ttl'] = refresh_token_data['tapis/initial_ttl'] refresh_token = TokensResource.get_refresh_from_access_token_data(new_token_data, access_token) result = {'access_token': access_token.serialize, 'refresh_token': refresh_token.serialize } return utils.ok(result=result, msg="Token generation successful.")
def test_custom_claims_show_up_in_access_token(client): payload = { "token_tenant_id": "admin", "account_type": "service", "token_username": "******", "generate_refresh_token": True, "claims": { "test_claim": "here it is!" }, "target_site_id": "admin" } response = client.post("http://localhost:5000/v3/tokens", data=json.dumps(payload), content_type='application/json', headers=get_basic_auth_header()) print(f"response.data: {response.data}") assert response.status_code == 200 access_token = response.json['result']['access_token']['access_token'] access_token_data = auth.validate_token(access_token) assert access_token_data['test_claim'] == "here it is!"