def logout(): """API can logout a user.""" #Token retrival auth_header = request.headers.get('Authorization', None) if not auth_header: response = jsonify({'message': 'No token provided!'}) response.status_code = 500 return response else: token = auth_header.split(" ") access_token = token[1] if access_token: user_id = User.decode_auth_token(access_token) if not isinstance(user_id, str): invalid_token = BlacklistToken(access_token) invalid_token.save() response = jsonify( {'message': 'You have successfully logged out'}) response.status_code = 200 return response else: response = jsonify({'message': user_id}) response.status_code = 401 return response else: response = jsonify({'message': 'Invalid token'}) response.status_code = 401 return response
def logout_user(user): """Log out a user --- tags: - "auth" parameters: - in : "header" name: "Authorization" description: "Token of logged in user" required: true type: "string" responses: 200: description: "Success" 401: description: "Failed" """ blacklist_token = BlacklistToken(token=user['auth_token']) try: blacklist_token.save() response = {'message': "Successfully logged out", 'status': "Success"} return make_response(jsonify(response)), 200 except Exception as error: response = {"message": error, "status": "Failed"} return make_response(jsonify(response)), 401
def post(self): """Endpoint to logout a user""" jti = get_raw_jwt()['jti'] blacklist = BlacklistToken(token=jti) blacklist.save() response = {'message': 'Successfully logged out'} return jsonify(response), 200
def post(self): # get auth token args = parser.parse_args() auth_header = args["Authorization"] if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = "" if auth_token: resp = User.decode_auth_token(auth_token) if not isinstance(resp, str): # mark the token as blacklisted blacklist_token = BlacklistToken(token=auth_token) try: # insert the token blacklist_token.save() responseObject = { "status": "success", "message": "Successfully logged out.", } return responseObject, 200 except Exception as e: responseObject = {"status": "fail", "message": e} return responseObject, 200 else: responseObject = {"status": "fail", "message": resp} return responseObject, 401 else: responseObject = { "status": "fail", "message": "Provide a valid auth token.", } return responseObject, 403
def user_logout(): """Logout resource.""" auth_header = request.headers.get("Authorization") if auth_header: try: auth_token = auth_header.split(" ")[1] except IndexError: response = {"status": "fail", "message": "Bearer token malformed."} return make_response(jsonify(response), 401) else: auth_token = "" if auth_token: response = User.decode_auth_token(auth_token) if not isinstance(response, str): # mark the token as blacklisted blacklist_token = BlacklistToken(token=auth_token) try: # insert the token blacklist_token.save() response = { "status": "success", "message": "Successfully logged out." } return make_response(jsonify(response), 200) except Exception as e: response = {"status": "fail", "message": e} return make_response(jsonify(response), 200) else: response = {"status": "fail", "message": response} return make_response(jsonify(response), 401) else: response = {"status": "fail", "message": "Provide a valid auth token."} return make_response(jsonify(response), 403)
def test_token_is_successfully_blacklisted(self): self.assertTrue(self.user.save()) user = User.query.filter_by(email=self.user.email).first() self.assertIsNotNone(user) self.assertEqual(user.email, self.user.email) token = user.generate_token(user.id) # generating the token self.assertIsInstance(token, bytes) # add the token to the BlacklistToken blacklist = BlacklistToken(str(token)) blacklist.save() self.assertTrue(blacklist.is_blacklisted(str(token)))
def blacklist_auth_token(current_user): """blacklist token""" auth_header = None if 'Authorization' in request.headers: auth_header = request.headers.get('Authorization') if auth_header: auth_token = list(filter(None, auth_header.split(" ")))[1] else: auth_token = '' if not auth_token: response = jsonify({'error': True, 'message': 'token is missing!'}) response.status_code = 401 return response is_token_blacklisted = BlacklistToken.blacklisted(auth_token) if is_token_blacklisted: response = jsonify({ 'error': True, 'message': 'Token already blacklisted' }) response.status_code = 401 return response try: data = jwt.decode(auth_token, current_app.config['SECRET'], algorithms=['HS256']) _current_user = User.get_by_public_id(data['public_id']) if not _current_user: response = jsonify({'error': True, 'message': 'token is invalid'}) response.status_code = 401 return response blacklist_token = BlacklistToken(auth_token) blacklist_token.save() return jsonify({"error": False, "message": "logout successful"}) except jwt.ExpiredSignatureError: response = jsonify({'error': True, 'message': 'token has expired'}) response.status_code = 401 return response except jwt.InvalidTokenError: response = jsonify({'error': True, 'message': 'token is invalid'}) response.status_code = 401 return response
def post(): """ User can only logout if and only if a user is logged in and has an authentication token. """ user_id, msg, status, status_code, token = parse_auth_header(request) if user_id is None: return jsonify({"status": status, "message": msg}), status_code user = User.query.filter_by(id=user_id).first() blacklist = BlacklistToken(token) if blacklist.save(): # blacklist token return jsonify({ "status": "success", "message": f"Successfully logged out '{user.email}'" }), 200
def post(self, user_type): args = parser.parse_args(strict=True) # Check aruments are valid or not error_mssgs = check_valid_request(args, endpoint='logout') # log_info(error_mssgs) # Error for invalid arguments if error_mssgs: return {'status': 'fail', 'msg': error_mssgs}, 400 auth_header = args.get('Authorization') if auth_header: try: # 'auth_header' format "Authorization: Bearer JWT_TOKEN" auth_token = auth_header.split(' ')[1] except IndexError: return {'status': 'fail', 'msg': 'Bearer token malformed'}, 400 else: return { 'status': 'fail', 'msg': "Provide valid 'Authorization' header" }, 403 if user_type == 'buyer': User = Buyer elif user_type == 'seller': User = Seller else: return {'status': 'fail', 'msg': 'Invalid endpoint'}, 404 decode = User.decode_auth_token(auth_token) if not isinstance(decode, str): # mark the token as blacklisted blacklist_token = BlacklistToken(token=auth_token) try: blacklist_token.save() response = { 'status': 'success', 'msg': 'Successfully logged out' } return response, 200 except Exception as e: return {'status': 'fail', 'msg': e}, 202 else: return {'status': 'fail', 'msg': decode}, 401
def logout(current_user, user_id): access_token = request.headers.get('Authorization') if user_id != User.decode_token(access_token): response = {'message': 'An error occured.'} return make_response(jsonify(response)), 403 try: # insert the token blacklist_token = BlacklistToken(token=access_token) blacklist_token.save() response = {'message': 'Successfully logged out.'} return make_response(jsonify(response)), 200 except Exception as e: response = {'message': e} return make_response(jsonify(response)), 400
def post(current_user, self): auth_token = request.headers['x-access-token'] blacklist_token = BlacklistToken(token=auth_token) try: blacklist_token.add() response = jsonify({"message": "Successfully logged out."}) response.status_code = 200 return response except Exception as e: response = jsonify({"message": e}) response.status_code = 200 return response
def logout(): """store the access_token in blacklist when a user logs out""" auth_header = request.headers.get('Authorization') access_token = auth_header.split(" ")[1] #check is the token is valid res = User.decode_auth_token(access_token) if isinstance(res, int) and not BlacklistToken.is_blacklisted(access_token): #the token is still valid and not in blasklist blasklisted_token = BlacklistToken(access_token) db.session.add(blasklisted_token) db.session.commit() return jsonify( {"message": "logout succees. Thank you for using Bright Events"}), 200 return jsonify({"message": "you are already logged out"}), 401
def logout(): # get auth token auth_header = request.headers.get("Authorization") if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = "" if auth_token: resp = User.decode_auth_token(auth_token) if not isinstance(resp, str): # mark the token as blacklisted blacklist_token = BlacklistToken(token=auth_token) try: # insert the token db.session.add(blacklist_token) db.session.commit() responseObject = { "status": "success", "message": "Successfully logged out.", } return make_response(jsonify(responseObject)), 200 except Exception as e: responseObject = {"status": "fail", "message": e} return make_response(jsonify(responseObject)), 200 else: responseObject = {"status": "fail", "message": resp} return make_response(jsonify(responseObject)), 401 else: responseObject = { "status": "fail", "message": "Provide a valid auth token." } return make_response(jsonify(responseObject)), 403
def test_valid_blacklisted_token_logout(self): """ Test for logout after a valid token gets blacklisted """ with self.client: # user registration register_resp = register_user(self) data_register = json.loads(register_resp.data.decode()) self.assertTrue( data_register['message'] == 'Registered successfully!') self.assertTrue(register_resp.content_type == 'application/json') self.assertEqual(register_resp.status_code, 201) # user login login_resp = login_user(self) data_login = json.loads(login_resp.data.decode()) self.assertTrue(data_login['message'] == 'Logged in successfully.') self.assertTrue(data_login['access_token']) self.assertTrue(login_resp.content_type == 'application/json') self.assertEqual(login_resp.status_code, 200) # blacklist a valid token blacklist_token = BlacklistToken( token=json.loads(login_resp.data.decode())['access_token']) db.session.add(blacklist_token) db.session.commit() # blacklisted valid token logout response = self.client.post( '/api/v1/auth/logout', headers=dict(Authorization=json.loads(login_resp.data.decode()) ['access_token'])) data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'fail') self.assertTrue( data['message'] == 'Token blacklisted. Please log in again.') self.assertEqual(response.status_code, 401)
def test_valid_blacklisted_token_logout(client): """ Test for logout after a valid token gets blacklisted """ # user registration resp_register = register_user(client) data_register = json.loads(resp_register.data.decode()) assert data_register['success'] assert data_register['message'] == 'Successfully registered.' assert data_register['auth_token'] assert resp_register.content_type == 'application/json' assert resp_register.status_code == 201 # user login resp_login = login_user(client) data_login = json.loads(resp_login.data.decode()) assert data_login['success'] assert data_login['message'] == 'Successfully logged in.' assert data_login['auth_token'] assert resp_login.content_type == 'application/json' assert resp_login.status_code == 200 # blacklist a valid token blacklist_token = BlacklistToken( token=json.loads(resp_login.data.decode())['auth_token']) db.session.add(blacklist_token) db.session.commit() # blacklisted valid token logout response = client.post( '/auth/logout', headers=dict(Authorization='Bearer ' + json.loads(resp_login.data.decode())['auth_token'])) data = json.loads(response.data.decode()) assert not data['success'] assert data['message'] == 'Token blacklisted. Please log in again.' assert response.status_code == 401
def test_valid_blacklisted_token_logout(self): resp_register = register_user(self, 'test', '*****@*****.**', 'test') data_register = json.loads(resp_register.data.decode()) self.assertTrue(data_register['status'] == 'success') self.assertTrue(data_register['message'] == 'Successfully registered.') self.assertTrue(data_register['auth_token']) self.assertTrue(resp_register.content_type == 'application/json') self.assertEqual(resp_register.status_code, 201) resp_login = login_user(self, 'test', 'test') data_login = json.loads(resp_login.data.decode()) self.assertTrue(data_login['status'] == 'success') self.assertTrue(data_login['message'] == 'Successfully logged in.') self.assertTrue(data_login['auth_token']) self.assertTrue(resp_login.content_type == 'application/json') self.assertEqual(resp_login.status_code, 200) blacklist_token = BlacklistToken( token=json.loads(resp_login.data.decode())['auth_token']) db.session.add(blacklist_token) db.session.commit() response = logout_user( self, json.loads(resp_login.data.decode())['auth_token']) data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'fail') self.assertTrue( data['message'] == 'Token blacklisted. Please log in again.') self.assertEqual(response.status_code, 401)
def wrap(*args, **kwargs): token = None if 'Authorization' in request.headers: token = request.headers['Authorization'] if not token: return jsonify({'message': 'Token is missing!'}), 403 is_blacklisted_token = BlacklistToken.check_blacklist(token) if is_blacklisted_token: return jsonify( {'message': 'Token blacklisted. Please log in again.'}), 403 try: # try to decode the token using our SECRET variable payload = jwt.decode(token, app.config['SECRET_KEY']) current_user = payload['sub'] # return current_user except jwt.ExpiredSignatureError: # the token is expired, return an error string return jsonify( {"messge": "Expired token. Please login to get a new token"}), 403 except jwt.InvalidTokenError: # the token is invalid, return an error string return jsonify( {'message': 'Invalid token. Please register or login'}), 403 return function(current_user, *args, **kwargs)
def logout_user(): auth_token = g.current_auth_token blacklist_token = BlacklistToken(token=auth_token) try: db.session.add(blacklist_token) db.session.commit() return successful('Successfully logged out.') except Exception as err: return server_error(str(err))
def delete(self): """Endpoint to delete a user account""" data = request.get_json() password = data.get('password') user_id = get_jwt_identity() jti = get_raw_jwt()['jti'] user_data = dict(password=password) if check_missing_field(**user_data): return jsonify(check_missing_field(**user_data)), 422 user = User.query.filter_by(id=user_id).first() if not user.password_is_valid(password): return self.generate_response(messages['valid_pass'], 401) user.delete() blacklist = BlacklistToken(token=jti) blacklist.save() return self.generate_response(messages['delete'], 200)
def put(self): """Endpoint to change a user password""" data = request.get_json() old_password = data.get('old_password') new_password = data.get('new_password') user_id = get_jwt_identity() jti = get_raw_jwt()['jti'] user_data = dict(old_password=old_password, new_password=new_password) if check_missing_field(**user_data): return jsonify(check_missing_field(**user_data)), 422 if check_password(new_password): return check_password(new_password) user = User.query.filter_by(id=user_id).first() if user and user.password_is_valid(old_password): password = Bcrypt().generate_password_hash(new_password).decode() user.update(user, password=password) blacklist = BlacklistToken(token=jti) blacklist.save() return self.generate_response(messages['password'], 201) return self.generate_response(messages['valid_pass'], 401)
def save_token(token): blacklist_token = BlacklistToken(token) try: db.session.add(blacklist_token) db.session.commit() response_object = { "status": "success", "message": "Successfully logged out." } return response_object, 200 except Exception as e: response_object = {"status": "fail", "message": e} return response_object, 200
def save_token(token): blacklist_token = BlacklistToken(token=token) try: # insert the token db.session.add(blacklist_token) db.session.commit() response_object = { 'status': 'success', 'message': 'Successfully logged out.' } return Response.jsonify(status=200, message=response_object) except Exception as e: response_object = {'status': 'fail', 'message': e} return Response.jsonify(status=200, message=response_object)
def test_verify_token_fails_if_the_token_is_already_blacklisted(self): self.assertTrue(self.user.save()) user = User.query.filter_by(email=self.user.email).first() self.assertIsNotNone(user) self.assertEqual(user.email, self.user.email) token = user.generate_token(user.id) # generating the token self.assertIsInstance(token, bytes) # add the token to the BlacklistToken BlacklistToken(str(token)).save() user_id, err = user.verify_token(token) self.assertIsNotNone(err) self.assertEqual(err, 'token has already expired: please re-login') self.assertIsNone(user_id)
def post(self, user_in_session): """Method to logout the user User logout --- tags: - Authentication responses: 200: description: User logged out successfully 400: description: Invalid access token 409: description: The user is already logged out! """ access_token = request.headers.get('x-access-token') if access_token: user_details = Users.query.filter_by(id=user_in_session).first() save_tokens = BlacklistToken(token=access_token) save_tokens.save() return make_response(jsonify({'message': 'User '+str(user_details.username) + ' logged out successfully'})), 200 return make_response(jsonify({'message': 'Invalid access token'})), 400
def post(): """Makes a post request of the user valid token and black lists it if still valid""" # get auth token auth_header = request.headers.get('Authorization') access_token = auth_header.split(" ")[1] if access_token: resp = User.decode_token(access_token) if isinstance(resp, int): # mark the token as blacklisted blacklist_token = BlacklistToken(token=access_token) try: blacklist_token.save() response_object = jsonify({ 'status': 'success', 'message': 'Successfully logged out.' }) return make_response(response_object), 200 except Exception as error: response_object = jsonify({ 'status': 'fail', 'message': error }) return make_response(response_object), 200 response_object = {'status': 'fail', 'message': resp} return make_response(jsonify(response_object)), 401 response_object = { 'status': 'fail', 'message': 'Provide a valid auth token.' } return make_response(jsonify(response_object)), 403
def test_valid_blacklisted_token_user(self): resp_register = register_user(self, 'test', '*****@*****.**', 'test') blacklist_token = BlacklistToken( token=json.loads(resp_register.data.decode())['auth_token']) db.session.add(blacklist_token) db.session.commit() response = get_user_status( self, json.loads(resp_register.data.decode())['auth_token']) data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'fail') self.assertTrue( data['message'] == 'Token blacklisted. Please log in again.') self.assertEqual(response.status_code, 401)
def logout(): auth_header = request.headers.get('Authorization') if auth_header: auth_token = auth_header.split(" ")[1] else: auth_token = '' if auth_token: response = User.decode_auth_token(auth_token) if not isinstance(response, str): #Mark token as blacklisted blacklist_token = BlacklistToken(token=auth_token) try: blacklist_token.save() response_object = { 'status': 'success', 'message': 'Successfully logged out.' } return jsonify(response_object), 200 except Exception as e: response_object = { 'status': 'fail', 'message': e } return jsonify(response_object), 500 else: response_object = { 'status': 'fail', 'message': resp } return jsonify(response_object), 401 else: response_object = { 'status': 'fail', 'message': 'Please return a valid auth token.' } return jsonify(response_object), 403
def test_valid_blacklisted_token_user(client): """ Test for user status with a blacklisted valid token """ resp_register = register_user(client) # blacklist a valid token blacklist_token = BlacklistToken( token=json.loads(resp_register.data.decode())['auth_token']) db.session.add(blacklist_token) db.session.commit() response = client.get( '/auth/status', headers=dict(Authorization='Bearer ' + json.loads(resp_register.data.decode())['auth_token'])) data = json.loads(response.data.decode()) assert not data['success'] assert data['message'] == 'Token blacklisted. Please log in again.' assert response.status_code == 401
def logout(): auth_header = request.headers.get('Authorization') auth_token = auth_header.split(' ')[0] if auth_token: decoded = Users.decode_auth_token(auth_token) if isinstance(decoded, str): responseObject = {'status': 'error', 'message': decoded} return jsonify(responseObject), 401 else: blacklist_token = BlacklistToken(token=auth_token) db.session.add(blacklist_token) db.session.commit() responseObject = {'status': 'success', 'message': 'Logged out.'} return jsonify(responseObject), 200 else: responseObject = {'status': 'error', 'message': 'Invalid token.'} return jsonify(responseObject), 403
def decode_access_token(access_token): """ Validates the user access token :param str access_token: The access token tp be decoded :return: integer|string """ try: payload = jwt.decode(access_token, APP.config.get('SECRET_KEY')) is_blacklisted_token = BlacklistToken.check_blacklisted(access_token) if is_blacklisted_token: return 'Token blacklisted. Please log in again.' public_id = payload['sub'] user = User.query.filter_by(public_id=public_id).first() return user.id except jwt.ExpiredSignatureError: return 'Signature expired. Please log in again.' except jwt.InvalidTokenError: return 'Invalid token. Please log in again.'