def test_valid_request_correct_url_code(self, other_private_jwk): '''Ensure that the a code url parameter is passed and is valid ''' url_args = { 'grand_type': 'authorization_code', 'client_secret': 'something', 'code': 'Not a valid token' } # ---> Invalid representation of JWS Format auth_token = oauth_code.AuthorisationToken(url_args=url_args) assert not auth_token.validate_request() assert 'non-valid representation' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 400 # ---> JWS has not been signed by us # Create a JWS with given payload and a different private key payload = {'dummy': 'data'} jws_obj = jws.JWS( json.dumps(payload).encode(config.Config.AUTH_CODE_ENCODING)) jws_obj.add_signature(other_private_jwk, None, json.dumps({"alg": config.Config.JWT_ALGORITHM})) auth_token.code = jws_obj.serialize(compact=True) assert not auth_token.validate_request() assert 'token that has not been signed in' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403
def post(self): if not isinstance(api.payload, dict): raise api_errors.BadRequest400Error( message='Incorrect type of object received. Instead a json object is expected', envelop=api_utils.RESPONSE_400) # Do we have all expected fields? expected_fields = authorization_code_dto.keys() for key in expected_fields: if key not in api.payload: raise api_errors.BadRequest400Error(message=f"Required key '{key}' not found", envelop=api_utils.RESPONSE_400) auth_code = oauth_code.AuthorisationToken(url_args={ 'grand_type': api.payload['grand_type'], 'code': api.payload['code'], 'client_secret': api.payload['client_secret'] }) # Validate request if not auth_code.validate_request(): if auth_code.errors['code'] == 400: raise api_errors.BadRequest400Error(message=auth_code.errors['error_description'], envelop=api_utils.RESPONSE_400) if auth_code.errors['code'] == 401: raise api_errors.NotAuthorization401(message=auth_code.errors['error_description'], envelop=api_utils.RESPONSE_401) raise api_errors.Forbidden403Error(message=auth_code.errors['error_description'], envelop=api_utils.RESPONSE_403) return {'token': auth_code.response(), 'token_type': 'bearer'}, 201, \ {'Cache-Control': 'no-store', 'Pragma': 'no-cache'}
def test_client_secret_provided(self): '''Ensure client_secret url parameter has been provided ''' url_args = { 'grand_type': 'authorization_code', 'code': 'Not a valid token' } auth_token = oauth_code.AuthorisationToken(url_args=url_args) assert not auth_token.validate_request() assert 'did not provide a client_secret' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 400
def test_response(self): '''Test the issuing of a Authorisation Token. A Token that encrypted by us should also be able to be decrypted by the public key. ''' auth_token = oauth_code.AuthorisationToken() signed_jwt_token = auth_token.response() assert len(signed_jwt_token.split('.')) == 3 raw_token = jwt.JWT(key=jwk.JWK.from_json(config.Config.JWK_PUBLIC), jwt=signed_jwt_token) payload = {'expires_in': config.Config.AUTH_TOKEN_EXPIRATION_TIME} assert json.loads(raw_token.claims) == payload
def test_valid_request_grand_type(self): '''Ensure grand_type url parameter is passed and valid ''' auth_token = oauth_code.AuthorisationToken(url_args=None) assert not auth_token.validate_request() assert all(keywords in auth_token.errors['error_description'] for keywords in ("'authorization_code'", 'grand_type')) assert auth_token.errors['code'] == 400 auth_token.grand_type = 'something unexpected' assert not auth_token.validate_request() assert all(keywords in auth_token.errors['error_description'] for keywords in ("'authorization_code'", 'grand_type')) assert auth_token.errors['code'] == 400 auth_token.grand_type = 'authorization_code' assert not auth_token.validate_request() assert 'authorisation code' in auth_token.errors['error_description'] assert auth_token.errors['code'] == 400
def test_valid_request_correct_url_code_payload_fields_and_values(self): '''Ensure that fields provided in the payload are those expected and the authorisation code provided was not used before ''' # Prepare underlying database so that an application and code exist client_data, user_data = test_utils.add_user_client_context_to_db() db_auth_code = models.AuthorisationCode( application_id=client_data[0]['id'], used=True) db.session.add(db_auth_code) db.session.commit() assert db_auth_code.id url_args = { 'grand_type': 'authorization_code', 'client_secret': 'something', 'code': 'Not a valid token' } auth_token = oauth_code.AuthorisationToken(url_args=url_args) with patch.object(oauth_code, 'jwk'): with patch.object(oauth_code, 'jws'): with patch.object(oauth_code.json, 'loads') as mock_loads: # If either client_id or code_id does not exist payload = { 'client_id': 'something that does not match our records', 'redirect_uri': '', 'expiration_date': '', 'code_id': db_auth_code.id } mock_loads.return_value = payload assert not auth_token.validate_request() assert 'Either the client does not exist' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 payload['client_id'] = db_auth_code.application_id payload['code_id'] = 5555555555 assert not auth_token.validate_request() assert 'Either the client does not exist' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 # If code has already being used payload['code_id'] = db_auth_code.id assert not auth_token.validate_request() assert "'authorization_code' already" in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 # If code has expired db_auth_code.used = False db.session.commit() now = datetime.utcnow() after = now + timedelta(seconds=10) payload['expiration_date'] = after.strftime( "%d-%m-%Y %H:%M:%S") assert not auth_token.validate_request() assert "expired" in auth_token.errors['error_description'] assert auth_token.errors['code'] == 403 # if client_id and client_secret do not coincide before = now - timedelta(seconds=10) payload['expiration_date'] = before.strftime( "%d-%m-%Y %H:%M:%S") assert not auth_token.validate_request() assert "that don't match" in auth_token.errors[ 'error_description'] auth_token.client_secret = 'no within the database' assert not auth_token.validate_request() assert "that don't match" in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 401 # if redirect_uri does not match our records auth_token.client_secret = client_data[0]['client_secret'] payload[ 'redirect_uri'] = 'something that does not exist in the db' assert not auth_token.validate_request() assert "'redirect_uri'" in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403
def test_valid_request_correct_url_code_payload_fields(self): '''Ensure all fields in the payload are the ones expected and are valid ''' url_args = { 'grand_type': 'authorization_code', 'client_secret': 'something', 'code': 'Not a valid token' } auth_token = oauth_code.AuthorisationToken(url_args=url_args) with patch.object(oauth_code, 'jwk'): with patch.object(oauth_code, 'jws'): with patch.object(oauth_code.json, 'loads') as mock_loads: # No fields mock_loads.return_value = {} assert not auth_token.validate_request() assert 'did not provide all the required fields' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 # only 'client_id' provided mock_loads.return_value = { 'client_id': '', } assert not auth_token.validate_request() assert 'did not provide all the required fields' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 # only 'client_id' and 'redirect_uri' provided mock_loads.return_value = { 'client_id': '', 'redirect_uri': '', } assert not auth_token.validate_request() assert 'did not provide all the required fields' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 # only 'client_id', 'redirect_uri' and 'expiration_date' provided mock_loads.return_value = { 'client_id': '', 'redirect_uri': '', 'expiration_date': '', } assert not auth_token.validate_request() assert 'did not provide all the required fields' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403 mock_loads.return_value = { 'client_id': '', 'redirect_uri': '', 'expiration_date': '', 'code_id': '' } # client_id and/or code_id are not recognised assert not auth_token.validate_request() assert 'Either the client does not exist' in auth_token.errors[ 'error_description'] assert auth_token.errors['code'] == 403