views.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. # *************************************************************************
  2. # Copyright © 2015 JiangLin. All rights reserved.
  3. # File Name: auth.py
  4. # Author:JiangLin
  5. # Mail:xiyang0807@gmail.com
  6. # Created Time: 2015-11-25 02:21:04
  7. # *************************************************************************
  8. # !/usr/bin/env python
  9. # -*- coding=UTF-8 -*-
  10. from flask import (render_template,
  11. Blueprint,
  12. redirect,
  13. url_for,
  14. flash,
  15. request,
  16. current_app,
  17. session,
  18. abort,
  19. jsonify)
  20. from flask_login import (login_user,
  21. logout_user,
  22. current_user,
  23. login_required)
  24. from flask_principal import (Identity, AnonymousIdentity,
  25. identity_changed)
  26. from werkzeug.security import generate_password_hash
  27. from maple import redis_data, app, db
  28. from maple.main.permissions import guest_permission, time_permission
  29. from maple.email.email import email_token, email_send, confirm_token
  30. from maple.user.models import User, UserInfor, UserSetting, Role
  31. from maple.auth.forms import LoginForm, RegisterForm, ForgetPasswdForm
  32. from maple.forms.forms import return_errors
  33. from datetime import datetime
  34. site = Blueprint('auth', __name__)
  35. @site.route('/login', methods=['GET', 'POST'])
  36. @guest_permission
  37. def login():
  38. error = None
  39. form = LoginForm()
  40. if form.validate_on_submit() and request.method == "POST":
  41. validate_code = session['validate_code']
  42. validate = form.code.data
  43. if validate.lower() != validate_code.lower():
  44. return jsonify(judge=False, error=u'验证码错误')
  45. else:
  46. name = form.name.data
  47. passwd = form.passwd.data
  48. remember = request.get_json()["remember"]
  49. user = User.load_by_name(name)
  50. if user and User.check_password(user.passwd, passwd):
  51. if remember:
  52. session.permanent = True
  53. login_user(user, remember=remember)
  54. identity_changed.send(current_app._get_current_object(),
  55. identity=Identity(user.id))
  56. flash(u'你已成功登陆')
  57. return jsonify(judge=True, error=error)
  58. else:
  59. error = u'用户名或密码错误'
  60. return jsonify(judge=False, error=error)
  61. else:
  62. if form.errors:
  63. return return_errors(form)
  64. else:
  65. pass
  66. return render_template('auth/login.html', form=form, error=error)
  67. @site.route('/logout')
  68. @login_required
  69. def logout():
  70. '''注销'''
  71. logout_user()
  72. session.clear()
  73. for key in ('identity.id', 'identity.auth_type'):
  74. session.pop(key, None)
  75. identity_changed.send(current_app._get_current_object(),
  76. identity=AnonymousIdentity())
  77. return redirect(request.args.get('next') or url_for('forums.forums'))
  78. @site.route('/register', methods=['GET', 'POST'])
  79. @guest_permission
  80. def register():
  81. error = None
  82. form = RegisterForm()
  83. if form.validate_on_submit() and request.method == "POST":
  84. validate_code = session['validate_code']
  85. validate = form.code.data
  86. if validate.lower() != validate_code.lower():
  87. return jsonify(judge=False, error=u'验证码错误')
  88. else:
  89. useremail = User.load_by_email(form.email.data)
  90. username = User.load_by_name(form.name.data)
  91. if username is not None:
  92. error = u'用户名已存在'
  93. return jsonify(judge=False, error=error)
  94. elif useremail is not None:
  95. error = u'邮箱已被注册'
  96. return jsonify(judge=False, error=error)
  97. else:
  98. account = User(name=form.name.data,
  99. email=form.email.data,
  100. passwd=form.passwd.data)
  101. userinfor = UserInfor()
  102. usersetting = UserSetting()
  103. roles = Role(name='unconfirmed', rank=1)
  104. account.infor = userinfor
  105. account.setting = usersetting
  106. account.roles.append(roles)
  107. '''邮箱验证'''
  108. token = email_token(account.email)
  109. confirm_url = url_for('auth.confirm',
  110. token=token,
  111. _external=True)
  112. html = render_template('templet/email.html',
  113. confirm_url=confirm_url)
  114. subject = "请验证你的邮箱"
  115. email_send(account.email, html, subject)
  116. db.session.add(account)
  117. db.session.commit()
  118. '''记录用户数'''
  119. redis_data.hincrby('user', 'all:count', 1)
  120. login_user(account)
  121. identity_changed.send(current_app._get_current_object(),
  122. identity=Identity(account.id))
  123. '''发送邮件时间'''
  124. from time import time
  125. time = int(time()) + 28800
  126. user = 'user:%s' % str(current_user.id)
  127. redis_data.hset(user, 'send_email_time', time)
  128. flash(u'一封验证邮件已发往你的邮箱,請查收.')
  129. return jsonify(judge=True, error=error)
  130. else:
  131. if form.errors:
  132. return return_errors(form)
  133. else:
  134. pass
  135. if request.args.get('mode') == 'agree':
  136. return render_template('auth/register.html',
  137. form=form,
  138. error=error)
  139. else:
  140. return render_template('auth/register_service.html',
  141. form=form,
  142. error=error)
  143. @site.route('/confirm/<token>')
  144. @login_required
  145. def confirm(token):
  146. email = confirm_token(token)
  147. if not email:
  148. flash('验证链接已过期,请重新获取', 'danger')
  149. return redirect(url_for('user.index', user_url=current_user.name))
  150. user = User.query.filter_by(email=email).first()
  151. if user.is_confirmed:
  152. flash('账户已经验证. Please login.', 'success')
  153. else:
  154. user.is_confirmed = True
  155. user.confirmed_time = datetime.now()
  156. role = Role(name='member', rank=3)
  157. user.roles.append(role)
  158. db.session.commit()
  159. flash('You have confirmed your account. Thanks!', 'success')
  160. return redirect(url_for('forums.forums'))
  161. @site.route('/confirm_email', methods=['GET', 'POST'])
  162. @login_required
  163. def confirm_email():
  164. if request.method == "POST":
  165. if not time_permission.allow():
  166. return time_permission.action()
  167. else:
  168. token = email_token(current_user.email)
  169. '''email模板'''
  170. confirm_url = url_for('auth.confirm', token=token, _external=True)
  171. html = render_template(
  172. 'templet/email.html',
  173. confirm_url=confirm_url)
  174. subject = "Please confirm your email"
  175. email_send(current_user.email, html, subject)
  176. from time import time
  177. time = int(time()) + 28800
  178. user = 'user:%s' % str(current_user.id)
  179. redis_data.hset(user, 'send_email_time', time)
  180. error = '一封验证邮件已发往你的邮箱,請查收.'
  181. return error
  182. else:
  183. abort(404)
  184. @site.route('/forget', methods=['GET', 'POST'])
  185. def forget():
  186. '''忘记密码'''
  187. error = None
  188. form = ForgetPasswdForm()
  189. if form.validate_on_submit() and request.method == "POST":
  190. validate_code = session['validate_code']
  191. validate = form.code.data
  192. if validate.lower() != validate_code.lower():
  193. return jsonify(judge=False, error=u'验证码错误')
  194. else:
  195. exsited_email = User.query.filter_by(
  196. email=form.confirm_email.data).first()
  197. if exsited_email:
  198. '''email模板'''
  199. from random import sample
  200. from string import ascii_letters, digits
  201. npasswd = ''.join(sample(ascii_letters + digits, 8))
  202. exsited_email.passwd = generate_password_hash(npasswd)
  203. db.session.commit()
  204. html = render_template('templet/forget.html',
  205. confirm_url=npasswd)
  206. subject = "请及时修改你的密码"
  207. email_send(form.confirm_email.data, html, subject)
  208. flash(u'邮件已发送到你的邮箱,请及时查收并修改密码')
  209. return jsonify(judge=True, error=error)
  210. else:
  211. error = u'邮箱未注册'
  212. return jsonify(judge=False, error=error)
  213. else:
  214. if form.errors:
  215. return return_errors(form)
  216. else:
  217. pass
  218. return render_template('auth/forget.html', form=form)
  219. @site.route('/validcode', methods=['GET'])
  220. def validcode():
  221. from maple.main.validate_code import ValidateCode
  222. t = ValidateCode()
  223. buf = t.start()
  224. buf_value = buf.getvalue()
  225. response = app.make_response(buf_value)
  226. response.headers['Content-Type'] = 'image/jpeg'
  227. return response