mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2025-11-04 14:49:58 +08:00
增加后台编辑两步验证和openapi appkey的功能。
同时修复: - 去除部分表单的 id 和 name,阻止chrome的自动填充 - 不再需要的model - 部分代码格式问题
This commit is contained in:
parent
c00d631ed0
commit
030a9b52f1
23
account/migrations/0018_auto_20160217_0920.py
Normal file
23
account/migrations/0018_auto_20160217_0920.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.1 on 2016-02-17 01:20
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('account', '0017_auto_20151212_2139'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='AdminGroup',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='openapi_appkey',
|
||||||
|
field=models.CharField(blank=True, max_length=35, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -5,10 +5,6 @@ from django.contrib.auth.models import AbstractBaseUser
|
|||||||
from jsonfield import JSONField
|
from jsonfield import JSONField
|
||||||
|
|
||||||
|
|
||||||
class AdminGroup(models.Model):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class UserManager(models.Manager):
|
class UserManager(models.Manager):
|
||||||
use_in_migrations = True
|
use_in_migrations = True
|
||||||
|
|
||||||
@ -38,11 +34,13 @@ class User(AbstractBaseUser):
|
|||||||
reset_password_token = models.CharField(max_length=40, blank=True, null=True)
|
reset_password_token = models.CharField(max_length=40, blank=True, null=True)
|
||||||
# token 生成时间
|
# token 生成时间
|
||||||
reset_password_token_create_time = models.DateTimeField(blank=True, null=True)
|
reset_password_token_create_time = models.DateTimeField(blank=True, null=True)
|
||||||
# 论坛授权token
|
# SSO授权token
|
||||||
auth_token = models.CharField(max_length=40, blank=True, null=True)
|
auth_token = models.CharField(max_length=40, blank=True, null=True)
|
||||||
# 是否开启两步验证
|
# 是否开启两步验证
|
||||||
two_factor_auth = models.BooleanField(default=False)
|
two_factor_auth = models.BooleanField(default=False)
|
||||||
tfa_token = models.CharField(max_length=40, blank=True, null=True)
|
tfa_token = models.CharField(max_length=40, blank=True, null=True)
|
||||||
|
# open api key
|
||||||
|
openapi_appkey = models.CharField(max_length=35, blank=True, null=True)
|
||||||
|
|
||||||
USERNAME_FIELD = 'username'
|
USERNAME_FIELD = 'username'
|
||||||
REQUIRED_FIELDS = []
|
REQUIRED_FIELDS = []
|
||||||
|
|||||||
@ -38,7 +38,8 @@ class UserSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ["id", "username", "real_name", "email", "admin_type", "create_time", "last_login"]
|
fields = ["id", "username", "real_name", "email", "admin_type",
|
||||||
|
"create_time", "last_login", "two_factor_auth", "openapi_appkey"]
|
||||||
|
|
||||||
|
|
||||||
class EditUserSerializer(serializers.Serializer):
|
class EditUserSerializer(serializers.Serializer):
|
||||||
@ -48,6 +49,8 @@ class EditUserSerializer(serializers.Serializer):
|
|||||||
password = serializers.CharField(max_length=30, min_length=6, required=False, default=None)
|
password = serializers.CharField(max_length=30, min_length=6, required=False, default=None)
|
||||||
email = serializers.EmailField(max_length=254)
|
email = serializers.EmailField(max_length=254)
|
||||||
admin_type = serializers.IntegerField(default=0)
|
admin_type = serializers.IntegerField(default=0)
|
||||||
|
openapi = serializers.BooleanField()
|
||||||
|
tfa_auth = serializers.BooleanField()
|
||||||
|
|
||||||
|
|
||||||
class ApplyResetPasswordSerializer(serializers.Serializer):
|
class ApplyResetPasswordSerializer(serializers.Serializer):
|
||||||
|
|||||||
@ -210,8 +210,24 @@ class UserAdminAPIView(APIView):
|
|||||||
user.real_name = data["real_name"]
|
user.real_name = data["real_name"]
|
||||||
user.email = data["email"]
|
user.email = data["email"]
|
||||||
user.admin_type = data["admin_type"]
|
user.admin_type = data["admin_type"]
|
||||||
|
|
||||||
if data["password"]:
|
if data["password"]:
|
||||||
user.set_password(data["password"])
|
user.set_password(data["password"])
|
||||||
|
|
||||||
|
# 后台控制用户是否可以使用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()
|
||||||
|
|
||||||
user.save()
|
user.save()
|
||||||
return success_response(UserSerializer(user).data)
|
return success_response(UserSerializer(user).data)
|
||||||
else:
|
else:
|
||||||
@ -368,8 +384,9 @@ class SSOAPIView(APIView):
|
|||||||
user = User.objects.get(auth_token=serializer.data["token"])
|
user = User.objects.get(auth_token=serializer.data["token"])
|
||||||
user.auth_token = None
|
user.auth_token = None
|
||||||
user.save()
|
user.save()
|
||||||
return success_response(
|
return success_response({"username": user.username,
|
||||||
{"username": user.username, "admin_type": user.admin_type, "avatar": user.userprofile.avatar})
|
"admin_type": user.admin_type,
|
||||||
|
"avatar": user.userprofile.avatar})
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
return error_response(u"用户不存在")
|
return error_response(u"用户不存在")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -20,6 +20,8 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "pager", "validator"],
|
|||||||
email: "",
|
email: "",
|
||||||
adminType: 0,
|
adminType: 0,
|
||||||
userId: -1,
|
userId: -1,
|
||||||
|
openAPI: false,
|
||||||
|
tfa_auth: false,
|
||||||
|
|
||||||
pager: {
|
pager: {
|
||||||
getPage: function (page) {
|
getPage: function (page) {
|
||||||
@ -32,6 +34,8 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "pager", "validator"],
|
|||||||
vm.adminType = user.admin_type;
|
vm.adminType = user.admin_type;
|
||||||
vm.email = user.email;
|
vm.email = user.email;
|
||||||
vm.userId = user.id;
|
vm.userId = user.id;
|
||||||
|
vm.tfa_auth = user.two_factor_auth;
|
||||||
|
vm.openAPI = user.openapi_appkey ? true: false;
|
||||||
|
|
||||||
vm.isEditing = true;
|
vm.isEditing = true;
|
||||||
},
|
},
|
||||||
@ -77,7 +81,9 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "pager", "validator"],
|
|||||||
real_name: vm.realName,
|
real_name: vm.realName,
|
||||||
email: vm.email,
|
email: vm.email,
|
||||||
id: vm.userId,
|
id: vm.userId,
|
||||||
admin_type: vm.adminType
|
admin_type: vm.adminType,
|
||||||
|
openapi: vm.openAPI,
|
||||||
|
tfa_auth: vm.tfa_auth
|
||||||
};
|
};
|
||||||
if ($("#password").val() !== "")
|
if ($("#password").val() !== "")
|
||||||
data.password = $("#password").val();
|
data.password = $("#password").val();
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
<input name="id" type="number" class="form-control" readonly ms-duplex="userId">
|
<input name="id" type="number" class="form-control" readonly ms-duplex="userId">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-4"><label>用户名</label>
|
<div class="form-group col-md-4"><label>用户名</label>
|
||||||
<input name="username" type="text" class="form-control" ms-duplex="username"
|
<input type="text" class="form-control" ms-duplex="username"
|
||||||
data-minlength="3" data-minlength-error="用户名不得少于3位" required>
|
data-minlength="3" data-minlength-error="用户名不得少于3位" required>
|
||||||
<div class="help-block with-errors"></div>
|
<div class="help-block with-errors"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -60,12 +60,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-4"><label>新密码(留空则保留原密码)</label>
|
<div class="form-group col-md-4"><label>新密码(留空则保留原密码)</label>
|
||||||
<input name="password" type="password" class="form-control" id="password" autocomplete="off"
|
<input type="password" class="form-control" autocomplete="off"
|
||||||
placeholder="此项留空则保留原密码" data-minlength="6" data-minlength-error="密码不得少于6位">
|
placeholder="此项留空则保留原密码" data-minlength="6" data-minlength-error="密码不得少于6位">
|
||||||
<div class="help-block with-errors"></div>
|
<div class="help-block with-errors"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group col-md-4"><label>电子邮箱</label>
|
<div class="form-group col-md-4"><label>电子邮箱</label>
|
||||||
<input name="email" type="email" class="form-control" ms-duplex="email"
|
<input type="email" class="form-control" ms-duplex="email"
|
||||||
data-error="请填写邮箱地址(并保证是正确的邮箱格式)" required>
|
data-error="请填写邮箱地址(并保证是正确的邮箱格式)" required>
|
||||||
<div class="help-block with-errors"></div>
|
<div class="help-block with-errors"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -75,6 +75,16 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-3">
|
||||||
|
<label>是否开放API功能</label>
|
||||||
|
<input name="openapi" type="checkbox" class="form-control" ms-duplex-checked="openAPI">
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-3">
|
||||||
|
<label>两步验证</label>
|
||||||
|
<input name="tfa_auth" type="checkbox" class="form-control" ms-duplex-checked="tfa_auth">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="submit" class="btn btn-success">保存修改</button>
|
<button type="submit" class="btn btn-success">保存修改</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user