Skip to content

Commit

Permalink
Merge pull request #31 from JoshuaOndieki/ft-logout-158791514
Browse files Browse the repository at this point in the history
[Delivers #158791514] Logout API Endpoint
  • Loading branch information
JoshuaOndieki committed Jul 6, 2018
2 parents f2aed3b + 9c74706 commit 8cdf8d5
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 3 deletions.
10 changes: 10 additions & 0 deletions ridemyway/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ def create_app(config_name):
app.jwt = JWTManager(app)
app.blacklist = set()

@app.jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
"""
Checks whether the identity of the token is blacklisted
Returns:
True if it's blacklisted, false otherwise
"""
jti = decrypted_token['jti'] # JWT ID
return jti in app.blacklist

@app.route('/')
def api_docs():
""" Route to the api docs"""
Expand Down
18 changes: 18 additions & 0 deletions ridemyway/api/v2/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
"""
import json
from flask_restful import Resource, reqparse
from flask_jwt_extended import jwt_required, get_raw_jwt
from flask import current_app as app

from .controllers.auth import AuthController
from ridemyway.utils import errors
from ridemyway.utils.response import Response


auth = AuthController()
Expand Down Expand Up @@ -72,3 +75,18 @@ def post(self):
if login_errors:
return json.loads(json.dumps(login_errors)), 422
return auth.login(**self.data)


class Logout(Resource):
"""
Logs out a user and revokes the token
"""
@jwt_required
def post(self):
"""
Revokes a token and blacklists it.
"""
self.jti = get_raw_jwt()['jti']
app.blacklist.add(self.jti)
message = 'Log out successful'
return Response.success(message=message)
1 change: 1 addition & 0 deletions ridemyway/api/v2/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@
# Add routes here
add(r.Signup, '/auth/signup') # POST
add(r.Login, '/auth/login') # POST
add(r.Logout, '/auth/logout') # POST
38 changes: 38 additions & 0 deletions ridemyway/tests/tests_v2/test_auth/test_logout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
This module tests logout
"""
import unittest
import json

from ridemyway.tests.tests_v2 import V2BaseTest
from ridemyway.tests.tests_v2.urls import SIGNUP, LOGIN, LOGOUT
from ridemyway.tests.tests_v2.data import VALID_DRIVER


class TestLogout(V2BaseTest):
"""
Tests logout API endpoint
- Auth: '/api/v2/auth/logout' # POST
"""

def test_user_can_logout_successfully(self):
self.client().post(SIGNUP, data=VALID_DRIVER)
self.response = self.client().post(LOGIN, data=VALID_DRIVER)
result = json.loads(self.response.data.decode())
access_token = result['access_token']
self.response = self.client().post(LOGOUT,
headers=dict(
Authorization="Bearer " +
access_token))
# Attempt to logout again
self.response = self.client().post(LOGOUT,
headers=dict(
Authorization="Bearer " +
access_token))
self.assertEqual(self.response.status_code, 401,
msg='Should return 401 status code for' +
' use of blacklisted token')


if __name__ == '__main__':
unittest.main()
1 change: 1 addition & 0 deletions ridemyway/tests/tests_v2/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

SIGNUP = ROOT_URL + '/auth/signup'
LOGIN = ROOT_URL + '/auth/login'
LOGOUT = ROOT_URL + '/auth/logout'

USER = ROOT_URL + '/users'

Expand Down
4 changes: 1 addition & 3 deletions ridemyway/utils/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def success(**kwargs):
"""
success_response = {
'status': 'success',
'meta': {},
'message': '',
}
for item in kwargs:
Expand All @@ -53,8 +52,7 @@ def failed(**kwargs):
"""
fail_response = {
'status': 'failed',
'message': '',
'meta': {}
'message': ''
}
for item in kwargs:
fail_response[item] = kwargs[item]
Expand Down

0 comments on commit 8cdf8d5

Please sign in to comment.