finish v1

This commit is contained in:
RainSun 2020-04-21 11:09:13 +08:00
commit b4921f5457
10 changed files with 427 additions and 0 deletions

6
Dockerfile Normal file
View File

@ -0,0 +1,6 @@
FROM python:3.7-alpine
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY . /app

53
ReadMe.md Normal file
View File

@ -0,0 +1,53 @@
# db电话簿
## 服务器配置
```js
// 安装venv
python3 -m venv venv
// 启动venv
. venv/bin/activate
// 升级pip
pip install --upgrade pip
// 根据依赖文件安装环境
pip install -r requirements.txt
// 设置全局变量
export FLASK_APP=phonebook.py
export FLASK_ENV=development
flask run --host=0.0.0.0 -p 80
// 启动永久服务
gunicorn phonebook:app -c gunicorn.conf.py
// 查看已启动服务
pstree -ap|grep gunicorn
// 关闭某服务
kill (pid)
//关闭venv
deactivate
// 创建当前环境的依赖文件
pip freeze > requirements.txt
```
## 错误码
/login
450没用手机号登录过教务
422账号或者密码错误
400数据不合法
510数据库查询失败
511教务挂了
512未注册
/sign
400数据不合法
510数据库插入失败
511已注册过无需再次注册
512数据库查询失败
/del
400数据不合法
510数据库删除失败
/update
400数据不合法
510数据库覆写失败
/get
400数据不合法
510数据库查询失败
511用户认证失败
512数据库查询失败
docker run -it --name beta -v /root/data/phonebook:/app -p 127.0.0.1:6000:80 --network=lacus lacus/flask_env /bin/sh

3
go.sh Normal file
View File

@ -0,0 +1,3 @@
#!/bin/sh
echo start
gunicorn phonebook:app -c gunicorn.conf.py

8
gunicorn.conf.py Normal file
View File

@ -0,0 +1,8 @@
# 并行工作线程数
workers = 4
bind = '0.0.0.0:80'
daemon = True
timeout = 120
accesslog = './logs/acess.log'
errorlog = './logs/error.log'
autostart = True

0
lib/__init__.py Normal file
View File

202
lib/allFunctions.py Normal file
View File

