def test_the_is_token_revoked_method_of_user_repository(app, mocker): """ GIVEN the TokenRepository instance WHEN the is_token_revoked() method is call THEN check session method calls """ from app.model import TokenRepository, Token token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() token = Token() token.id = 1 token.jti = "27d1b1a3-45b4-4a5f-83ed-b823f5ea1dbe" token.token_type = "access" token.user_identity = "test" token.revoked = True token.expires = datetime.now() token_repository.session.add(token) token_repository.session.commit() decoded_token = mocker.MagicMock() decoded_token['jti'] = token.jti result = token_repository.is_token_revoked(decoded_token) assert result (token_repository.session.query.return_value.filter_by. assert_called_once_with(jti=decoded_token['jti']))
def test_the_change_token_revoking_method_of_user_repository(app): """ GIVEN the TokenRepository instance WHEN the save() method is call THEN check session method calls and the token revoke value """ from app.model import TokenRepository, Token token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() token = Token() token.id = 1 token.jti = "27d1b1a3-45b4-4a5f-83ed-b823f5ea1dbe" token.token_type = "access" token.user_identity = "test" token.revoked = False token.expires = datetime.now() token_repository.session.add(token) token_repository.session.commit() token_repository.change_token_revoking(1, "test", True) (token_repository.session.query.return_value.filter_by. assert_called_once_with(id=1, user_identity="test")) assert token.revoked == True
def test_the_is_invalid_method_of_token_repository(app): """ GIVEN the TokenRepository instance WHEN the is_invalid() method is call THEN check the returned value """ from app.model import TokenRepository token_repository = TokenRepository() assert token_repository.is_invalid(object) == []
def test_the_change_token_revoking_method_of_user_repository_with_inexistent_token( app): """ GIVEN the TokenRepository instance WHEN the save() method is call with inexistent_token THEN check TokenNotFound exception throwing """ from app.model import TokenRepository, Token from app.exceptions import TokenNotFound token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() with pytest.raises(TokenNotFound): token_repository.change_token_revoking(100, 'test', True)
def check_if_token_in_blacklist(decoded_token): """Callback to check if a token is in the blacklist. Parameters: decrypted_token (dict): a jwt token decrypted into a dictionary. """ from app.model import TokenRepository return TokenRepository().is_token_revoked(decoded_token)
def test_the_save_method_of_user_repository(app): """ GIVEN the TokenRepository instance WHEN the save() method is call THEN check session method calls and the token returned """ from app.model import TokenRepository, Token token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() access_token_encoded = create_access_token("test") token = token_repository.save(access_token_encoded, app.config["JWT_IDENTITY_CLAIM"]) token_repository.session.add.assert_called_once_with(token) token_repository.session.commit.assert_called_once_with() assert token.user_identity == 'test'
def test_the_is_token_revoked_method_of_user_repository_with_inexistent_token( app, mocker): """ GIVEN the TokenRepository instance WHEN the is_token_revoked() method is call with inexistent token THEN check session method calls """ from app.model import TokenRepository, Token token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() decoded_token = mocker.MagicMock() decoded_token['jti'] = "xxxxxxxxxxxxxx" result = token_repository.is_token_revoked(decoded_token) assert result (token_repository.session.query.return_value.filter_by. assert_called_once_with(jti=decoded_token['jti']))
def refresh(): """Create a new access token. Returns: response: flask.Response object with the application/json mimetype. """ current_user = get_jwt_identity() access_token_encoded = create_access_token(identity=current_user) token_repository = TokenRepository() token_repository.save(access_token_encoded, current_app.config["JWT_IDENTITY_CLAIM"]) return make_response( jsonify({ 'status': 'success', 'data': { 'access_token': access_token_encoded } }), 200)
def auth(app, request): """Creates HTTP authorization header. Parameters: app (flask.app.Flask): The application instance. request (FixtureRequest): A request for a fixture from a test or fixture function Returns: headers: a dictionary with HTTP authorization header for a basic authentication """ from flask_jwt_extended import ( jwt_required, create_access_token, create_refresh_token ) from app.model import TokenRepository access_token_encoded = create_access_token(identity='test') refresh_token_encoded = create_refresh_token(identity='test') token_repository = TokenRepository() token_repository.save(access_token_encoded, app.config["JWT_IDENTITY_CLAIM"]) token_repository.save(refresh_token_encoded, app.config["JWT_IDENTITY_CLAIM"]) headers = { 'access_token': {'Authorization': 'Bearer ' + access_token_encoded}, 'refresh_token': {'Authorization': 'Bearer ' + refresh_token_encoded}, } return headers
def get_tokens(): """Retrieve all tokens of the user. Returns: response: flask.Response object with the application/json mimetype. """ user_identity = get_jwt_identity() tokens = TokenRepository().get_user_tokens(user_identity) data = [i.serialize() for i in tokens] return make_response(jsonify({'status': 'success', 'data': data}), 200)
def test_create_new_token_repository(app): """ GIVEN the TokenRepository class WHEN a new TokenRepository is created THEN check the TokenRepository and the SQLAlchemy session instances """ from app.model import TokenRepository token_repository = TokenRepository() assert isinstance(token_repository, TokenRepository) assert isinstance(token_repository.session, sqlalchemy.orm.scoping.scoped_session)
def test_the_get_user_tokens_method_of_user_repository(app): """ GIVEN the TokenRepository instance WHEN the get_user_tokens() method is call THEN check the token returned """ from app.model import TokenRepository, Token token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() jti = "27d1b1a3-45b4-4a5f-83ed-b823f5ea1dbe" token_type = "access" user_identity = "test" revoked = True expires = datetime.now() token = Token(jti, token_type, user_identity, revoked, expires) token_repository.session.add(token) token_repository.session.commit() serialized_data = { 'id': str(token.id), 'jti': jti, 'token_type': token_type, 'user_identity': user_identity, 'revoked': revoked, 'expires': expires } result = token_repository.get_user_tokens('test')[0] assert result.jti == jti assert result.token_type == token_type assert result.user_identity == user_identity assert result.revoked == revoked assert result.expires == expires assert result.serialize() == serialized_data assert str(result) == '<Token %r>' % (jti)
def test_the_revoke_all_tokens_method_of_user_repository(app): """ GIVEN the TokenRepository instance WHEN the revoke_all_tokens() method is call THEN check session method calls """ from app.model import TokenRepository, Token token_repository = TokenRepository() token_repository.session = UnifiedAlchemyMagicMock() acc_token = Token() acc_token.id = 1 acc_token.jti = "27d1b1a3-45b4-4a5f-83ed-b823f5ea1dbe" acc_token.token_type = "access" acc_token.user_identity = "test" acc_token.revoked = False acc_token.expires = datetime.now() token_repository.session.add(acc_token) ref_token = Token() ref_token.id = 2 ref_token.jti = "27d1b1a3-45b4-4a5f-83ed-b823f5ea1dbd" ref_token.token_type = "refresh" ref_token.user_identity = "test" ref_token.revoked = False ref_token.expires = datetime.now() token_repository.session.add(ref_token) token_repository.session.commit() token_repository.revoke_all_tokens("test") (token_repository.session.query.return_value.filter_by. assert_called_once_with(user_identity="test")) (token_repository.session.query.return_value.filter_by.return_value.update. assert_called_once_with({Token.revoked: True}))
def delete_account() -> Response: """Deletes the user account. Returns: response: flask.Response object with the application/json mimetype. """ user_identity = get_jwt_identity() user_repository = UserRepository() user = user_repository.get_by_username(user_identity) if user: user_repository.delete(user) TokenRepository().revoke_all_tokens(user_identity) return make_response('', 201) abort(404)
def login() -> Response: """Login of the user by creating a valid token. Returns: response: flask.Response object with the application/json mimetype. """ data = request.json # checkint the json data if not request.is_json or not data.get('username') or not data.get( 'password'): abort(400) # authenticating the user user = UserRepository().authenticate(data.get('username'), data.get('password')) if not user: response = make_response( jsonify({ 'status': 'fail', 'message': 'Username or Password not valid' }), 401) else: access_token_encoded = create_access_token(identity=user.username) refresh_token_encoded = create_refresh_token(identity=user.username) token_repository = TokenRepository() token_repository.save(access_token_encoded, current_app.config["JWT_IDENTITY_CLAIM"]) token_repository.save(refresh_token_encoded, current_app.config["JWT_IDENTITY_CLAIM"]) response = make_response( jsonify({ 'status': 'success', 'data': { 'access_token': access_token_encoded, 'refresh_token': refresh_token_encoded } }), 200) return response
def modify_token(token_id: int): """Modifies the revocation status of a token. Parameters: token_id (int): Token ID to be changed. Returns: response: flask.Response object with the application/json mimetype. """ if not request.is_json: abort(400) revoke = request.json.get('revoke', None) if revoke is None or not isinstance(revoke, bool): abort(400) # Revoke or unrevoke the token based on what was passed to this function user_identity = get_jwt_identity() try: token_repository = TokenRepository() if revoke: token_repository.change_token_revoking(token_id, user_identity, True) return make_response( jsonify({ 'status': 'success', 'message': 'Token revoked' }), 200) else: token_repository.change_token_revoking(token_id, user_identity, False) return make_response( jsonify({ 'status': 'success', 'message': 'Token unrevoked' }), 200) except TokenNotFound: return make_response( jsonify({ 'status': 'fail', 'message': 'The specified token was not found' }), 404)