Skip to content

Commit 648a130

Browse files
committed
完善邮件发送功能 #39
- 用户注册后发送欢迎邮件 - 重置密码成功后发送通知邮件 - 优化发送密码模板的结构 - 修正登陆时密码验证逻辑错误的问题
1 parent 4927602 commit 648a130

File tree

5 files changed

+49
-9
lines changed

5 files changed

+49
-9
lines changed

website/scriptfan/forms/user.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
定义用户相关页面所用到的表单, 包括注册、登陆、基本资料修改、密码修改、邮箱修改等。
77
"""
88

9+
from flask import current_app as app
910
from flask.ext import wtf
1011
from flask.ext.login import current_user
1112
from flask.ext.babel import gettext as _
@@ -47,7 +48,7 @@ def validate(self):
4748
if not super(RedirectForm, self).validate(): return False
4849

4950
user = User.get_by_email(self.email.data)
50-
if not user or user.check_password(self.password.data):
51+
if not user or not user.check_password(self.password.data):
5152
self.email.errors.append(_('forms.signin.errors.invalid_email_or_password'))
5253
else:
5354
self.user = user
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{%- set home_url = url_for('home.index', _external=True) -%}
2+
<strong>{{ user.nickname }},你好!</strong>
3+
4+
你的 ScriptFan 的密码已经修改。
5+
6+
<p>想了解更多信息,请访问 <a href="{{ home_url }}">{{ home_url }}</a></p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{%- set home_url = url_for('home.index', _external=True) -%}
2+
<strong>{{ user.nickname }},你好!</strong>
3+
4+
<p>想了解更多信息,请访问 <a href="{{ home_url }}">{{ home_url }}</a></p>

website/scriptfan/views/users.py

+37-8
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ def _create_or_login(resp):
218218
db.session.add(user)
219219
db.session.commit()
220220

221+
_send_welcome_email(user)
222+
221223
flash(u'帐号已经创建, 可以在资料<a href="%s">修改页面</a>补充密码等信息'% url_for('users.general'), 'success')
222224

223225
app.logger.info('Signin users: %s', user.email)
@@ -240,6 +242,7 @@ def signup():
240242
user.set_password(form.password1.data)
241243
db.session.add(user)
242244
app.logger.info(u'New users added: %s', user)
245+
_send_welcome_email(user)
243246
flash(u'注册成功', 'success')
244247
return redirect(url_for('users.signin'))
245248

@@ -279,8 +282,6 @@ def general():
279282
# TODO 处理更新用户资料的请求
280283
# TODO 用户照片上传
281284

282-
# TODO: 用户找回密码功能
283-
284285
# 更新用户slug功能
285286
@blurprint.route('/slug', methods=['GET', 'POST'])
286287
@login.login_required
@@ -296,14 +297,27 @@ def slug():
296297
form.process(obj=current_user.user)
297298
return render_template('users/slug.html', form=form, skip_slug_info=True)
298299

300+
def _send_welcome_email(user):
301+
""" 发送欢迎邮件 """
302+
303+
try:
304+
app.logger.info('Sending welcome email to %s', user.email)
305+
msg = Message(u'欢迎来到ScriptFan', recipients=[user.email])
306+
msg.html = render_template('users/email/welcome.html', user=user)
307+
# FIXME: 邮件发送使用异步方式,避免用户等待太长时间
308+
mail.send(msg)
309+
app.logger.info('Mail sent successfully.')
310+
except Exception, e:
311+
app.logger.info(e.message)
312+
app.logger.error('Failed to send welcome reset mail, because: %s', e)
299313

300314
def _send_reset_email(user, token):
301315
""" 发送密码重置邮件 """
302316

303317
try:
304318
app.logger.info('Sending reset email to %s with token %s', user.email, token)
305319
msg = Message(u'ScriptFan密码重置', recipients=[user.email])
306-
msg.html = render_template('users/reset_email.html', user=user, token=token)
320+
msg.html = render_template('users/email/reset.html', user=user, token=token)
307321
# FIXME: 邮件发送使用异步方式,避免用户等待太长时间
308322
mail.send(msg)
309323
app.logger.info('Mail sent successfully.')
@@ -313,6 +327,20 @@ def _send_reset_email(user, token):
313327
app.logger.error('Failed to send password reset mail, because: %s', e)
314328
return False
315329

330+
def _send_reset_success_email(user):
331+
""" 发送重置通知邮件 """
332+
333+
try:
334+
app.logger.info('Sending email confirm notification to %s', user.email)
335+
msg = Message(u'你在 ScriptFan 的密码已经重置!', recipients=[user.email])
336+
msg.html = render_template('users/email/reset_success.html', user=user)
337+
# FIXME: 邮件发送使用异步方式,避免用户等待太长时间
338+
mail.send(msg)
339+
app.logger.info('Mail sent successfully.')
340+
except Exception, e:
341+
app.logger.info(e.message)
342+
app.logger.error('Failed to send email reset notification mail, because: %s', e)
343+
316344

317345
@blurprint.route('/reset/step1', methods=['GET', 'POST'])
318346
def reset_step1():
@@ -336,11 +364,12 @@ def reset_step1():
336364

337365
def _valid_reset_token():
338366
""" 验证重置口令及邮件地址是否匹配 """
339-
367+
email, token = request.args.get('email'), request.args.get('token')
368+
app.logger.info('Validating email reset with email: %s and token: %s', email, token)
340369
return session.get('reset_email') and \
341370
session.get('reset_token') and \
342-
session['reset_email'] == request.args['email'] and \
343-
session['reset_token'] == request.args['token']
371+
session['reset_email'] == email and \
372+
session['reset_token'] == token
344373

345374
@blurprint.route('/reset/step2', methods=['GET', 'POST'])
346375
def reset_step2():
@@ -353,12 +382,12 @@ def reset_step2():
353382
user.set_password(form.password.data)
354383
flash(u'用户密码已经更新', 'success')
355384

356-
# TODO: 通过重置密码功能修改密码成功后,向用户发送邮件提醒。
357-
358385
# 清除验证用的 Token
359386
del session['reset_email']
360387
del session['reset_token']
361388

389+
_send_reset_success_email(user)
390+
362391
return redirect(url_for('users.signin'))
363392

364393
# 如果邮件及当前token均匹配,则显示重置密码的表单

0 commit comments

Comments
 (0)