@ -0,0 +1,202 @@
from utils import randomId, md5Check, connection, signCode
from db import col
import json
# 前端传来的参数应为 cid, pwd, sign
def manageLogin(request):
try:
data = json.loads(request.form['data'])
if not data.__contains__('cid'):
raise Exception
if not data.__contains__('pwd'):
raise Exception
if not data.__contains__('sign'):
raise Exception
if md5Check(data):
# 数据校验通过
try:
# 查询用户信息
user_info = col().find_one({'cid': data['cid']}, {"_id": 0})
if user_info:
# 获取到用户正常返回
if user_info['pwd'] == signCode(data['pwd']):
return {'user_info': user_info}, 200
else:
return '账号或密码错误', 422
else:
# 数据库没有用户信息,查询一下教务
return connection(data['cid'], data['pwd'])
except Exception as e:
print(e)
return '数据库查询失败', 510
else:
return '数据不合法', 400
except Exception as e:
print(e)
return '数据不合法', 400
# 前端传来的参数应为 cid, pwd, sign, sex, tel, department, position, adds, qq, wx
def manageSign(request):
try:
data = json.loads(request.form['data'])
if not data.__contains__('cid'):
raise Exception
if not data.__contains__('pwd'):
raise Exception
if not data.__contains__('sign'):
raise Exception
if not data.__contains__('sex'):
raise Exception
if not data.__contains__('tel'):
raise Exception
if not data.__contains__('department'):
raise Exception
if not data.__contains__('position'):
raise Exception
if not data.__contains__('adds'):
raise Exception
if not data.__contains__('qq'):
raise Exception
if not data.__contains__('wx'):
raise Exception
if md5Check(data):
# 数据校验通过
try:
user_info = col().find_one({'cid': data['cid']}, {"_id": 0})
if user_info:
return '已注册过,无需再次注册', 511
else:
try:
data.pop('sign')
data['pwd'] = signCode(data['pwd'])
data['openid'] = randomId()
data_cache = data.copy()
# 插入用户信息
col().insert_one(data)
return {'user_info': data_cache}, 200
except Exception as e:
print(e)
return '数据库插入失败', 510
except Exception as e:
print(e)
return '数据库查询失败', 512
else:
return '数据不合法', 400
except Exception as e:
print(e)
return '数据不合法', 400
# 前端传来的参数应为 openid sign
def manageDel(request):
try:
data = json.loads(request.form['data'])
if not data.__contains__('openid'):
raise Exception
if not data.__contains__('sign'):
raise Exception
if md5Check(data):
# 数据校验通过
try:
col().remove({'openid': data['openid']})
return 'OK', 200
except Exception as e:
print(e)
return '数据库删除失败', 510
else:
return '数据不合法', 400
except Exception as e:
print(e)
return '数据不合法', 400
# 前端传来的参数应为 cid, pwd, sign, sex, tel, department, position, adds, qq, wx, openid, id, name
def manageUpdate(request):
try:
data = json.loads(request.form['data'])
if not data.__contains__('cid'):
raise Exception
if not data.__contains__('name'):
raise Exception
if not data.__contains__('id'):
raise Exception
if not data.__contains__('pwd'):
raise Exception
if not data.__contains__('sign'):
raise Exception
if not data.__contains__('sex'):
raise Exception
if not data.__contains__('tel'):
raise Exception
if not data.__contains__('department'):
raise Exception
if not data.__contains__('position'):
raise Exception
if not data.__contains__('adds'):
raise Exception
if not data.__contains__('qq'):
raise Exception
if not data.__contains__('wx'):
raise Exception
if not data.__contains__('openid'):
raise Exception
if md5Check(data):
# 数据校验通过
try:
data.pop('sign')
data['pwd'] = signCode(data['pwd'])
# 更新用户信息
col().update({'openid': data['openid']}, data)
return 'OK', 200
except Exception as e:
print(e)
return '数据库覆写失败', 510
else:
return '数据不合法', 400
except Exception as e:
print(e)
return '数据不合法', 400
# 前端传来的参数应为 openid, sign
def manageGet(request):
try:
data = json.loads(request.form['data'])
if not data.__contains__('openid'):
raise Exception
if not data.__contains__('sign'):
raise Exception
if md5Check(data):
# 数据校验通过
try:
# 查询用户信息
user_info = col().find_one(
{'openid': data['openid']}, {"_id": 0})
if user_info:
user_list = []
try:
for i in col().find({}, {"sex": 1, "tel": 1, "department": 1, "position": 1, "adds": 1, "qq": 1, "wx": 1, "id": 1, "name": 1}):
if i.get('_id'):
i.pop('_id')
user_list.append(i)
return {'user_list': user_list}, 200
except Exception as e:
print(e)
return ('数据库查询失败', 512)
else:
return '用户认证失败', 511
except Exception as e:
print(e)
return '数据库查询失败', 510
else:
return '数据不合法', 400
except Exception as e:
print(e)
return '数据不合法', 400

9
lib/db.py Normal file
View File

@ -0,0 +1,9 @@
from pymongo import MongoClient
from bson import ObjectId, json_util
# 获取数据集
def col():
# 链接数据库
conn = MongoClient('mongodb://pb:wO0pM5rD9eP3@mongo:27017/pb')
return conn.pb.user

82
lib/utils.py Normal file
View File

