implement activation code
This commit is contained in:
parent
2cebb06f76
commit
7953235912
@ -1,5 +1,5 @@
|
|||||||
app:
|
app:
|
||||||
NAME: APP_NAME
|
NAME: web-gpt
|
||||||
SECRET_KEY: SOME_RANDOM_STRING
|
SECRET_KEY: SOME_RANDOM_STRING
|
||||||
HOMEPAGE_NOTICE: |
|
HOMEPAGE_NOTICE: |
|
||||||
1. 此网站基于openAI的API提供服务
|
1. 此网站基于openAI的API提供服务
|
||||||
|
@ -20,6 +20,7 @@ def create_app():
|
|||||||
print("config file path: ", config_file)
|
print("config file path: ", config_file)
|
||||||
with open(config_file) as config_file:
|
with open(config_file) as config_file:
|
||||||
conf = yaml.safe_load(config_file)
|
conf = yaml.safe_load(config_file)
|
||||||
|
app.config['NAME'] = conf['app']['NAME']
|
||||||
app.config['SECRET_KEY'] = conf['app']['SECRET_KEY']
|
app.config['SECRET_KEY'] = conf['app']['SECRET_KEY']
|
||||||
app.config['LOGGING_LEVEL'] = conf['app']['LOGGING_LEVEL']
|
app.config['LOGGING_LEVEL'] = conf['app']['LOGGING_LEVEL']
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = conf['app']['SQLALCHEMY_DATABASE_URI']
|
app.config['SQLALCHEMY_DATABASE_URI'] = conf['app']['SQLALCHEMY_DATABASE_URI']
|
||||||
@ -30,6 +31,8 @@ def create_app():
|
|||||||
app.config['OPENAI_PROMPT'] = conf['openai']['PROMPT']
|
app.config['OPENAI_PROMPT'] = conf['openai']['PROMPT']
|
||||||
app.config['mail'] = conf['mail']
|
app.config['mail'] = conf['mail']
|
||||||
|
|
||||||
|
app.add_template_global(app.config['NAME'], "web_title")
|
||||||
|
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
login_manager = LoginManager()
|
login_manager = LoginManager()
|
||||||
login_manager.login_view = 'auth.login'
|
login_manager.login_view = 'auth.login'
|
||||||
|
@ -1,14 +1,38 @@
|
|||||||
from flask_login import login_user, logout_user
|
from flask_login import login_user, logout_user
|
||||||
from flask import Blueprint, render_template, redirect, url_for, request, flash
|
from flask import Blueprint, render_template, redirect, url_for, request, flash, current_app
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
from flask_login import login_required, current_user, login_manager
|
from flask_login import login_required, current_user, login_manager
|
||||||
from .models import User, Conversation
|
from .models import User, Conversation
|
||||||
from . import db
|
from . import db
|
||||||
import time
|
import time
|
||||||
|
import hashlib
|
||||||
|
|
||||||
auth = Blueprint('auth', __name__)
|
auth = Blueprint('auth', __name__)
|
||||||
|
|
||||||
|
|
||||||
|
def hash_to_digit(instr: str) -> str:
|
||||||
|
outstr = hashlib.md5(instr.encode('utf-8')).hexdigest()
|
||||||
|
outstr = f"{int(outstr, 16) % 1000000:0>6d}"
|
||||||
|
return outstr
|
||||||
|
|
||||||
|
|
||||||
|
def gen_activation_code(email: str) -> str:
|
||||||
|
current_time_slot = int(time.time() // 60)
|
||||||
|
s = email + current_app.config['SECRET_KEY'] + str(current_time_slot)
|
||||||
|
activation_code = hash_to_digit(s)
|
||||||
|
return activation_code
|
||||||
|
|
||||||
|
|
||||||
|
def check_activation_code(email: str, activation_code: str) -> bool:
|
||||||
|
current_time_slot = int(time.time() // 60)
|
||||||
|
for time_slot in range(current_time_slot-10, current_time_slot+1):
|
||||||
|
s = email + current_app.config['SECRET_KEY'] + str(time_slot)
|
||||||
|
expected_code = hash_to_digit(s)
|
||||||
|
if expected_code == activation_code:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@auth.route('/login')
|
@auth.route('/login')
|
||||||
def login():
|
def login():
|
||||||
return render_template('login.html')
|
return render_template('login.html')
|
||||||
@ -35,6 +59,22 @@ def login_post():
|
|||||||
return redirect(url_for('main.index'))
|
return redirect(url_for('main.index'))
|
||||||
|
|
||||||
|
|
||||||
|
@auth.route('/activate', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def activate():
|
||||||
|
activation_code = request.form.get('activation_code')
|
||||||
|
if check_activation_code(current_user.email, activation_code):
|
||||||
|
account = User.query.filter_by(
|
||||||
|
id=current_user.id, email=current_user.email, name=current_user.name).first()
|
||||||
|
if account:
|
||||||
|
if db.session.query(User).filter(User.id == account.id).update({"isActivated": True}) and not db.session.commit():
|
||||||
|
time.sleep(0.05)
|
||||||
|
return redirect(url_for('main.index'))
|
||||||
|
time.sleep(1)
|
||||||
|
flash("激活码不匹配")
|
||||||
|
return redirect(url_for('main.index'))
|
||||||
|
|
||||||
|
|
||||||
@auth.route('/signup')
|
@auth.route('/signup')
|
||||||
def signup():
|
def signup():
|
||||||
return render_template('signup.html')
|
return render_template('signup.html')
|
||||||
@ -53,12 +93,12 @@ def signup_post():
|
|||||||
flash('此邮箱已注册!')
|
flash('此邮箱已注册!')
|
||||||
return redirect(url_for('auth.signup'))
|
return redirect(url_for('auth.signup'))
|
||||||
if not (email):
|
if not (email):
|
||||||
flash('Email missing!')
|
flash('请输入邮箱!')
|
||||||
return redirect(url_for('auth.signup'))
|
return redirect(url_for('auth.signup'))
|
||||||
if not (name):
|
if not (name):
|
||||||
name = email
|
name = email
|
||||||
if not (password):
|
if not (password):
|
||||||
flash('Password missing!')
|
flash('请输入密码')
|
||||||
return redirect(url_for('auth.signup'))
|
return redirect(url_for('auth.signup'))
|
||||||
# create a new user with the form data. Hash the password so the plaintext version isn't saved.
|
# create a new user with the form data. Hash the password so the plaintext version isn't saved.
|
||||||
new_user = User(email=email,
|
new_user = User(email=email,
|
||||||
@ -74,6 +114,11 @@ def signup_post():
|
|||||||
# add the new user to the database
|
# add the new user to the database
|
||||||
db.session.add(new_user)
|
db.session.add(new_user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
activation_code = gen_activation_code(new_user.email)
|
||||||
|
from . import smtp
|
||||||
|
smtp.sendmail(new_user.email, "web-gpt激活码", "欢迎注册。您的激活码是:"+activation_code)
|
||||||
|
|
||||||
return redirect(url_for('auth.login'))
|
return redirect(url_for('auth.login'))
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ import logging
|
|||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from email.header import Header
|
from email.header import Header
|
||||||
from . import app
|
from flask import current_app
|
||||||
|
|
||||||
mail_config = app['mail']
|
mail_config = current_app.config['mail']
|
||||||
logger = logging.getLogger('waitress')
|
logger = logging.getLogger('waitress')
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<title>Flask</title>
|
<title>{{ web_title }}</title>
|
||||||
<link rel="shortcut icon"
|
<link rel="shortcut icon"
|
||||||
href="{{ url_for('static', filename='favicon.ico') }}"/>
|
href="{{ url_for('static', filename='favicon.ico') }}"/>
|
||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
|
@ -7,13 +7,36 @@
|
|||||||
你好,游客!
|
你好,游客!
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h2>
|
</h2>
|
||||||
|
{% with messages = get_flashed_messages() %}
|
||||||
|
{% if messages %}<div class="notification is-danger">{{ messages[0] }}</div>{% endif %}
|
||||||
|
{% endwith %}
|
||||||
{% if user and user.is_authenticated %}
|
{% if user and user.is_authenticated %}
|
||||||
{% if user.isActivated %}
|
{% if user.isActivated %}
|
||||||
<a href="{{ url_for('main.chat') }}">
|
<a href="{{ url_for('main.chat') }}">
|
||||||
<button type="button" class="btn btn-primary">开始聊天</button>
|
<button type="button" class="btn btn-primary">开始聊天</button>
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-warning">您的账号暂未激活,请等待管理员激活此账号。</p>
|
<div class="column is-4 is-offset-4">
|
||||||
|
<div class="box">
|
||||||
|
<p class="text-warning">您的账号暂未激活。</p>
|
||||||
|
<p class="text-warning">如未收到激活码邮件,请联系管理员处理</p>
|
||||||
|
<br/>
|
||||||
|
<form method="post" action="{{ url_for('auth.activate') }}">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input is-large"
|
||||||
|
type="text"
|
||||||
|
name="activation_code"
|
||||||
|
placeholder="激活码"
|
||||||
|
autofocus=""
|
||||||
|
required="required"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="button is-block is-info is-large is-fullwidth">激活</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{{ url_for('auth.login') }}">
|
<a href="{{ url_for('auth.login') }}">
|
||||||
@ -24,9 +47,6 @@
|
|||||||
<button type="button" class="btn btn-default">注册</button>
|
<button type="button" class="btn btn-default">注册</button>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% with messages = get_flashed_messages() %}
|
|
||||||
{% if messages %}<div class="notification is-danger">{{ messages[0] }}</div>{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
<div id="homepage-notice" class="row" style="margin-top: 100px;">
|
<div id="homepage-notice" class="row" style="margin-top: 100px;">
|
||||||
{% if homepage_notice %}
|
{% if homepage_notice %}
|
||||||
<h3 class="subtitle">公告栏</h3>
|
<h3 class="subtitle">公告栏</h3>
|
||||||
|
Reference in New Issue
Block a user