finish v1

This commit is contained in:
RainSun 2020-02-22 09:45:11 +08:00
commit 0cd4633edb
9 changed files with 450 additions and 0 deletions

51
ReadMe.md Normal file
View File

@ -0,0 +1,51 @@
# ccb
## 错误代码一览
* 200成功
* /login
* 用户登录或者注册
* 100校验失败
* 101用户不存在
* 102user_info获取失败
* 103新用户插入失败
* 104: 签名失败
* 105: 用户未激活,未重新发送邮件
* 106密码错误
* 107注册成功验证码已下发
* 108用户未激活已重新发送邮件
* /activation
* 接受开启账户的uuid
* 400校验失败
* 401: active用户不存在
* 402: active覆写失败
* 403签名失败
* 404用户不存在
* 405user_info获取失败
* 406该用户已经激活过了
* 407验证码非本人所有
* /download
* 更新到本地
* 500校验失败
* 501签名失败
* 502密码错误
* 101用户不存在
* 102user_info获取失败
* /upload
* 上传到云端
* 300校验失败
* 301codebook用户不存在
* 302codebook覆写失败
* 303密码错误
* 304签名失败
* 101用户不存在
* 102user_info获取失败
# 功能总结
* 注册/登录
* 用户发来邮箱地址和密码(密码加密一下)
* 前后端校验
* 如果注册过就返回200
* 前端收到了codebook就把用户密码加密的存起来
* 之后就可以免登录刷新
* 如果没注册过就给那个邮箱发验证邮件内容是uuid同时放进数据库里 内容为 mail_addr codebook is_active uuid update_time password
* 上传
* 下载

BIN
canary.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

45
ccb.py Normal file
View File

@ -0,0 +1,45 @@
# 将lib里边的文件加到路由中
import sys
sys.path.append('./lib')
from flask import Flask, escape, url_for, request, render_template, redirect, abort, send_from_directory, Response, make_response
from allFunction import manageLogin, manageActivation, manageDownload, manageUpload
app = Flask(__name__)
if __name__ == '__main__':
app.run()
# 测试用根路由
@app.route('/api/')
def sayHello():
return 'Hello! Glad to serve you, please go to the official website: https://ccb.canary.moe'
# 登录或者注册
@app.route('/api/login', methods=["POST"])
def login():
res = manageLogin(request)
return res
# 激活账户
@app.route('/api/activation', methods=["POST"])
def activation():
res = manageActivation(request)
return res
# 更新本地数据
@app.route('/api/download', methods=["POST"])
def download():
res = manageDownload(request)
return res
# 更新云端数据
@app.route('/api/upload', methods=["POST"])
def upload():
res = manageUpload(request)
return res
# 访问拦截器转发到根路由
@app.errorhandler(404)
def miss(e):
return redirect('/api')

13
gunicorn.conf.py Normal file
View File

@ -0,0 +1,13 @@
# 并行工作线程数
workers = 4
# 监听内网端口5000【按需要更改】
bind = '127.0.0.1:5005'
# 设置守护进程【关闭连接时,程序仍在运行】
daemon = True
# 设置超时时间120s默认为30s。按自己的需求进行设置
timeout = 120
# 设置访问日志和错误信息日志路径
accesslog = './logs/acess.log'
errorlog = './logs/error.log'
#自动重启
autostart = True

191
lib/allFunction.py Normal file
View File

