2015-06-29 04:43:17 +00:00
|
|
|
|
# coding=utf-8
|
2015-10-09 08:17:07 +00:00
|
|
|
|
import codecs
|
2015-12-11 14:43:23 +00:00
|
|
|
|
import qrcode
|
|
|
|
|
import StringIO
|
2015-08-27 14:26:00 +00:00
|
|
|
|
from django import http
|
2015-06-29 04:43:17 +00:00
|
|
|
|
from django.contrib import auth
|
|
|
|
|
from django.shortcuts import render
|
2015-08-07 12:25:58 +00:00
|
|
|
|
from django.db.models import Q
|
2015-09-24 06:55:20 +00:00
|
|
|
|
from django.conf import settings
|
2015-12-11 14:43:23 +00:00
|
|
|
|
from django.http import HttpResponse
|
2015-10-10 11:33:31 +00:00
|
|
|
|
from django.core.exceptions import MultipleObjectsReturned
|
2015-10-16 12:49:01 +00:00
|
|
|
|
from django.utils.timezone import now
|
2015-08-07 12:25:58 +00:00
|
|
|
|
|
2015-06-29 04:43:17 +00:00
|
|
|
|
from rest_framework.views import APIView
|
2015-09-17 02:53:33 +00:00
|
|
|
|
from rest_framework.response import Response
|
2015-10-16 12:49:01 +00:00
|
|
|
|
from utils.shortcuts import (serializer_invalid_response, error_response,
|
|
|
|
|
success_response, error_page, paginate, rand_str)
|
2015-09-10 07:59:48 +00:00
|
|
|
|
from utils.captcha import Captcha
|
2015-12-11 14:43:23 +00:00
|
|
|
|
from utils.otp_auth import OtpAuth
|
2015-10-09 08:17:07 +00:00
|
|
|
|
|
2015-12-12 07:41:57 +00:00
|
|
|
|
from .tasks import _send_email
|
2015-10-09 08:17:07 +00:00
|
|
|
|
|
2015-08-12 14:59:27 +00:00
|
|
|
|
from .decorators import login_required
|
2015-11-08 15:05:02 +00:00
|
|
|
|
from .models import User, UserProfile
|
2015-11-10 10:46:51 +00:00
|
|
|
|
|
2015-11-09 13:11:39 +00:00
|
|
|
|
from .serializers import (UserLoginSerializer, UserRegisterSerializer,
|
|
|
|
|
UserChangePasswordSerializer,
|
|
|
|
|
UserSerializer, EditUserSerializer,
|
2015-10-20 12:09:23 +00:00
|
|
|
|
ApplyResetPasswordSerializer, ResetPasswordSerializer,
|
2015-12-11 14:43:23 +00:00
|
|
|
|
SSOSerializer, EditUserProfileSerializer,
|
2015-12-11 15:00:31 +00:00
|
|
|
|
UserProfileSerializer, TwoFactorAuthCodeSerializer)
|
2015-11-10 10:46:51 +00:00
|
|
|
|
|
2015-09-24 06:55:20 +00:00
|
|
|
|
from .decorators import super_admin_required
|
2015-06-29 04:43:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserLoginAPIView(APIView):
|
|
|
|
|
def post(self, request):
|
|
|
|
|
"""
|
|
|
|
|
用户登录json api接口
|
|
|
|
|
---
|
|
|
|
|
request_serializer: UserLoginSerializer
|
|
|
|
|
"""
|
2015-08-07 14:01:16 +00:00
|
|
|
|
serializer = UserLoginSerializer(data=request.data)
|
2015-06-29 04:43:17 +00:00
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
|
|
|
|
user = auth.authenticate(username=data["username"], password=data["password"])
|
|
|
|
|
# 用户名或密码错误的话 返回None
|
|
|
|
|
if user:
|
2015-12-12 13:12:00 +00:00
|
|
|
|
if not user.two_factor_auth:
|
|
|
|
|
auth.login(request, user)
|
|
|
|
|
return success_response(u"登录成功")
|
|
|
|
|
|
|
|
|
|
# 没有输入两步验证的验证码
|
|
|
|
|
if user.two_factor_auth and "tfa_code" not in data:
|
|
|
|
|
return success_response("tfa_required")
|
|
|
|
|
|
|
|
|
|
if OtpAuth(user.tfa_token).valid_totp(data["tfa_code"]):
|
|
|
|
|
auth.login(request, user)
|
|
|
|
|
return success_response(u"登录成功")
|
|
|
|
|
else:
|
|
|
|
|
return error_response(u"验证码错误")
|
2015-06-29 04:43:17 +00:00
|
|
|
|
else:
|
|
|
|
|
return error_response(u"用户名或密码错误")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
2015-09-13 13:58:13 +00:00
|
|
|
|
|
2016-03-26 17:26:24 +00:00
|
|
|
|
#@login_required
|
2015-08-28 09:12:41 +00:00
|
|
|
|
def logout(request):
|
2015-08-27 14:26:00 +00:00
|
|
|
|
auth.logout(request)
|
|
|
|
|
return http.HttpResponseRedirect("/")
|
|
|
|
|
|
2015-09-13 13:58:13 +00:00
|
|
|
|
|
2015-09-14 03:37:41 +00:00
|
|
|
|
def index_page(request):
|
2015-09-13 13:58:13 +00:00
|
|
|
|
if not request.user.is_authenticated():
|
|
|
|
|
return render(request, "oj/index.html")
|
|
|
|
|
|
2015-11-27 14:23:00 +00:00
|
|
|
|
if request.META.get('HTTP_REFERER') or request.GET.get("index"):
|
2015-12-12 07:41:57 +00:00
|
|
|
|
return render(request, "oj/index.html")
|
2015-11-27 14:23:00 +00:00
|
|
|
|
else:
|
2015-09-13 13:58:13 +00:00
|
|
|
|
return http.HttpResponseRedirect('/problems/')
|
|
|
|
|
|
|
|
|
|
|
2015-08-03 10:45:26 +00:00
|
|
|
|
class UserRegisterAPIView(APIView):
|
2015-06-29 04:43:17 +00:00
|
|
|
|
def post(self, request):
|
2015-08-03 10:45:26 +00:00
|
|
|
|
"""
|
|
|
|
|
用户注册json api接口
|
|
|
|
|
---
|
|
|
|
|
request_serializer: UserRegisterSerializer
|
|
|
|
|
"""
|
2015-08-07 14:01:16 +00:00
|
|
|
|
serializer = UserRegisterSerializer(data=request.data)
|
2015-08-03 10:45:26 +00:00
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
2015-09-17 02:24:01 +00:00
|
|
|
|
captcha = Captcha(request)
|
|
|
|
|
if not captcha.check(data["captcha"]):
|
|
|
|
|
return error_response(u"验证码错误")
|
2015-08-03 10:45:26 +00:00
|
|
|
|
try:
|
|
|
|
|
User.objects.get(username=data["username"])
|
|
|
|
|
return error_response(u"用户名已存在")
|
|
|
|
|
except User.DoesNotExist:
|
2015-08-05 12:11:25 +00:00
|
|
|
|
pass
|
|
|
|
|
try:
|
|
|
|
|
User.objects.get(email=data["email"])
|
|
|
|
|
return error_response(u"该邮箱已被注册,请换其他邮箱进行注册")
|
2015-10-10 11:33:31 +00:00
|
|
|
|
# 兼容部分老数据,有邮箱重复的
|
|
|
|
|
except MultipleObjectsReturned:
|
|
|
|
|
return error_response(u"该邮箱已被注册,请换其他邮箱进行注册")
|
2015-08-05 12:11:25 +00:00
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
user = User.objects.create(username=data["username"], real_name=data["real_name"],
|
|
|
|
|
email=data["email"])
|
2015-08-03 10:45:26 +00:00
|
|
|
|
user.set_password(data["password"])
|
|
|
|
|
user.save()
|
2015-12-08 06:33:40 +00:00
|
|
|
|
UserProfile.objects.create(user=user, school=data["school"], student_id=data["student_id"])
|
2015-08-03 10:45:26 +00:00
|
|
|
|
return success_response(u"注册成功!")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-07-17 03:00:15 +00:00
|
|
|
|
|
|
|
|
|
|
2015-08-03 11:54:55 +00:00
|
|
|
|
class UserChangePasswordAPIView(APIView):
|
2015-09-01 11:04:07 +00:00
|
|
|
|
@login_required
|
2015-07-17 03:00:15 +00:00
|
|
|
|
def post(self, request):
|
2015-08-03 11:54:55 +00:00
|
|
|
|
"""
|
|
|
|
|
用户修改密码json api接口
|
|
|
|
|
---
|
|
|
|
|
request_serializer: UserChangePasswordSerializer
|
|
|
|
|
"""
|
2015-08-07 14:01:16 +00:00
|
|
|
|
serializer = UserChangePasswordSerializer(data=request.data)
|
2015-08-03 11:54:55 +00:00
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
2015-09-10 07:59:48 +00:00
|
|
|
|
captcha = Captcha(request)
|
|
|
|
|
if not captcha.check(data["captcha"]):
|
|
|
|
|
return error_response(u"验证码错误")
|
2015-09-01 11:04:07 +00:00
|
|
|
|
username = request.user.username
|
|
|
|
|
user = auth.authenticate(username=username, password=data["old_password"])
|
2015-08-03 11:54:55 +00:00
|
|
|
|
if user:
|
|
|
|
|
user.set_password(data["new_password"])
|
|
|
|
|
user.save()
|
|
|
|
|
return success_response(u"用户密码修改成功!")
|
|
|
|
|
else:
|
|
|
|
|
return error_response(u"密码不正确,请重新修改!")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-08-03 08:52:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UsernameCheckAPIView(APIView):
|
2015-09-17 02:53:33 +00:00
|
|
|
|
def get(self, request):
|
2015-08-03 08:52:31 +00:00
|
|
|
|
"""
|
2015-09-17 02:53:33 +00:00
|
|
|
|
检测用户名是否存在,存在返回状态码400,不存在返回200
|
2015-08-03 08:52:31 +00:00
|
|
|
|
---
|
|
|
|
|
"""
|
2015-09-17 02:53:33 +00:00
|
|
|
|
username = request.GET.get("username", None)
|
|
|
|
|
if username:
|
2015-08-03 08:52:31 +00:00
|
|
|
|
try:
|
2015-09-17 02:53:33 +00:00
|
|
|
|
User.objects.get(username=username)
|
|
|
|
|
return Response(status=400)
|
2015-08-03 08:52:31 +00:00
|
|
|
|
except User.DoesNotExist:
|
2015-09-17 02:53:33 +00:00
|
|
|
|
return Response(status=200)
|
|
|
|
|
return Response(status=200)
|
2015-08-05 12:11:25 +00:00
|
|
|
|
|
2015-08-06 11:07:46 +00:00
|
|
|
|
|
2015-08-05 12:11:25 +00:00
|
|
|
|
class EmailCheckAPIView(APIView):
|
2015-09-17 02:53:33 +00:00
|
|
|
|
def get(self, request):
|
2015-08-05 12:11:25 +00:00
|
|
|
|
"""
|
2015-11-29 01:39:39 +00:00
|
|
|
|
检测邮箱是否存在,用状态码标识结果
|
2015-08-05 12:11:25 +00:00
|
|
|
|
---
|
|
|
|
|
"""
|
2015-12-11 14:43:23 +00:00
|
|
|
|
# 这里是为了适应前端表单验证空间的要求
|
2015-11-29 01:39:39 +00:00
|
|
|
|
reset = request.GET.get("reset", None)
|
2015-12-11 14:43:23 +00:00
|
|
|
|
# 如果reset为true说明该请求是重置密码页面发出的,要返回的状态码应正好相反
|
2015-11-29 01:39:39 +00:00
|
|
|
|
if reset:
|
|
|
|
|
existed = 200
|
|
|
|
|
does_not_existed = 400
|
|
|
|
|
else:
|
|
|
|
|
existed = 400
|
|
|
|
|
does_not_existed = 200
|
|
|
|
|
|
2015-09-17 02:53:33 +00:00
|
|
|
|
email = request.GET.get("email", None)
|
|
|
|
|
if email:
|
2015-08-05 12:11:25 +00:00
|
|
|
|
try:
|
2015-09-17 02:53:33 +00:00
|
|
|
|
User.objects.get(email=email)
|
2015-11-29 01:39:39 +00:00
|
|
|
|
return Response(status=existed)
|
2015-10-10 11:33:31 +00:00
|
|
|
|
except Exception:
|
2015-11-29 01:39:39 +00:00
|
|
|
|
return Response(status=does_not_existed)
|
|
|
|
|
return Response(status=does_not_existed)
|
2015-08-07 12:25:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserAdminAPIView(APIView):
|
2015-09-24 06:55:20 +00:00
|
|
|
|
@super_admin_required
|
2015-08-07 12:25:58 +00:00
|
|
|
|
def put(self, request):
|
|
|
|
|
"""
|
|
|
|
|
用户编辑json api接口
|
|
|
|
|
---
|
|
|
|
|
request_serializer: EditUserSerializer
|
|
|
|
|
response_serializer: UserSerializer
|
|
|
|
|
"""
|
2015-08-07 14:01:16 +00:00
|
|
|
|
serializer = EditUserSerializer(data=request.data)
|
2015-08-07 12:25:58 +00:00
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
|
|
|
|
try:
|
|
|
|
|
user = User.objects.get(id=data["id"])
|
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_response(u"该用户不存在!")
|
2015-08-14 02:21:50 +00:00
|
|
|
|
try:
|
|
|
|
|
user = User.objects.get(username=data["username"])
|
|
|
|
|
if user.id != data["id"]:
|
|
|
|
|
return error_response(u"昵称已经存在")
|
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
pass
|
2015-08-07 12:25:58 +00:00
|
|
|
|
user.username = data["username"]
|
|
|
|
|
user.real_name = data["real_name"]
|
|
|
|
|
user.email = data["email"]
|
|
|
|
|
user.admin_type = data["admin_type"]
|
2016-02-17 01:45:35 +00:00
|
|
|
|
|
2015-08-07 12:25:58 +00:00
|
|
|
|
if data["password"]:
|
|
|
|
|
user.set_password(data["password"])
|
2016-02-17 01:45:35 +00:00
|
|
|
|
|
|
|
|
|
# 后台控制用户是否可以使用openapi
|
|
|
|
|
if data["openapi"] is False:
|
|
|
|
|
user.openapi_appkey = None
|
|
|
|
|
elif data["openapi"] and user.openapi_appkey is None:
|
|
|
|
|
user.openapi_appkey = rand_str()
|
|
|
|
|
|
|
|
|
|
# 后台控制用户是否使用两步验证
|
|
|
|
|
# 注意:用户没开启,后台开启的话,用户没有绑定过两步验证token,会造成无法登陆的!
|
|
|
|
|
if data["tfa_auth"] is False:
|
|
|
|
|
user.two_factor_auth = False
|
|
|
|
|
elif data["tfa_auth"] and user.two_factor_auth is False:
|
|
|
|
|
user.two_factor_auth = True
|
|
|
|
|
user.tfa_token = rand_str()
|
|
|
|
|
|
2016-03-26 17:26:24 +00:00
|
|
|
|
# 后台控制用户是否被禁用
|
|
|
|
|
if data["is_forbidden_user"] is False:
|
|
|
|
|
user.is_forbidden = False
|
|
|
|
|
else:
|
|
|
|
|
user.is_forbidden = True
|
|
|
|
|
|
2015-08-07 12:25:58 +00:00
|
|
|
|
user.save()
|
|
|
|
|
return success_response(UserSerializer(user).data)
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-08-12 14:59:27 +00:00
|
|
|
|
|
2015-09-24 06:55:20 +00:00
|
|
|
|
@super_admin_required
|
2015-08-12 14:59:27 +00:00
|
|
|
|
def get(self, request):
|
|
|
|
|
"""
|
|
|
|
|
用户分页json api接口
|
|
|
|
|
---
|
|
|
|
|
response_serializer: UserSerializer
|
|
|
|
|
"""
|
|
|
|
|
user = User.objects.all().order_by("-create_time")
|
|
|
|
|
admin_type = request.GET.get("admin_type", None)
|
|
|
|
|
if admin_type:
|
|
|
|
|
try:
|
|
|
|
|
user = user.filter(admin_type__gte=int(admin_type))
|
|
|
|
|
except ValueError:
|
|
|
|
|
return error_response(u"参数错误")
|
|
|
|
|
keyword = request.GET.get("keyword", None)
|
|
|
|
|
if keyword:
|
|
|
|
|
user = user.filter(Q(username__contains=keyword) |
|
|
|
|
|
Q(real_name__contains=keyword) |
|
|
|
|
|
Q(email__contains=keyword))
|
|
|
|
|
return paginate(request, user, UserSerializer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserInfoAPIView(APIView):
|
|
|
|
|
@login_required
|
|
|
|
|
def get(self, request):
|
|
|
|
|
"""
|
|
|
|
|
返回这个用户的个人信息
|
|
|
|
|
---
|
|
|
|
|
response_serializer: UserSerializer
|
|
|
|
|
"""
|
|
|
|
|
return success_response(UserSerializer(request.user).data)
|
2015-09-17 02:24:01 +00:00
|
|
|
|
|
|
|
|
|
|
2015-11-10 10:46:51 +00:00
|
|
|
|
class UserProfileAPIView(APIView):
|
|
|
|
|
@login_required
|
|
|
|
|
def get(self, request):
|
|
|
|
|
"""
|
|
|
|
|
返回这个用户的个人信息
|
|
|
|
|
---
|
|
|
|
|
response_serializer: UserSerializer
|
|
|
|
|
"""
|
|
|
|
|
return success_response(UserSerializer(request.user).data)
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def put(self, request):
|
|
|
|
|
serializer = EditUserProfileSerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
|
|
|
|
user_profile = request.user.userprofile
|
|
|
|
|
if data["avatar"]:
|
|
|
|
|
user_profile.avatar = data["avatar"]
|
2015-11-11 01:15:43 +00:00
|
|
|
|
else:
|
|
|
|
|
user_profile.mood = data["mood"]
|
|
|
|
|
user_profile.hduoj_username = data["hduoj_username"]
|
|
|
|
|
user_profile.bestcoder_username = data["bestcoder_username"]
|
|
|
|
|
user_profile.codeforces_username = data["codeforces_username"]
|
|
|
|
|
user_profile.blog = data["blog"]
|
|
|
|
|
user_profile.school = data["school"]
|
2015-12-08 06:33:40 +00:00
|
|
|
|
user_profile.student_id = data["student_id"]
|
2015-11-11 01:15:43 +00:00
|
|
|
|
user_profile.phone_number = data["phone_number"]
|
2015-11-10 10:46:51 +00:00
|
|
|
|
user_profile.save()
|
|
|
|
|
return success_response(u"修改成功")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
|
|
|
|
|
2015-09-24 06:55:20 +00:00
|
|
|
|
class ApplyResetPasswordAPIView(APIView):
|
|
|
|
|
def post(self, request):
|
2015-10-09 08:17:07 +00:00
|
|
|
|
"""
|
|
|
|
|
提交请求重置密码
|
|
|
|
|
---
|
|
|
|
|
request_serializer: ApplyResetPasswordSerializer
|
|
|
|
|
"""
|
2015-09-24 06:55:20 +00:00
|
|
|
|
serializer = ApplyResetPasswordSerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
|
|
|
|
captcha = Captcha(request)
|
|
|
|
|
if not captcha.check(data["captcha"]):
|
|
|
|
|
return error_response(u"验证码错误")
|
|
|
|
|
try:
|
2015-11-29 03:21:39 +00:00
|
|
|
|
user = User.objects.get(email=data["email"])
|
2015-09-24 06:55:20 +00:00
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_response(u"用户不存在")
|
2015-12-12 07:41:57 +00:00
|
|
|
|
if user.reset_password_token_create_time and (
|
|
|
|
|
now() - user.reset_password_token_create_time).total_seconds() < 20 * 60:
|
2015-11-29 07:26:35 +00:00
|
|
|
|
return error_response(u"20分钟内只能找回一次密码")
|
2015-09-24 06:55:20 +00:00
|
|
|
|
user.reset_password_token = rand_str()
|
2015-10-16 12:49:01 +00:00
|
|
|
|
user.reset_password_token_create_time = now()
|
2015-09-24 06:55:20 +00:00
|
|
|
|
user.save()
|
2015-12-12 07:41:57 +00:00
|
|
|
|
email_template = codecs.open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r",
|
|
|
|
|
"utf-8").read()
|
|
|
|
|
|
|
|
|
|
email_template = email_template.replace("{{ username }}", user.username). \
|
|
|
|
|
replace("{{ website_name }}", settings.WEBSITE_INFO["website_name"]). \
|
2016-02-18 00:56:50 +00:00
|
|
|
|
replace("{{ link }}", request.scheme + "://"
|
|
|
|
|
+ request.META['HTTP_HOST'] + "/reset_password/t/" +
|
|
|
|
|
user.reset_password_token)
|
2015-12-12 07:41:57 +00:00
|
|
|
|
|
|
|
|
|
_send_email.delay(settings.WEBSITE_INFO["website_name"],
|
|
|
|
|
user.email,
|
|
|
|
|
user.username,
|
|
|
|
|
settings.WEBSITE_INFO["website_name"] + u" 登录信息找回邮件",
|
|
|
|
|
email_template)
|
2015-11-29 03:21:39 +00:00
|
|
|
|
return success_response(u"邮件发送成功,请前往您的邮箱查收")
|
2015-09-24 06:55:20 +00:00
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ResetPasswordAPIView(APIView):
|
2015-10-16 12:49:01 +00:00
|
|
|
|
def post(self, request):
|
|
|
|
|
serializer = ResetPasswordSerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
data = serializer.data
|
|
|
|
|
captcha = Captcha(request)
|
|
|
|
|
if not captcha.check(data["captcha"]):
|
|
|
|
|
return error_response(u"验证码错误")
|
|
|
|
|
try:
|
|
|
|
|
user = User.objects.get(reset_password_token=data["token"])
|
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_response(u"token 不存在")
|
|
|
|
|
if (now() - user.reset_password_token_create_time).total_seconds() > 30 * 60:
|
|
|
|
|
return error_response(u"token 已经过期,请在30分钟内重置密码")
|
|
|
|
|
user.reset_password_token = None
|
|
|
|
|
user.set_password(data["password"])
|
|
|
|
|
user.save()
|
|
|
|
|
return success_response(u"密码重置成功")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
2015-09-24 06:55:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def user_index_page(request, username):
|
2015-10-25 07:30:11 +00:00
|
|
|
|
try:
|
|
|
|
|
user = User.objects.get(username=username)
|
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_page(request, u"用户不存在")
|
|
|
|
|
|
|
|
|
|
blog_link = ""
|
|
|
|
|
|
|
|
|
|
if user.userprofile.blog:
|
|
|
|
|
blog_link = user.userprofile.blog.replace("http://", "").replace("https://", "")
|
|
|
|
|
|
|
|
|
|
return render(request, "oj/account/user_index.html", {"user": user, "blog_link": blog_link})
|
2015-10-16 12:49:01 +00:00
|
|
|
|
|
|
|
|
|
|
2015-10-20 12:09:23 +00:00
|
|
|
|
class SSOAPIView(APIView):
|
|
|
|
|
def post(self, request):
|
|
|
|
|
serializer = SSOSerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
2016-02-18 00:56:50 +00:00
|
|
|
|
try:
|
|
|
|
|
User.objects.get(openapi_appkey=serializer.data["appkey"])
|
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_response(u"appkey无效")
|
2015-10-20 12:09:23 +00:00
|
|
|
|
try:
|
|
|
|
|
user = User.objects.get(auth_token=serializer.data["token"])
|
2015-12-11 06:24:05 +00:00
|
|
|
|
user.auth_token = None
|
|
|
|
|
user.save()
|
2016-02-17 01:45:35 +00:00
|
|
|
|
return success_response({"username": user.username,
|
2016-02-18 00:56:50 +00:00
|
|
|
|
"id": user.id,
|
2016-02-17 01:45:35 +00:00
|
|
|
|
"admin_type": user.admin_type,
|
|
|
|
|
"avatar": user.userprofile.avatar})
|
2015-10-20 12:09:23 +00:00
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_response(u"用户不存在")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def get(self, request):
|
|
|
|
|
callback = request.GET.get("callback", None)
|
2016-02-18 00:56:50 +00:00
|
|
|
|
if not callback:
|
2015-10-20 12:09:23 +00:00
|
|
|
|
return error_page(request, u"参数错误")
|
|
|
|
|
token = rand_str()
|
|
|
|
|
request.user.auth_token = token
|
|
|
|
|
request.user.save()
|
2015-12-12 07:41:57 +00:00
|
|
|
|
return render(request, "oj/account/sso.html",
|
|
|
|
|
{"redirect_url": callback + "?token=" + token, "callback": callback})
|
2015-11-29 03:21:39 +00:00
|
|
|
|
|
2015-11-29 07:26:35 +00:00
|
|
|
|
|
|
|
|
|
def reset_password_page(request, token):
|
|
|
|
|
try:
|
|
|
|
|
user = User.objects.get(reset_password_token=token)
|
|
|
|
|
except User.DoesNotExist:
|
|
|
|
|
return error_page(request, u"链接已失效")
|
|
|
|
|
if (now() - user.reset_password_token_create_time).total_seconds() > 30 * 60:
|
|
|
|
|
return error_page(request, u"链接已过期")
|
|
|
|
|
return render(request, "oj/account/reset_password.html", {"user": user})
|
2015-12-11 14:43:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TwoFactorAuthAPIView(APIView):
|
|
|
|
|
@login_required
|
|
|
|
|
def get(self, request):
|
|
|
|
|
"""
|
|
|
|
|
获取绑定二维码
|
|
|
|
|
"""
|
|
|
|
|
user = request.user
|
|
|
|
|
if user.two_factor_auth:
|
|
|
|
|
return error_response(u"已经开启两步验证了")
|
|
|
|
|
token = rand_str()
|
|
|
|
|
user.tfa_token = token
|
|
|
|
|
user.save()
|
|
|
|
|
|
2015-12-12 13:40:04 +00:00
|
|
|
|
image = qrcode.make(OtpAuth(token).to_uri("totp", settings.WEBSITE_INFO["url"], "OnlineJudgeAdmin"))
|
2015-12-11 14:43:23 +00:00
|
|
|
|
buf = StringIO.StringIO()
|
|
|
|
|
image.save(buf, 'gif')
|
|
|
|
|
|
|
|
|
|
return HttpResponse(buf.getvalue(), 'image/gif')
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def post(self, request):
|
|
|
|
|
"""
|
|
|
|
|
开启两步验证
|
|
|
|
|
"""
|
2015-12-11 15:00:31 +00:00
|
|
|
|
serializer = TwoFactorAuthCodeSerializer(data=request.data)
|
2015-12-11 14:43:23 +00:00
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
code = serializer.data["code"]
|
|
|
|
|
user = request.user
|
|
|
|
|
if OtpAuth(user.tfa_token).valid_totp(code):
|
|
|
|
|
user.two_factor_auth = True
|
|
|
|
|
user.save()
|
|
|
|
|
return success_response(u"开启两步验证成功")
|
|
|
|
|
else:
|
|
|
|
|
return error_response(u"验证码错误")
|
|
|
|
|
else:
|
2015-12-11 15:00:31 +00:00
|
|
|
|
return serializer_invalid_response(serializer)
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def put(self, request):
|
|
|
|
|
serializer = TwoFactorAuthCodeSerializer(data=request.data)
|
|
|
|
|
if serializer.is_valid():
|
|
|
|
|
user = request.user
|
|
|
|
|
code = serializer.data["code"]
|
|
|
|
|
if OtpAuth(user.tfa_token).valid_totp(code):
|
|
|
|
|
user.two_factor_auth = False
|
|
|
|
|
user.save()
|
|
|
|
|
else:
|
|
|
|
|
return error_response(u"验证码错误")
|
|
|
|
|
else:
|
|
|
|
|
return serializer_invalid_response(serializer)
|