@ -0,0 +1,82 @@
import json
import requests
from urllib.parse import quote
import base64
from bs4 import BeautifulSoup
import random
from hashlib import md5
import datetime
# 链接教务获取信息
def connection(username,password):
try:
s = requests.Session()
# 获取统一身份系统的网页
r = s.get(url='http://mysso-cust-edu-cn-s.webvpn.cust.edu.cn:8118/cas/login?service=https%3A%2F%2Fwebvpn.cust.edu.cn%2Fauth%2Fcas_validate%3Fentry_id%3D1')
# soup = BeautifulSoup(r.text,'lxml')
soup = BeautifulSoup(r.text,'html.parser')
execution=soup.find_all(name='input')[6]['value']
formdata={
'username':username,
'password':password,
'execution':execution,
'_eventId':'submit',
'geolocation':''
}
r = s.post(url='http://mysso-cust-edu-cn-s.webvpn.cust.edu.cn:8118/cas/login?service=https%3A%2F%2Fwebvpn.cust.edu.cn%2Fauth%2Fcas_validate%3Fentry_id%3D1',data=formdata)
soup=BeautifulSoup(r.text,'html.parser')
flag = soup.find(name='title')
if(flag.text=="手机号设置"):
return ('没用手机号登陆过教务', 450)
r = s.get(url='http://portal-cust-edu-cn-s.webvpn.cust.edu.cn:8118/custp/index')
soup=BeautifulSoup(r.text,'html.parser')
try:
ip = soup.findAll(name='a')[7]['href'][7:].split("-")
except:
return ('账号或密码错误', 422)
r = s.get(url='http://mysso-cust-edu-cn-s.webvpn.cust.edu.cn:8118/cas/login?service=http://'+ip[0]+'.'+ip[1]+'.'+ip[2]+'.'+ip[3]+':8080/welcome',allow_redirects=False)
ticket = r.headers['Location'][68:]
asp_net_sessionid_param = {'Ticket':ticket,'Url':'http://'+ip[0]+'.'+ip[1]+'.'+ip[2]+'.'+ip[3]+':8080/welcome'}
asp_net_sessionid_param = base64.b64encode(quote(json.dumps(asp_net_sessionid_param)).encode('utf-8')).decode('utf-8')
asp_net_sessionid_param = {'param':asp_net_sessionid_param}
headers = {'Content-Type': 'application/json'}
r = s.post(url='http://'+ip[0]+'-'+ip[1]+'-'+ip[2]+'-'+ip[3]+'-8080-p.webvpn.cust.edu.cn:8118/api/LoginApi/LGSSOLocalLogin?sf_request_type=ajax',data=json.dumps(asp_net_sessionid_param),headers=headers)
data = json.loads(r.content.decode('utf-8'))
student_name = data['data']['StudentDto']['XM']
student_id = data['data']['StudentDto']['XH']
return ({'name': student_name, 'id': student_id}, 512)
except Exception as e:
print(e)
return ('教务挂了', 511)
# 给str签名用于加密密码
def signCode(code):
d = str(code)
d = d.replace(' ', '')
md = md5()
md.update(d.encode('utf-8'))
r = md.hexdigest().upper()
return r
# 生成唯一不重名字符串
def randomId():
nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S") # 生成当前时间
randomNum = random.randint(0, 100) # 生成的随机整数n其中0<=n<=100
if randomNum <= 10:
randomNum = str(0) + str(randomNum)
uniqueNum = str(nowTime) + str(randomNum)
return uniqueNum
# MD5 校验
def md5Check(data):
d = data.copy()
try:
d.pop('sign')
except KeyError:
pass
d = str(d)
d = d.replace(' ', '')
md = md5()
md.update(d.encode('utf-8'))
r = md.hexdigest().upper()
return r == data['sign']

46
phonebook.py Normal file
View File

@ -0,0 +1,46 @@
import sys
sys.path.append('./lib')
from flask import Flask, request, redirect
from flask_cors import CORS
from allFunctions import manageLogin, manageSign, manageUpdate, manageDel, manageGet
app = Flask(__name__)
CORS(app, resources=r'/*')
# 测试
@app.route('/v1/')
def base():
return 'Hello! Glad to serve you.'
# 登录
@app.route('/v1/login', methods=['POST'])
def login():
return manageLogin(request)
# 注册
@app.route('/v1/sign', methods=['POST'])
def sign():
return manageSign(request)
# 修改
@app.route('/v1/update', methods=['POST'])
def update():
return manageUpdate(request)
# 获取
@app.route('/v1/get', methods=['POST'])
def get():
return manageGet(request)
# 删除
@app.route('/v1/del', methods=['POST'])
def dele():
return manageDel(request)
# 访问拦截器转发到根路由
@app.errorhandler(404)
def miss(e):
return redirect('/v1/')
if __name__ == '__main__':
app.run(host="0.0.0.0", debug=True, port="80")

18
requirements.txt Normal file
View File

@ -0,0 +1,18 @@
beautifulsoup4==4.8.2
bs4==0.0.1
certifi==2019.11.28
chardet==3.0.4
Click==7.0
Flask==1.1.1
Flask-Cors==3.0.8
gunicorn==20.0.4
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.3
MarkupSafe==1.1.1
pymongo==3.10.1
requests==2.22.0
six==1.14.0
soupsieve==1.9.5
urllib3==1.25.7
Werkzeug==0.16.0