Skip to content

Commit 508c7dd

Browse files
authored
Merge branch 'master' into add_user_logout_using_blacklist
2 parents dd9a9e8 + 5fdb340 commit 508c7dd

File tree

7 files changed

+38
-10
lines changed

7 files changed

+38
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.vscode/
12
*.pyc
23
.idea/
34
__pycache__/

section11/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ tips:
8383
Introduce the concept of `claims`, it's just the data we choose to attach to the JWT payload. Use the `Item.delete()` endpoint as example, we make it only accessible by authenticated admins. So we need to configure the claims in `app.py` and decide whether a user is an admin, then we add a boolean claim `is_admin` to the JWT payload.
8484

8585
tips:
86-
- `get_jwt_oidentity()` now as opposed to `current_identity`
86+
- `get_jwt_identity()` now as opposed to `current_identity`
8787
- The identity is just the user id now as opposed to a UserModel object.
8888

8989
### Half protected endpoints

section11/app.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,34 @@
44

55
from db import db
66
from blacklist import BLACKLIST
7-
from resources.user import UserRegister, UserLogin, TokenRefresh, UserLogout
7+
from resources.user import UserRegister, UserLogin, User, TokenRefresh, UserLogout
88
from resources.item import Item, ItemList
99
from resources.store import Store, StoreList
1010

1111
app = Flask(__name__)
1212
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
1313
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
14+
app.config['PROPAGATE_EXCEPTIONS'] = True
1415
api = Api(app)
15-
db.init_app(app)
1616

1717
"""
18-
JWT related configurations began. The following functions includes:
18+
JWT related configuration. The following functions includes:
1919
1) add claims to each jwt
2020
2) customize the token expired error message
2121
"""
22-
app.config['JWT_SECRET_KEY'] = 'jose' # we can also use app.secret like before, Flask-JWT-Extended can recognize both
22+
app.config['JWT_SECRET_KEY'] = 'jose' # we can also use app.secret like before, Flask-JWT-Extended can recognize both
2323
app.config['JWT_BLACKLIST_ENABLED'] = True # enable blacklist feature
2424
app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh'] # allow blacklisting for access and refresh tokens
2525
jwt = JWTManager(app)
2626

2727
"""
28-
`claims` are data we choose to attached to each jwt payload
28+
`claims` are data we choose to attach to each jwt payload
2929
and for each jwt protected endpoint, we can retrieve these claims via `get_jwt_claims()`
3030
one possible use case for claims are access level control, which is shown below
3131
"""
32-
33-
3432
@jwt.user_claims_loader
3533
def add_claims_to_jwt(identity):
36-
if identity == 1: # instead of hard-coding, we can read from a config file to get a list of admins instead
34+
if identity == 1: # instead of hard-coding, we should read from a config file to get a list of admins instead
3735
return {'is_admin': True}
3836
return {'is_admin': False}
3937

@@ -99,8 +97,10 @@ def create_tables():
9997
api.add_resource(ItemList, '/items')
10098
api.add_resource(UserRegister, '/register')
10199
api.add_resource(UserLogin, '/login')
100+
api.add_resource(User, '/user/<int:user_id>')
102101
api.add_resource(TokenRefresh, '/refresh')
103102
api.add_resource(UserLogout, '/logout')
104103

105104
if __name__ == '__main__':
105+
db.init_app(app)
106106
app.run(port=5000, debug=True)

section11/requirement.txt

-108 Bytes
Binary file not shown.

section11/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Flask-JWT-Extended
2+
Flask-RESTful
3+
Flask-SQLAlchemy

section11/resources/item.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,7 @@ def get(self):
8080
items = [item.json() for item in ItemModel.find_all()]
8181
if user_id:
8282
return {'items': items}, 200
83-
return {'items': [item['name'] for item in items]}, 401
83+
return {
84+
'items': [item['name'] for item in items],
85+
'message': 'More data available if you log in.'
86+
}, 200

section11/resources/user.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ def post(self):
6262
return {"message": "Successfully logged out"}, 200
6363

6464

65+
class User(Resource):
66+
"""
67+
This resource can be useful when testing our Flask app. We may not want to expose it to public users, but for the
68+
sake of demonstration in this course, it can be useful when we are manipulating data regarding the users.
69+
"""
70+
@classmethod
71+
def get(cls, user_id: int):
72+
user = UserModel.find_by_id(user_id)
73+
if not user:
74+
return {'message': 'User Not Found'}, 404
75+
return {'user': user.json()}, 200
76+
77+
@classmethod
78+
def delete(cls, user_id: int):
79+
user = UserModel.find_by_id(user_id)
80+
if not user:
81+
return {'message': 'User Not Found'}, 404
82+
user.delete_from_db()
83+
return {'message': 'User deleted.'}, 200
84+
85+
6586
class TokenRefresh(Resource):
6687
@jwt_refresh_token_required
6788
def post(self):

0 commit comments

Comments
 (0)