@ -0,0 +1,191 @@
# 引入数据库操作函数
from db import searchUser, insertUser, updateCodebook, ActivateUser, searchUserByUuid
# 引入json
import json
# 引入时间
import datetime
# 引入发送邮件
from mail import sendMail
# 引入md5
from hashlib import md5
# 引入随机数
import random
# 主处理逻辑函数-----------------------------------------------------------
# 处理用户登录 前端发送 mail_addr password update_time
def manageLogin(request):
# json化应该能当dict用
try:
data_cache = json.loads(request.form['data'])
except Exception as e:
return {'errcode': 100, 'errmsg': '校验失败'}
checked = checkData(data_cache)
if checked:
# 校验通过
user_info = searchUser(data_cache['mail_addr'])
if user_info['errcode'] == 200:
# 用户登录
user_info = user_info['user_info']
if user_info['active']:
# 已经激活的账户
if user_info['password'] == data_cache['password']:
# 密码正确
return {'errcode': 200, 'errmsg': 'ok', 'update_time': user_info['update_time']}
else:
# 密码错误
return {'errcode': 106, 'errmsg': '密码错误'}
else:
# 没激活的用户
time_difference = int(data_cache['update_time']) - int(user_info['update_time'])
if time_difference > 1000 * 60 * 5:
# 超过五分钟重新发送uuid
send_str = '非常感谢您的使用,您的验证码为:' + user_info['uuid']
sendMail('欢迎注册Canary Codebook', send_str, [user_info['mail_addr']])
return {'errcode': 108, 'errmsg': '用户未激活,已重新发送邮件'}
else:
return {'errcode': 105, 'errmsg': '用户未激活,未重新发送邮件'}
elif user_info['errcode'] == 101:
# 用户注册
user_data = createUserData(data_cache)
insert_res = insertUser(user_data)
if insert_res['errcode'] == 200:
# 新用户插入成功,发送邮件
send_str = '非常感谢您的使用,您的验证码为:' + user_data['uuid']
sendMail('欢迎注册Canary Codebook', send_str, [user_data['mail_addr']])
return {'errcode': 107, 'errmsg': '注册成功,验证码已下发'}
else:
# 用户插入失败
return insert_res
else:
# 查询错误
return user_info
else:
return {'errcode': 104, 'errmsg': '签名失败'}
# 处理激活用户 用户发来uuid mail_addr
def manageActivation(request):
# json化应该能当dict用
try:
data_cache = json.loads(request.form['data'])
except Exception as e:
return {'errcode': 400, 'errmsg': '校验失败'}
checked = checkData(data_cache)
if checked:
# 校验通过
# 判断用户之前是否未激活
user_info = searchUserByUuid(data_cache['uuid'])
if user_info['errcode'] == 200:
# 用户存在
user_info = user_info['user_info']
if user_info['mail_addr'] == data_cache['mail_addr']:
# 是自己的激活码
if user_info['active']:
return {'errcode': 406, 'errmsg': '该用户已经激活过了', 'update_time': user_info['update_time']}
else:
# 进入激活程序
active_res = ActivateUser(data_cache['uuid'])
if active_res['errcode'] == 200:
# 激活成功
return {'errcode': 200, 'errmsg': 'ok', 'update_time': user_info['update_time']}
else:
# 激活失败
return active_res
else:
# 输入的不是自己的激活码
return {'errcode': 407, 'errmsg': '验证码非本人所有'}
else:
# 用户不存在或者错误
return user_info
else:
return {'errcode': 403, 'errmsg': '签名失败'}
# 处理云端覆写本地数据 用户发来 mail_addr password
def manageDownload(request):
# json化应该能当dict用
try:
data_cache = json.loads(request.form['data'])
except Exception as e:
return {'errcode': 500, 'errmsg': '校验失败'}
checked = checkData(data_cache)
if checked:
# 校验通过
# 获取用户信息
user_info = searchUser(data_cache['mail_addr'])
if user_info['errcode'] == 200:
user_info = user_info['user_info']
if user_info['password'] == data_cache['password']:
# 密码正确
return {'errcode': 200, 'errmsg': 'ok', 'codebook': user_info['codebook']}
else:
# 密码错误
return {'errcode': 502, 'errmsg': '密码错误'}
else:
return user_info
else:
return {'errcode': 501, 'errmsg': '签名失败'}
# 处理本地覆写云端数据 用户发来 mail_addr password codebook update_time
def manageUpload(request):
# json化应该能当dict用
try:
data_cache = json.loads(request.form['data'])
except Exception as e:
return {'errcode': 300, 'errmsg': '校验失败'}
checked = checkData(data_cache)
if checked:
# 校验通过
# 获取用户信息
user_info = searchUser(data_cache['mail_addr'])
if user_info['errcode'] == 200:
user_info = user_info['user_info']
if user_info['password'] == data_cache['password']:
# 密码正确
return updateCodebook(user_info['mail_addr'], data_cache['codebook'], data_cache['update_time'])
else:
# 密码错误
return {'errcode': 502, 'errmsg': '密码错误'}
else:
return user_info
else:
return {'errcode': 304, 'errmsg': '签名失败'}
# 工具函数---------------------------------------------------------------
# MD5 校验
def checkData(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']
return True
# 创建用户初始信息
def createUserData(data):
user_info = {
'mail_addr' : data['mail_addr'],
'password': data['password'],
'update_time': data['update_time'],
'codebook': '',
'active': False,
'uuid': create_uuid()
}
return user_info
#生成唯一的名称字符串,防止重名问题
def create_uuid():
# 生成当前时间
nowTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
# 生成的随机整数n其中0<=n<=100
randomNum = random.randint(0, 100)
if randomNum <= 10:
randomNum = str(0) + str(randomNum)
uniqueNum = str(nowTime) + str(randomNum)
return uniqueNum

80
lib/db.py Normal file
View File

@ -0,0 +1,80 @@
from pymongo import MongoClient
from bson import ObjectId, json_util
import re
# 主环境 (生产环境为production开发环境为development)
setting = 'development'
# 获取数据集
def col(arg):
conn = MongoClient('mongodb://ccb:srVgEGwTf4@localhost:27017/ccb')
if setting == 'development':
arg += '_test'
if arg == 'user_info':
return conn.ccb.user_info
elif arg == 'user_info_test':
return conn.ccb.user_info_test
else:
return False
# 查询有无用户
def searchUser(mail_addr):
try:
user_info = col('user_info').find_one({"mail_addr": mail_addr})
if user_info:
return {'errcode': 200, 'user_info': user_info, 'errmsg': 'ok'}
else:
return {'errcode': 101, 'errmsg': '用户不存在'}
except Exception as e:
print(e)
# id不合法
return {'errcode': 102, 'errmsg': 'user_info获取失败'}
# 插入一个新的用户
def insertUser(data):
try:
col('user_info').insert_one(data)
except Exception as e:
# 插入失败
return {'errcode': 103, 'errmsg': '新用户插入失败'}
return {'errcode': 200, 'errmsg': '新用户插入成功'}
# 更新密码本
def updateCodebook(mail_addr, content, update_time):
try:
res = col('user_info').update({"mail_addr": mail_addr},
{'$set': {'codebook': content, 'update_time': update_time}})
# 判断有没有是否成功
if(res['updatedExisting']):
return {'errcode': 200, 'errmsg': 'codebook覆写成功', 'update_time': update_time}
else:
return { 'errcode': 301, 'errmsg': 'codebook用户不存在'}
except Exception as e:
return {'errcode': 302, 'errmsg': 'codebook覆写失败'}
# 激活用户
def ActivateUser(uuid):
try:
res = col('user_info').update({"uuid": uuid},
{'$set': {'active': True}})
# 判断有没有是否成功
if(res['updatedExisting']):
return {'errcode': 200, 'errmsg': 'active覆写成功'}
else:
return { 'errcode': 401, 'errmsg': 'active用户不存在'}
except Exception as e:
return {'errcode': 402, 'errmsg': 'active覆写失败'}
# 查询有无用户
def searchUserByUuid(uuid):
try:
user_info = col('user_info').find_one({"uuid": uuid})
if user_info:
return {'errcode': 200, 'user_info': user_info, 'errmsg': 'ok'}
else:
return {'errcode': 404, 'errmsg': '用户不存在'}
except Exception as e:
print(e)
# id不合法
return {'errcode': 405, 'errmsg': 'user_info获取失败'}

32
lib/mail.py Normal file
View File

@ -0,0 +1,32 @@
# coding=utf-8
import smtplib
from email.mime.text import MIMEText
# 发送纯文本格式的邮件
def sendMail(title, content, mailto_list):
msg = MIMEText(content, 'plain', 'utf-8')
#发送邮箱地址
sender = 'canarycodebook@163.com'
#邮箱授权码,非登陆密码
password = 'eTn49CftDfaytar'
#收件箱地址
#receiver = '19xxxxxxx9@qq.com'
# mailto_list = ['1144131090@qq.com','nayiyewosile@qq.com'] #群发邮箱地址
#smtp服务器
smtp_server = 'smtp.163.com'
#发送邮箱地址
msg['From'] = sender
#收件箱地址
#msg['To'] = receiver
msg['To'] =';'.join(mailto_list) #发送多人邮件写法
#主题
msg['Subject'] = title
server = smtplib.SMTP(smtp_server,25) # SMTP协议默认端口是25
server.login(sender,password) #ogin()方法用来登录SMTP服务器
server.set_debuglevel(1) #打印出和SMTP服务器交互的所有信息。
server.sendmail(sender,mailto_list,msg.as_string()) #msg.as_string()把MIMEText对象变成str server.quit()
# 第一个参数为发送者,第二个参数为接收者,可以添加多个例如:['hello@163.com','xxx@qq.com',]# 第三个参数为发送的内容
server.quit()

4
start.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
cd /home/pi/data/ccb/backEnd
. venv/bin/activate
gunicorn ccb:app -c gunicorn.conf.py

34
test.py Normal file
View File

@ -0,0 +1,34 @@
# coding=utf-8
import smtplib
from email.mime.text import MIMEText
# 发送纯文本格式的邮件
def sendMail(title, content, mailto_list):
msg = MIMEText(content, 'plain', 'utf-8')
#发送邮箱地址
sender = 'canarycodebook@163.com'
#邮箱授权码,非登陆密码
password = 'eTn49CftDfaytar'
#收件箱地址
#receiver = '19xxxxxxx9@qq.com'
# mailto_list = ['1144131090@qq.com','nayiyewosile@qq.com'] #群发邮箱地址
#smtp服务器
smtp_server = 'smtp.163.com'
#发送邮箱地址
msg['From'] = sender
#收件箱地址
#msg['To'] = receiver
msg['To'] =';'.join(mailto_list) #发送多人邮件写法
#主题
msg['Subject'] = title
server = smtplib.SMTP(smtp_server,25) # SMTP协议默认端口是25
server.login(sender,password) #ogin()方法用来登录SMTP服务器
server.set_debuglevel(1) #打印出和SMTP服务器交互的所有信息。
server.sendmail(sender,mailto_list,msg.as_string()) #msg.as_string()把MIMEText对象变成str server.quit()
# 第一个参数为发送者,第二个参数为接收者,可以添加多个例如:['hello@163.com','xxx@qq.com',]# 第三个参数为发送的内容
server.quit()
sendMail('欢迎注册Canary Codebook', 'test', ['1144131090@qq.com'])