diff --git a/account/serializers.py b/account/serializers.py index fe128f6..a16caa8 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -44,3 +44,9 @@ class EditUserSerializer(serializers.Serializer): open_api = serializers.BooleanField() two_factor_auth = serializers.BooleanField() is_disabled = serializers.BooleanField() + + +class ApplyResetPasswordSerializer(serializers.Serializer): + email = serializers.EmailField() + captcha = serializers.CharField(max_length=4, min_length=4) + diff --git a/account/urls/oj.py b/account/urls/oj.py index 6a1ef6c..899f26a 100644 --- a/account/urls/oj.py +++ b/account/urls/oj.py @@ -1,9 +1,15 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + from django.conf.urls import url -from ..views.oj import UserChangePasswordAPI, UserLoginAPI, UserRegisterAPI +from ..views.oj import (UserChangePasswordAPI, UserLoginAPI, UserRegisterAPI, + ApplyResetPasswordAPI, ResetPasswordAPI) urlpatterns = [ url(r"^login$", UserLoginAPI.as_view(), name="user_login_api"), url(r"^register$", UserRegisterAPI.as_view(), name="user_register_api"), - url(r"^change_password$", UserChangePasswordAPI.as_view(), name="user_change_password_api") + url(r"^change_password$", UserChangePasswordAPI.as_view(), name="user_change_password_api"), + url(r"^apply_reset_password$", ApplyResetPasswordAPI.as_view(), name="apply_reset_password_api"), + url(r'^reset_password$', ResetPasswordAPI.as_view(), name="apply_reset_password_api") ] diff --git a/account/urls/user.py b/account/urls/user.py index 7ddca03..518b952 100644 --- a/account/urls/user.py +++ b/account/urls/user.py @@ -3,8 +3,9 @@ from django.conf.urls import url -from ..views.user import UserProfileAPI +from ..views.user import UserInfoAPI ,UserProfileAPI urlpatterns = [ + url(r"^user", UserInfoAPI.as_view(), name="user_info_api"), url(r"^profile$", UserProfileAPI.as_view(), name="user_profile_api"), ] diff --git a/account/views/oj.py b/account/views/oj.py index 3e48a12..6d47dcb 100644 --- a/account/views/oj.py +++ b/account/views/oj.py @@ -1,15 +1,25 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import codecs +from datetime import timedelta + from django.contrib import auth +from django.conf import settings from django.core.exceptions import MultipleObjectsReturned from django.utils.translation import ugettext as _ +from django.utils.timezone import now from otpauth import OtpAuth from utils.api import APIView, validate_serializer from utils.captcha import Captcha +from utils.shortcuts import rand_str from ..decorators import login_required from ..models import User, UserProfile from ..serializers import (UserChangePasswordSerializer, UserLoginSerializer, - UserRegisterSerializer) + UserRegisterSerializer, + ApplyResetPasswordSerializer) class UserLoginAPI(APIView): @@ -92,3 +102,44 @@ class UserChangePasswordAPI(APIView): return self.success(_("Succeeded")) else: return self.error(_("Invalid old password")) + + +class ApplyResetPasswordAPI(APIView): + @validate_serializer(ApplyResetPasswordSerializer) + def post(self, request): + data = request.data + captcha = Captcha(request) + if not captcha.check(data["captcha"]): + return self.error(_("Invalid captcha")) + try: + user = User.objects.get(email=data["email"]) + except User.DoesNotExist: + return self.error(_("User does not exist")) + if user.reset_password_token_expire_time and 0 < ( + user.reset_password_token_expire_time - now()).total_seconds() < 20 * 60: + return self.error(_("You can only reset password once per 20 minutes")) + user.reset_password_token = rand_str() + + user.reset_password_token_expire_time = now() + timedelta(minutes=20) + user.save() + # TODO:email template + # TODO:send email + return self.success(_("Succeeded")) + + +class ResetPasswordAPI(APIView): + def post(self, request): + data = request.data + captcha = Captcha(request) + if not captcha.check(data["captcha"]): + return self.error(_("Invalid captcha")) + try: + user = User.objects.get(reset_password_token=data["token"]) + except User.DoesNotExist: + return self.error(_("Token dose not exist")) + if 0 < (user.reset_password_token_expire_time - now()).total_seconds() < 30 * 60: + return self.error(_("Token expired")) + user.reset_password_token = None + user.set_password(data["password"]) + user.save() + return self.success(_("Succeeded")) diff --git a/account/views/user.py b/account/views/user.py index f20a77b..190c39c 100644 --- a/account/views/user.py +++ b/account/views/user.py @@ -9,13 +9,13 @@ from ..decorators import login_required from ..serializers import EditUserSerializer, UserSerializer -# class UserInfoAPI(APIView): -# @login_required -# def get(self, request): -# """ -# Return user info api -# """ -# return self.success(UserSerializer(request.user).data) +class UserInfoAPI(APIView): + @login_required + def get(self, request): + """ + Return user info api + """ + return self.success(UserSerializer(request.user).data) class UserProfileAPI(APIView): @@ -43,5 +43,3 @@ class UserProfileAPI(APIView): # Timezone & language 暂时不加 user_profile.save() return self.success(_("Succeeded")) - -