Add mail module and fix reset password api

This commit is contained in:
Chiaki
2017-04-18 14:34:23 +08:00
parent a9b25b872a
commit c6f49c1fe7
6 changed files with 130 additions and 4 deletions

10
account/tasks.py Normal file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from celery import shared_task
from utils.mail import send_email
@shared_task
def _send_email(from_name, to_email, to_name, subject, content):
send_email(from_name, to_email, to_name, subject, content)

View File

@@ -0,0 +1,78 @@
<table cellpadding="0" cellspacing="0" align="center" style="text-align:left;font-family:'微软雅黑','黑体',arial;"
width="742">
<tbody>
<tr>
<td>
<table cellpadding="0" cellspacing="0"
style="text-align:left;border:1px solid #50a5e6;color:#fff;font-size:18px;" width="740">
<tbody>
<tr height="39" style="background-color:#50a5e6;">
<td style="padding-left:15px;font-family:'微软雅黑','黑体',arial;">
{{ website_name }} 登录信息找回
</td>
</tr>
</tbody>
</table>
<table cellpadding="0" cellspacing="0"
style="text-align:left;border:1px solid #f0f0f0;border-top:none;color:#585858;background-color:#fafafa;"
width="740">
<tbody>
<tr height="25">
<td></td>
</tr>
<tr height="40">
<td style="padding-left:25px;padding-right:25px;font-size:18px;font-family:'微软雅黑','黑体',arial;">
Hello, {{ username }}:
</td>
</tr>
<tr height="15">
<td></td>
</tr>
<tr height="30">
<td style="padding-left:55px;padding-right:55px;font-family:'微软雅黑','黑体',arial;font-size:14px;">
您刚刚在 {{ website_name }} 申请了找回登录信息服务。
</td>
</tr>
<tr height="30">
<td style="padding-left:55px;padding-right:55px;font-family:'微软雅黑','黑体',arial;font-size:14px;">
请在<span style="color:rgb(255,0,0)">30分钟</span>内点击下面链接设置您的新密码:
</td>
</tr>
<tr height="60">
<td style="padding-left:55px;padding-right:55px;font-family:'微软雅黑','黑体',arial;font-size:14px;">
<a href="{{ link }}" target="_blank"
style="color: rgb(255,255,255);text-decoration: none;display: block;min-height: 39px;width: 158px;line-height: 39px;background-color:rgb(80,165,230);font-size:20px;text-align:center;">重置密码</a>
</td>
</tr>
<tr height="10">
<td></td>
</tr>
<tr height="20">
<td style="padding-left:55px;padding-right:55px;font-family:'微软雅黑','黑体',arial;font-size:12px;">
如果上面的链接点击无效,请复制以下链接至浏览器的地址栏直接打开。
</td>
</tr>
<tr height="30">
<td style="padding-left:55px;padding-right:65px;font-family:'微软雅黑','黑体',arial;">
<a href="{{ link }}" target="_blank" style="color:#0c94de;font-size:12px;">
{{ link }}
</a>
</td>
</tr>
<tr height="20">
<td style="padding-left:55px;padding-right:55px;font-family:'微软雅黑','黑体',arial;font-size:12px;">
如果您没有提出过该申请,请忽略此邮件。有可能是其他用户误填了您的邮件地址,我们不会对你的帐户进行任何修改。
请不要向他人透露本邮件的内容,否则可能会导致您的账号被盗。
</td>
</tr>
<tr height="20">
<td></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>

View File

@@ -1,14 +1,18 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
from datetime import timedelta from datetime import timedelta
from django.contrib import auth from django.contrib import auth
from django.conf import settings
from django.core.exceptions import MultipleObjectsReturned from django.core.exceptions import MultipleObjectsReturned
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.timezone import now from django.utils.timezone import now
from otpauth import OtpAuth from otpauth import OtpAuth
from conf.models import WebsiteConfig
from utils.api import APIView, validate_serializer from utils.api import APIView, validate_serializer
from utils.captcha import Captcha from utils.captcha import Captcha
from utils.shortcuts import rand_str from utils.shortcuts import rand_str
@@ -18,6 +22,7 @@ from ..models import User, UserProfile
from ..serializers import (UserChangePasswordSerializer, UserLoginSerializer, from ..serializers import (UserChangePasswordSerializer, UserLoginSerializer,
UserRegisterSerializer, UserRegisterSerializer,
ApplyResetPasswordSerializer) ApplyResetPasswordSerializer)
from ..tasks import _send_email
class UserLoginAPI(APIView): class UserLoginAPI(APIView):
@@ -114,14 +119,24 @@ class ApplyResetPasswordAPI(APIView):
except User.DoesNotExist: except User.DoesNotExist:
return self.error(_("User does not exist")) return self.error(_("User does not exist"))
if user.reset_password_token_expire_time and 0 < ( if user.reset_password_token_expire_time and 0 < (
user.reset_password_token_expire_time - now()).total_seconds() < 20 * 60: user.reset_password_token_expire_time - now()).total_seconds() < 20 * 60:
return self.error(_("You can only reset password once per 20 minutes")) return self.error(_("You can only reset password once per 20 minutes"))
user.reset_password_token = rand_str() user.reset_password_token = rand_str()
user.reset_password_token_expire_time = now() + timedelta(minutes=20) user.reset_password_token_expire_time = now() + timedelta(minutes=20)
user.save() user.save()
# TODO:email template email_template = open("reset_password_email.html", "w",
# TODO:send email encoding="utf-8").read()
email_template = email_template.replace("{{ username }}", user.username). \
replace("{{ website_name }}", settings.WEBSITE_INFO["website_name"]). \
replace("{{ link }}", settings.WEBSITE_INFO["url"] + "/reset_password/t/" +
user.reset_password_token)
config = WebsiteConfig.objects.first()
_send_email.delay(config.name,
user.email,
user.username,
config.name + " 登录信息找回邮件",
email_template)
return self.success(_("Succeeded")) return self.success(_("Succeeded"))

View File

@@ -4,3 +4,5 @@ dateutil
otpauth otpauth
pillow pillow
python-dateutil python-dateutil
celery
Envelopes

View File

21
utils/mail.py Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from envelopes import Envelope
from conf.models import SMTPConfig
def send_email(from_name, to_email, to_name, subject, content):
smtp = SMTPConfig.objects.first()
if not smtp:
return
envlope = Envelope(from_addr=(smtp.email, from_name),
to_addr=(to_email, to_name),
subject=subject,
html_body=content)
envlope.send(smtp.server,
login=smtp.email,
password=smtp.password,
port=smtp.port,
tls=smtp.tls)