-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
146 lines (117 loc) · 3.46 KB
/
server.py
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import flask
import db
from werkzeug.security import generate_password_hash, check_password_hash
from werkzeug.exceptions import HTTPException
import jwt
import datetime
import os
import time
import dotenv
# Const check
dotenv.load_dotenv()
SECRET_KEY = os.getenv("SECRET_KEY")
if not SECRET_KEY:
print('SECRET_KEY ERROR')
exit()
HOST = os.getenv("HOST_IP")
if not HOST:
print('HOST_IP ERROR')
exit()
# Error const
INVALID_TOKEN_ERROR = 'invalid token'
app = flask.Flask(__name__)
db.init()
def exp_tommorow():
"""вернёт время через 24 часа
Returns:
datetime: Время через 24 часа
"""
return datetime.datetime.now() + datetime.timedelta(days=1)
def check_token(token: str):
"""Проверка jwt токена
Args:
token (str):
Returns:
dict: Словарь с полями
{
'username': str,
'user_id': int,
'exp': int
}
Или
None: Тогда токен недействителен
"""
try:
user = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
# Проверка на время действия токена
if user['exp'] < time.time():
return
else:
return user
except jwt.exceptions.DecodeError:
return
def check_valid(func):
"""Декоратор для проверки валидности токена
"""
def check_token_decorator(*args, **kwargs):
args_f = flask.request.args
token = args_f['token']
user = check_token(token)
flask.request.user = user
if not user:
return flask.abort(400, INVALID_TOKEN_ERROR)
return func(*args, **kwargs)
return check_token_decorator
@app.route('/login')
def check_login():
args = flask.request.args
login = args['login']
passw = args['password']
user = db.get_user(login)
try:
if check_password_hash(user.pwhash, passw):
return jwt.encode({'username': login, 'user_id': user.id, 'exp': exp_tommorow()},
SECRET_KEY, algorithm='HS256')
except AttributeError:
return flask.abort(400, 'Check password or username')
@app.route('/register')
def register():
args = flask.request.args
login = args['login']
passw = args['password']
if db.get_user(login):
return flask.abort(400, 'username_exists')
db.create_user(login, generate_password_hash(passw))
return 'ok'
@app.route('/new_thread', endpoint='create_thread')
@check_valid
def create_thread():
args = flask.request.args
username = args['username']
user = flask.request.user
try:
db.create_thread(user['username'], username)
except Exception:
return flask.abort(400, 'user not found')
return 'ok'
@app.route('/send_message', endpoint='send_message')
@check_valid
def send_message():
args = flask.request.args
text = args['text']
thread_id = args['thread_id']
user = flask.request.user
db.create_message(text, thread_id, user['user_id'])
return 'ok'
@app.route('/get_threads', endpoint='get_thread')
@check_valid
def get_thread():
user = flask.request.user
return db.get_threads(user['user_id'])
@app.route('/get_messages', endpoint='messages')
@check_valid
def messages():
thread_id = flask.request.args['thread_id']
return db.get_messages(thread_id)
if __name__ == "__main__":
app.run(HOST, 80)