-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathviews.py
More file actions
122 lines (105 loc) · 3.17 KB
/
Copy pathviews.py
File metadata and controls
122 lines (105 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from time import time
from apiflask import abort
from apiflask import APIBlueprint
from authlib.jose import jwt
from authlib.jose.errors import JoseError
from flask import current_app
from ...extensions import auth
from ...extensions import db
from ...models import User
from .schemas import LoginSchema
from .schemas import RegisterSchema
# create authentication blueprint for API v4
auth_bp = APIBlueprint("auth", __name__, url_prefix="/auth")
@auth.verify_token
def verify_token(token: str):
"""
verify token and returns user
"""
try:
data = jwt.decode(token.encode("ascii"), current_app.config["SECRET_KEY"])
if data.get("time") + 3600 * 24 * 30 > time():
user = User.query.get(data.get("uid")) # None if user does not exist
if (
user
and user.password_update
and user.password_update > data.get("time")
):
return None
else:
raise JoseError("Token expired")
except JoseError:
return None
else:
user.ping()
return user
@auth_bp.get("/")
@auth_bp.get("/help")
def help(): # pragma: no cover
"""
help API of blueprint
"""
return {
"/help": "help API of blueprint",
"/login": "sign in and get API auth token",
"/register": "create a new account",
}
@auth_bp.post("/login")
@auth_bp.input(LoginSchema)
def login(data):
"""
sign in and get API auth token
"""
username, password = data["username"], data["password"]
user = User.query.filter_by(username=username).first()
email = User.query.filter_by(email=username).first()
if not (user or email):
abort(404)
user = user or email
if not user.verify_password(password):
abort(403)
return {"auth_token": "Bearer " + user.auth_token()}, 200
@auth_bp.post("/register")
@auth_bp.input(RegisterSchema)
def register(data):
"""
create a new account
"""
u = User()
for key, value in data.items():
if key == "password":
u.set_password(value)
continue
elif key == "username" and User.query.filter_by(username=value).first():
return {"message": "username already exists"}, 400
elif key == "email" and User.query.filter_by(email=value).first():
return {"message": "email already exists"}, 400
setattr(u, key, value)
db.session.add(u)
db.session.commit()
return {"message": "ok"}
# TODO: finish these after send_mail has been implemented.
# @auth_bp.get("/confirm/send")
# @auth_bp.auth_required
# def send_confirmation():
# me: User = g.current_user
# token = me.gen_email_verify_token()
# send_email(
# [me.email],
# "Confirm Your Account",
# "confirm",
# username=me.username,
# token=token,
# mode=2,
# )
# return {"message": "ok"}
# @auth_bp.get("/confirm")
# @auth.login_required
# @auth_bp.input(EmailConfirmationSchema)
# def confirm(data):
# me: User = g.current_user
# token = data["token"]
# if me.verify_email_token(token):
# return {"message": "ok"}
# else:
# return {"message": "failed"}