123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- # -*- coding: utf-8 -*-
- from fastapi import APIRouter, Depends, Request, Header, Form, Body
- from fastapi.responses import FileResponse, StreamingResponse
- from sqlalchemy.orm import Session
- from fastapi.responses import JSONResponse
- from database import get_db
- from utils import *
- from utils.vcode import *
- from utils.redis_util import *
- import base64
- from common.const import *
- from io import BytesIO
- from utils.StripTagsHTMLParser import *
- from common import security
- from datetime import timedelta
- from common.security import verify_password
- from utils import ase_utils
- from common.auth_user import *
- from common import YzyApi, TassApi
- from models import *
- from urllib.parse import quote
- from exceptions import *
- import traceback
- from common.db import db_czrz
- from common.enc import mpfun, sys_user_data
- router = APIRouter()
- @router.get('/tenant/list')
- async def tenant_list(
- request: Request,
- db: Session = Depends(get_db)
- ):
- return {
- "code": 200,
- "msg": "操作成功",
- "data": {
- "tenantEnabled": False,
- "voList": []
- }
- }
- def buildVerificationCodeRedisKey(uuid: str) -> str:
- return VERIFICATION_CODE_REDIS_PREFIX.format(uuid)
- @router.get('/code')
- async def code(
- request: Request,
- db: Session = Depends(get_db)
- ):
- uuid_str = md5(new_guid())
- image, code = getVerifyCode()
- buf = BytesIO()
- image.save(buf, 'png')
- img_data = buf.getvalue()
- image_bytes_io = BytesIO(img_data)
- image_bytes_io.seek(0)
- image_bytes = image_bytes_io.read()
- base64_str = base64.b64encode(image_bytes).decode('utf-8')
- redis_key = "kaptcha_" + buildVerificationCodeRedisKey(uuid_str)
- redis_set(redis_key, code)
- return {
- "code": 200,
- "msg": "操作成功",
- "data": {
- "captchaEnabled": True,
- "uuid": uuid_str,
- "img": base64_str
- }
- }
- @router.post('/login')
- async def login(
- request: Request,
- db: Session = Depends(get_db),
- data: dict = Depends(remove_xss_json)
- ):
- try:
- # tenantId = data['tenantId']
- username = data['username']
- password = data['password']
- # rememberMe = data['rememberMe']
- uuid_str = data['uuid']
- code = data['code']
- # clientId = data['clientId']
- # grantType = data['grantType']
- # 仅为了可能的兼容
- clientId = "e5cd7e4891bf95d1d19206ce24a7b32e"
- grantType = "password"
- uuid = buildVerificationCodeRedisKey(uuid_str)
- redis_key = "kaptcha_" + uuid
- redis_code = redis_get(redis_key)
- if code is None or code != redis_code:
- raise AppException(500, "图片验证码不正确")
- redis_login_key = "login_user_" + username
- login_error_times = redis_get(redis_login_key)
- if login_error_times is None:
- login_error_times = 0
- else:
- login_error_times = int(login_error_times)
- if login_error_times >= 5:
- raise AppException(500, "登录错误多,请5分钟后再尝试!")
-
- # 对用户账号进行密码机接口加密处理
- username = mpfun.enc_data(username)
- password = ase_utils.aesDecrypt(uuid_str, password)
- logger.info('userpass: {}', password)
- row = db.query(SysUser).filter(SysUser.user_name == username).first()
- if sys_user_data.sign_valid_row(row) == False:
- raise AppException(500, "系统用户表验证异常,已被非法篡改")
- if row is None:
- login_error_times = login_error_times + 1
- redis_set_with_time(redis_login_key, str(login_error_times), 300)
- raise AppException(500, "帐号或者密码错误")
- logger.info('row.password: {}', row.password)
-
- # bcrypt 加密校验
- # if verify_password(password, row.password) == False:
-
- # 密码机加密校验
- if mpfun.enc_data(password) != row.password:
- login_error_times = login_error_times + 1
- redis_set_with_time(redis_login_key, str(login_error_times), 300)
- raise AppException(500, "帐号或者密码错误")
- # 校验长期(超过1个月)未使用的账号和及开通后未及时(如72小时)修改初始密码的账号做清除
- login_date = row.login_date
- if row.login == 0:
- # 计算初始化的时间和当前时间相差的小时数
- diff_hour = (datetime.now() - login_date).seconds/3600
- if diff_hour > 72:
- raise AppException(500, "你的账号在开通后(72小时)内未登录及修改初始密码,账号已被锁定,请联系管理员处理,否则将被清除。")
-
- else:
- # 计算上次登录到当前时间的相差天数
- diff_day = (datetime.now() - login_date).days
- if diff_day > 30:
- raise AppException(500, "你的账号在超过30天未登录使用,账号已被锁定,请联系管理员处理,否则将被清除。")
- redis_set_with_time(redis_login_key, str(0), 1)
-
- user_id = str(row.user_id)
- auth = {
- "user_id": user_id,
- "user_name": mpfun.dec_data(row.user_name),
- "nick_name": row.nick_name,
- "is_yzy_user": "0"
- }
- request.session.update({
- 'user_auth': auth,
- 'user_auth_sign': data_auth_sign(auth),
- 'user_name': username
- })
- db_czrz.log_username(db, row.user_id, auth['user_name'], row.nick_name, "登录", "后台管理登录成功", request.client.host)
- row.login_date = datetime.now()
- row.login_ip = request.client.host
- row.login = row.login + 1
- db.commit()
- access_token_expires = timedelta(days = 5)
- access_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = access_token_expires
- )
- refresh_token_expires = timedelta(days = 10)
- refresh_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = refresh_token_expires
- )
- return {
- "code": 200,
- "msg": "操作成功",
- "data": {
- "access_token": access_token,
- "refresh_token": refresh_token,
- "expire_in": 7200,
- "refresh_expire_in": 7200,
- "client_id": clientId,
- "scope": "",
- "openid": ""
- }
- }
- except AppException as e:
- return {
- "code": e.code,
- "msg": e.msg
- }
-
- except Exception as e:
- traceback.print_exc()
- return {
- "code": 500,
- "msg": "帐号或者密码错误"
- }
- @router.post('/logout')
- async def logout(
- request: Request,
- user: AuthUser = Depends(get_auth_user),
- db: Session = Depends(get_db)
- ):
- logger.info("logout ok")
- request.session.clear()
- try:
- # db_czrz.log(db, user, "退出", "后台管理退出成功", request.client.host)
- if user.is_yzy_user == 1:
- logout_url = settings.TYRZ_LOGOUT.format(settings.TYRZ_CLIENT_ID) + quote(settings.HOME_URL+"/yjzp/")
- logger.info(logout_url)
- else:
- logout_url = settings.HOME_URL + "/yjzp/"
- except Exception as e:
- traceback.print_exc()
- logout_url = settings.HOME_URL+"/yjzp/"
- return {
- "code": 200,
- "msg": "退出成功",
- "data": logout_url
- }
- # 小屏专用
- @router.post('/yzy/callback')
- async def yzy(
- request: Request,
- db: Session = Depends(get_db),
- data: dict = Depends(remove_xss_json)
- ):
- code = data['code']
- state = data['state']
- state_str = base64.b64decode(state).decode('utf-8')
- state_json = json.loads(state_str)
- logger.info("code:{}, {}", code, state_json)
- resp = YzyApi.get_user_info(code)
- if resp['errcode'] != 0:
- return {
- "code": 500,
- "msg": "Code异常"
- }
- user_id = resp['UserId']
- row = db.query(YzyOrgUserEntity).filter(YzyOrgUserEntity.userid == user_id).first()
- if row is None:
- return {
- "code": 500,
- "msg": "user_id异常"
- }
-
- yzy_account = row.account
- row = db.query(SysUser).filter(SysUser.yzy_account == yzy_account).first()
- if row is None:
- return {
- "code": 500,
- "msg": "用户不是本系统用户"
- }
-
- user_id = str(row.user_id)
- access_token_expires = timedelta(seconds = 7200)
- access_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = access_token_expires
- )
- refresh_token_expires = timedelta(seconds = 7200)
- refresh_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = refresh_token_expires
- )
- return {
- "code": 200,
- "msg": "粤政易登录成功",
- "data": {
- "access_token": access_token,
- "refresh_token": refresh_token,
- "expire_in": 7200,
- "refresh_expire_in": 7200,
- "scope": "",
- "redirect_url": state_json['redirect_url']
- }
- }
- # 粤政易token登录
- @router.post('/yzylogin')
- async def login(
- request: Request,
- data: dict = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- code = data['code']
- redis_key = "yzy_" + code
- user_id = redis_get(redis_key)
- if user_id is None:
- return {
- "code": 500,
- "msg": "用户不是本系统用户"
- }
- row = db.query(SysUser).filter(SysUser.user_id == int(user_id)).first()
- if row is None:
- return {
- "code": 500,
- "msg": "用户不是本系统用户"
- }
-
- user_id = str(row.user_id)
- auth = {
- "user_id": user_id,
- "user_name": row.user_name,
- "nick_name": row.nick_name,
- "is_yzy_user": "1"
- }
- logger.info('auth {}', auth)
- request.session['user_auth'] = auth
- request.session['user_auth_sign'] = data_auth_sign(auth)
- request.session['user_name'] = row.user_name
- db_czrz.log_username(db, row.user_id, auth['user_name'], row.nick_name, "登录", "粤政易登录登录成功", request.client.host)
- row.login_date = datetime.now()
- row.login_ip = request.client.host
- row.login = row.login + 1
- db.commit()
- access_token_expires = timedelta(days = 5)
- access_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = access_token_expires
- )
- refresh_token_expires = timedelta(days = 10)
- refresh_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = refresh_token_expires
- )
- return {
- "code": 200,
- "msg": "操作成功",
- "data": {
- "access_token": access_token,
- "refresh_token": refresh_token,
- "expire_in": 7200,
- "refresh_expire_in": 7200,
- "client_id": 0,
- "scope": "",
- "openid": ""
- }
- }
- # USBKEY登录
- @router.post("/login_with_usbkey")
- def login_with_usbkey(
- request: Request,
- username: str = Body(...),
- keyID: str = Body(...),
- p7SignData: str = Body(...),
- p7SignValue: str = Body(...),
- db: Session = Depends(get_db)
- ):
- result = TassApi.verifyP7Sign(p7SignData, p7SignValue)
- if result is None:
- return {
- "code": 500,
- "msg": "证书验签失败",
- }
- logger.info('keyID: {}', keyID)
- logger.info('verifyP7Sign: {}', result)
-
- # 对用户账号进行密码机接口加密处理
- username = mpfun.enc_data(username)
-
- redis_login_key = "login_user_" + username
- login_error_times = redis_get(redis_login_key)
- if login_error_times is None:
- login_error_times = 0
- else:
- login_error_times = int(login_error_times)
- if login_error_times >= 5:
- raise AppException(500, "登录错误多,请5分钟后再尝试!")
- row = db.query(SysUser).filter(SysUser.user_name == username).first()
- if row is None:
- login_error_times = login_error_times + 1
- redis_set_with_time(redis_login_key, str(login_error_times), 300)
- raise AppException(500, "帐号或者密码错误")
-
- if sys_user_data.sign_valid_row(row) == False:
- raise AppException(500, "系统用户表验证异常,已被非法篡改")
- user_id = str(row.user_id)
- auth = {
- "user_id": user_id,
- "user_name": mpfun.dec_data(row.user_name),
- "nick_name": row.nick_name,
- "is_yzy_user": "0"
- }
- logger.info('auth {}', auth)
- request.session['user_auth'] = auth
- request.session['user_auth_sign'] = data_auth_sign(auth)
- request.session['username'] = username
- db_czrz.log_username(db, row.user_id, auth['user_name'], row.nick_name, "登录", "后台USBKEY登录成功", request.client.host)
- row.login_date = datetime.now()
- row.login_ip = request.client.host
- row.login = row.login + 1
- db.commit()
- access_token_expires = timedelta(days = 5)
- access_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = access_token_expires
- )
- refresh_token_expires = timedelta(days = 10)
- refresh_token = security.create_access_token(
- data={"sub": user_id}, expires_delta = refresh_token_expires
- )
- return {
- "code": 200,
- "msg": "操作成功",
- "data": {
- "access_token": access_token,
- "refresh_token": refresh_token,
- "expire_in": 7200,
- "refresh_expire_in": 7200,
- "client_id": "e5cd7e4891bf95d1d19206ce24a7b32e",
- "scope": "",
- "openid": ""
- }
- }
|