-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.py
132 lines (112 loc) · 4.2 KB
/
api.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
import time
import math
import os
import string
from flask import Blueprint, request, redirect, make_response
from bcrypt import checkpw
import jwt
import DBHelper
from misc import error, host_limit, auth
from config import JWT_EXP
api = Blueprint(name="api", import_name=__name__)
# Users
@api.route("/login", methods = ["POST"])
@host_limit("panel")
def login():
# arguments
username = request.form.get("username")
password = request.form.get("password")
if (username is None) or (password is None):
return error("Invalid arguments"), 400
username, password = str(username), str(password)
if (len(username) == 0) or (len(password) == 0):
return error("Invalid arguments"), 400
# get user
user = DBHelper.select_user_with_username(username)
if user is None:
return error("Login failed"), 401
# check password
if checkpw(password.encode("utf-8"), user[1].encode("utf-8")):
# jwt
key = os.getenv("JWT_KEY", None)
payload = {
"user": username,
"exp": math.floor(time.time()) + JWT_EXP
}
token = jwt.encode(payload=payload, key=key, algorithm="HS256")
resp = make_response(redirect("/panel"))
resp.set_cookie("token", token, httponly=True)
return resp
else:
return error("Login failed!"), 401
@api.route("/register", methods = ["POST"])
@host_limit("panel")
def register():
# arguments
username = request.form.get("username")
password = request.form.get("password")
if (username is None) or (password is None):
return error("Invalid arguments"), 400
username, password = str(username), str(password)
if (len(username) == 0) or (len(password) == 0):
return error("Invalid arguments"), 400
# 確定是否有重複用戶
result = DBHelper.select_user_with_username(username=username)
if not(result is None):
return error("User already exists!"), 400
# 註冊
DBHelper.insert_user(username=username, password=password)
return redirect("/login")
# Lao 佬
@api.route("/page", methods=["POST"])
@host_limit("panel")
def new_page():
opuser = auth()
if opuser:
# arguments
subdomain = request.form.get("subdomain", None)
color = request.form.get("color", None)
name = request.form.get("name", None)
if (subdomain is None) or (color is None) or (name is None):
return error("Invalid arguments"), 400
subdomain, color, name = str(subdomain), str(color), str(name)
if (len(subdomain) == 0) or (len(name) == 0) or (len(color) != 7) or \
(subdomain == "panel"): # subdomain 不能是 panel
return error("Invalid arguments"), 400
# check subdomain
for _ in subdomain: # 檢查不合法字元
if not(_ in (string.ascii_letters + string.digits + "-")):
return error("Invalid subdomain"), 400
if subdomain.startswith("-") or subdomain.endswith("-"):
return error("Invalid subdomain"), 400
# 檢查重複subdomain
repeated = DBHelper.select_lao_with_subdomain(subdomain=subdomain)
if repeated:
return error("Subdomain is already exists"), 400
# check color
try:
color = int(color[1:], 16)
except:
return error("Invalid color"), 400
# insert
DBHelper.insert_lao(subdomain=subdomain,
name=name,
color=color,
userhash=DBHelper.select_user_with_username(username=opuser)[2])
return redirect("/panel")
else:
return redirect("/login")
@api.route("/delpage/<int:id>", methods=["GET"])
@host_limit("panel")
def del_page(id:int):
opuser = auth()
if opuser:
opuser_userhash = DBHelper.select_user_with_username(username=opuser)[2]
lao_userhash = DBHelper.select_lao_with_id(id=id)[0]
if opuser_userhash == lao_userhash:
DBHelper.delete_lao(lid=id)
return redirect("/panel")
else:
return error("You don't have permission to visit this page."), 402
else:
return redirect("/login")