You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
6.4 KiB
Python
182 lines
6.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
import logging
|
|
import json
|
|
import base64
|
|
import tornado.web
|
|
import uuid
|
|
import time
|
|
import datetime
|
|
import itertools
|
|
from io import StringIO, BytesIO
|
|
|
|
from website import errors
|
|
from website import settings
|
|
from website import db
|
|
from website import consts
|
|
from website.handler import APIHandler
|
|
from website.util import aes
|
|
from website.util.captcha import create_validate_code
|
|
from website.service.license import get_license_status
|
|
from website.util import shortuuid
|
|
from sqlalchemy import text
|
|
import tornado.escape
|
|
|
|
|
|
class CaptchaHandler(APIHandler):
|
|
def get(self):
|
|
self.set_header("Content-Type", "image/png")
|
|
image, image_str = create_validate_code()
|
|
c = uuid.uuid4().hex
|
|
token = self.create_signed_value("logc", c)
|
|
self.r_app.set("logincaptcha:%s" % c, image_str, ex=120)
|
|
|
|
buffered = BytesIO()
|
|
# 保存验证码图片
|
|
image.save(buffered, 'png')
|
|
img_b64 = base64.b64encode(buffered.getvalue())
|
|
|
|
# for line in buffered.getvalue():
|
|
# self.write(line)
|
|
# output.close()
|
|
self.finish({"token": self.tostr(token), "captcha": self.tostr(img_b64)})
|
|
|
|
class LogoutHandler(APIHandler):
|
|
def get(self):
|
|
if self.current_user:
|
|
# self.db_app.insert(
|
|
# "insert into system_log(user, ip, first_module, second_module, op_type, op_content, description) "
|
|
# "values(%s, %s, %s, %s, %s, %s, %s)",
|
|
# self.current_user.name, self.request.remote_ip, "平台管理中心", "账号管理", "登出", "系统登出", "系统登出"
|
|
# )
|
|
|
|
self.r_app.delete(settings.session_key_prefix % self.current_user.uuid)
|
|
self.finish()
|
|
|
|
class LoginHandler(APIHandler):
|
|
def post(self):
|
|
suid = shortuuid.ShortUUID().random(10)
|
|
logging.info(suid)
|
|
|
|
username = self.get_escaped_argument("username")
|
|
password = self.get_escaped_argument("pwd")
|
|
# captcha = self.get_escaped_argument("captcha", "")
|
|
# captcha_token = self.get_escaped_argument("captcha_token", "")
|
|
|
|
# wrong_time_lock = self.r_app.get("pwd:wrong:time:%s:lock" % self.tostr(username))
|
|
# if wrong_time_lock:
|
|
# raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "账号处于冷却期,请稍后再试")
|
|
# return
|
|
|
|
logging.info(self.request.arguments)
|
|
logging.info(password)
|
|
logging.info("#########################")
|
|
|
|
# if not captcha:
|
|
# raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "请输入验证码")
|
|
# if not captcha_token:
|
|
# raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "缺少参数")
|
|
|
|
# c = tornado.web.decode_signed_value(
|
|
# settings.cookie_secret,
|
|
# "logc",
|
|
# self.tostr(captcha_token)
|
|
# )
|
|
# code = self.r_app.get("logincaptcha:%s" % self.tostr(c))
|
|
# 清除校验码缓存
|
|
# self.r_app.delete("logincaptcha:%s" % c)
|
|
# if not code:
|
|
# raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "验证码已过期")
|
|
# 判断验证码与缓存是否一致
|
|
# if self.tostr(captcha).lower() != self.tostr(code).lower():
|
|
# raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "验证码错误")
|
|
|
|
|
|
username = self.tostr(username)
|
|
password = self.tostr(password)
|
|
|
|
pwd_enc = aes.encrypt(settings.pwd_aes_key, password)
|
|
|
|
row = {}
|
|
|
|
with self.app_mysql.connect() as conn:
|
|
cur = conn.execute(
|
|
text("select id, uid, available from sys_user where name=:name and pwd=:pwd"),
|
|
{"name": username, "pwd": pwd_enc}
|
|
)
|
|
# keys = list(cur.keys())
|
|
#
|
|
# one = cur.fetchone()
|
|
# row = dict(zip(keys, one))
|
|
# logging.info(db.Row(itertools.zip_longest(keys, one)))
|
|
|
|
row = db.to_json(cur)
|
|
|
|
cur.close()
|
|
# data = [dict(zip(keys, res)) for res in cur.fetchall()]
|
|
|
|
if not row:
|
|
# wrong_time = self.r_app.get("pwd:wrong:time:%s" % username)
|
|
# logging.info(wrong_time)
|
|
# logging.info(settings.pwd_error_limit - 1)
|
|
# if wrong_time and int(wrong_time) > settings.pwd_error_limit - 1:
|
|
# self.r_app.set("pwd:wrong:time:%s:lock" % username, 1, ex=3600)
|
|
# self.r_app.delete("pwd:wrong:time:%s" % username)
|
|
# else:
|
|
# self.r_app.incr("pwd:wrong:time:%s" % username)
|
|
raise errors.HTTPAPIError(errors.ERROR_BAD_REQUEST, "用户名或者密码错误")
|
|
return
|
|
if row["available"] == 0:
|
|
raise errors.HTTPAPIError(errors.ERROR_FORBIDDEN, "当前用户被禁用")
|
|
return
|
|
|
|
# row_role = self.db_app.get("select role from user_role where userid=%s", row["id"])
|
|
# user_role = row_role["role"]
|
|
|
|
userId = row["id"]
|
|
jsessionid = row["uid"]
|
|
|
|
# create sign value admin_login_sign
|
|
secure_cookie = self.create_signed_value(settings.secure_cookie_name, str(jsessionid))
|
|
|
|
self.r_app.set(
|
|
settings.session_key_prefix % jsessionid,
|
|
json.dumps({
|
|
"id": userId,
|
|
"name": username,
|
|
"uuid": row["uid"],
|
|
# "role": user_role
|
|
}),
|
|
ex=settings.session_ttl
|
|
)
|
|
|
|
# self.db_app.insert(
|
|
# "insert into system_log(user, ip, first_module, second_module, op_type, op_content, description) "
|
|
# "values(%s, %s, %s, %s, %s, %s, %s)",
|
|
# username, self.request.remote_ip, "平台管理中心", "账号管理", "登录", "系统登录", "系统登录"
|
|
# )
|
|
|
|
# license_row = self.db_app.get(
|
|
# "select expireat from license limit 1"
|
|
# )
|
|
|
|
# system_status = get_license_status(license_row)
|
|
|
|
render_data = {
|
|
"token": str(secure_cookie, encoding="utf-8"),
|
|
# "role": user_role,
|
|
"username": username,
|
|
# "system_status": system_status, # 9000/未激活, 9001/已激活, 9002/过期可查看, 9003/完全过期
|
|
}
|
|
|
|
self.finish(render_data)
|
|
|
|
|
|
class UserInfoHandler(APIHandler):
|
|
def post(self):
|
|
token = self.get_argument("token")
|
|
user = self.get_current_user(token_body=self.tostr(token))
|
|
if not user:
|
|
raise errors.HTTPAPIError(errors.ERROR_UNAUTHORIZED)
|
|
|
|
self.finish({"name": user.name, "role": user.role})
|