From 875e3b16717161b3a024a786dbd5f9aaf8fae73d Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 6 Aug 2015 09:43:14 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=B0=86=E6=B3=A8=E5=86=8C=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E7=94=A8=E6=88=B7=E5=90=8D=E5=92=8C=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E9=AA=8C=E8=AF=81=E6=94=B9=E4=B8=BA=E4=BA=86=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E6=A1=86=E5=A4=B1=E5=8E=BB=E7=84=A6=E7=82=B9=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E5=80=99=E6=89=8D=E9=AA=8C=E8=AF=81=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=E5=8F=91=E9=80=81=E5=A4=A7=E9=87=8F=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E3=80=82=20=E5=A2=9E=E5=8A=A0=E6=B3=A8=E5=86=8C=E7=9A=84?= =?UTF-8?q?=E6=97=B6=E5=80=99=E5=90=91=E5=90=8E=E7=AB=AF=E5=8F=91=E9=80=81?= =?UTF-8?q?=E9=82=AE=E7=AE=B1=E5=AD=97=E6=AE=B5=E3=80=82=20=E6=95=B4?= =?UTF-8?q?=E7=90=86=20js=20=E4=BB=A3=E7=A0=81=E9=A3=8E=E6=A0=BC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/js/app/oj/account/change_password.js | 24 +++++------ static/src/js/app/oj/account/login.js | 12 +++--- static/src/js/app/oj/account/register.js | 42 +++++++++---------- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/static/src/js/app/oj/account/change_password.js b/static/src/js/app/oj/account/change_password.js index e3e907fa..c76dd9d7 100644 --- a/static/src/js/app/oj/account/change_password.js +++ b/static/src/js/app/oj/account/change_password.js @@ -1,4 +1,4 @@ -require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrfHeader){ +require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csrfHeader) { $("#change_password-form").formValidation({ framework: "bootstrap", fields: { @@ -13,22 +13,22 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf validators: { notEmpty: { message: "请填写旧密码" - } + } } }, new_password: { validators: { notEmpty: { message: "请填写新密码" - }, + }, stringLength: { min: 6, max: 30, message: '密码长度必须在6到30位之间' } }, - onSuccess: function(e, data) { - data.fv.revalidateField('confirm_password'); + onSuccess: function (e, data) { + data.fv.revalidateField('confirm_password'); } }, confirm_password: { @@ -40,27 +40,27 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf original: $("#new_password"), message: "两次输入的密码必须一致" } - }, + } } } } - ).on('success.form.fv', function(e) { + ).on('success.form.fv', function (e) { e.preventDefault(); var username = $("#username").val(); - var new_password = $("#new_password ").val(); + var new_password = $("#new_password ").val(); var password = $("#password").val(); $.ajax({ beforeSend: csrfHeader, url: "/api/change_password/", - data: {username: username, new_password: new_password , old_password : password}, + data: {username: username, new_password: new_password, old_password: password}, dataType: "json", method: "post", success: function (data) { - if(!data.code){ - window.location.href="/login/"; + if (!data.code) { + window.location.href = "/login/"; } - else{ + else { bs_alert(data.data); } } diff --git a/static/src/js/app/oj/account/login.js b/static/src/js/app/oj/account/login.js index da4416db..2ecebf73 100644 --- a/static/src/js/app/oj/account/login.js +++ b/static/src/js/app/oj/account/login.js @@ -1,6 +1,6 @@ -require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrfHeader){ +require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csrfHeader) { $("#login-form") - .formValidation({ + .formValidation({ framework: "bootstrap", fields: { username: { @@ -19,7 +19,7 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf } } } - ).on('success.form.fv', function(e) { + ).on('success.form.fv', function (e) { e.preventDefault(); var username = $("#username").val(); var password = $("#password").val(); @@ -30,10 +30,10 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf dataType: "json", method: "post", success: function (data) { - if(!data.code){ - window.location.href="/"; + if (!data.code) { + window.location.href = "/"; } - else{ + else { bs_alert(data.data); } } diff --git a/static/src/js/app/oj/account/register.js b/static/src/js/app/oj/account/register.js index a7a3ea12..52c3d362 100644 --- a/static/src/js/app/oj/account/register.js +++ b/static/src/js/app/oj/account/register.js @@ -1,14 +1,10 @@ -require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrfHeader){ +require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csrfHeader) { $("#register-form") - .formValidation({ + .formValidation({ framework: "bootstrap", - icon: { - valid: 'glyphicon glyphicon-ok', - invalid: 'glyphicon glyphicon-remove', - validating: 'glyphicon glyphicon-refresh' - }, fields: { username: { + trigger: 'blur', validators: { notEmpty: { message: "请填写用户名" @@ -29,23 +25,23 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf validators: { notEmpty: { message: "请填写密码" - }, - stringLength: { - min: 6, - max: 30, - message: '密码长度必须在6到30位之间' - } + }, + stringLength: { + min: 6, + max: 30, + message: '密码长度必须在6到30位之间' + } }, - onSuccess: function(e, data) { - data.fv.revalidateField('confirm_password'); + onSuccess: function (e, data) { + data.fv.revalidateField('confirm_password'); } }, real_name: { validators: { notEmpty: { message: "请填写真实姓名" - } - }, + } + } }, confirm_password: { validators: { @@ -59,6 +55,7 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf } }, email: { + trigger: 'blur', validators: { notEmpty: { message: "请填写电子邮箱邮箱地址" @@ -75,22 +72,23 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf } } } - ).on('success.form.fv', function(e) { + ).on('success.form.fv', function (e) { e.preventDefault(); var username = $("#username").val(); var real_name = $("#real_name").val(); var password = $("#password").val(); + var email = $("#email").val(); $.ajax({ beforeSend: csrfHeader, url: "/api/register/", - data: {username: username, real_name: real_name, password: password}, + data: {username: username, real_name: real_name, password: password, email: email}, dataType: "json", method: "post", success: function (data) { - if(!data.code){ - window.location.href="/login/"; + if (!data.code) { + window.location.href = "/login/"; } - else{ + else { bs_alert(data.data); } } From 62f07e713f8a4137b24a6791cf1a18dbe1c06f82 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 6 Aug 2015 12:25:16 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20@admin=5Frequired=20?= =?UTF-8?q?=E4=BF=AE=E9=A5=B0=E7=AC=A6=E4=BB=A3=E7=A0=81=E5=92=8C=E5=AF=B9?= =?UTF-8?q?=E5=BA=94=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/decorators.py | 12 +++++- account/models.py | 3 +- account/test_urls.py | 16 +++++--- account/tests.py | 92 ++++++++++++++++++++++++++++++++++++++----- 4 files changed, 106 insertions(+), 17 deletions(-) diff --git a/account/decorators.py b/account/decorators.py index 6b108960..01cdd68f 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -20,5 +20,13 @@ def login_required(func): return check -def admin_required(): - pass +def admin_required(func): + def check(*args, **kwargs): + request = args[-1] + if request.user.is_authenticated() and request.user.admin_type: + return func(*args, **kwargs) + if request.is_ajax(): + return error_response(u"需要管理员权限") + else: + return render(request, "utils/error.html", {"error": "需要管理员权限"}) + return check diff --git a/account/models.py b/account/models.py index 1f02eef9..7c5afb96 100644 --- a/account/models.py +++ b/account/models.py @@ -21,7 +21,8 @@ class User(AbstractBaseUser): real_name = models.CharField(max_length=30, blank=True, null=True) # 用户邮箱 email = models.EmailField(max_length=254, blank=True, null=True) - admin_group = models.ForeignKey(AdminGroup, null=True, on_delete=models.SET_NULL) + # 0代表不是管理员 1是普通管理员 2是超级管理员 + admin_type = models.IntegerField(default=0) USERNAME_FIELD = 'username' REQUIRED_FIELDS = [] diff --git a/account/test_urls.py b/account/test_urls.py index 40667215..9757d901 100644 --- a/account/test_urls.py +++ b/account/test_urls.py @@ -1,12 +1,18 @@ # coding=utf-8 from django.conf.urls import include, url -from .tests import LoginRequiredCBVTestWithArgs, LoginRequiredCBVTestWithoutArgs +from .tests import (LoginRequiredCBVTestWithArgs, LoginRequiredCBVTestWithoutArgs, + AdminRequiredCBVTestWithArgs, AdminRequiredCBVTestWithoutArgs) urlpatterns = [ - url(r'^test/fbv/1/$', "account.tests.login_required_FBV_test_without_args"), - url(r'^test/fbv/(?P\d+)/$', "account.tests.login_required_FBC_test_with_args"), - url(r'^test/cbv/1/$', LoginRequiredCBVTestWithoutArgs.as_view()), - url(r'^test/cbv/(?P\d+)/$', LoginRequiredCBVTestWithArgs.as_view()), + url(r'^login_required_test/fbv/1/$', "account.tests.login_required_FBV_test_without_args"), + url(r'^login_required_test/fbv/(?P\d+)/$', "account.tests.login_required_FBC_test_with_args"), + url(r'^login_required_test/cbv/1/$', LoginRequiredCBVTestWithoutArgs.as_view()), + url(r'^login_required_test/cbv/(?P\d+)/$', LoginRequiredCBVTestWithArgs.as_view()), + + url(r'^admin_required_test/fbv/1/$', "account.tests.admin_required_FBV_test_without_args"), + url(r'^admin_required_test/fbv/(?P\d+)/$', "account.tests.admin_required_FBC_test_with_args"), + url(r'^admin_required_test/cbv/1/$', AdminRequiredCBVTestWithoutArgs.as_view()), + url(r'^admin_required_test/cbv/(?P\d+)/$', AdminRequiredCBVTestWithArgs.as_view()), ] diff --git a/account/tests.py b/account/tests.py index 89410da3..3529bb6e 100644 --- a/account/tests.py +++ b/account/tests.py @@ -10,7 +10,7 @@ from rest_framework.views import APIView from rest_framework.response import Response from .models import User -from .decorators import login_required +from .decorators import login_required, admin_required class UserLoginTest(TestCase): @@ -159,6 +159,7 @@ class LoginRequiredCBVTestWithoutArgs(APIView): def get(self, request): return HttpResponse("class based view login required test1") + class LoginRequiredCBVTestWithArgs(APIView): @login_required def get(self, request, problem_id): @@ -176,40 +177,113 @@ class LoginRequiredDecoratorTest(TestCase): def test_fbv_without_args(self): # 没登陆 - response = self.client.get("/test/fbv/1/") + response = self.client.get("/login_required_test/fbv/1/") self.assertTemplateUsed(response, "utils/error.html") # 登陆后 self.client.login(username="test", password="test") - response = self.client.get("/test/fbv/1/") + response = self.client.get("/login_required_test/fbv/1/") self.assertEqual(response.content, "function based view test1") def test_fbv_with_args(self): # 没登陆 - response = self.client.get("/test/fbv/1024/") + response = self.client.get("/login_required_test/fbv/1024/") self.assertTemplateUsed(response, "utils/error.html") # 登陆后 self.client.login(username="test", password="test") - response = self.client.get("/test/fbv/1024/") + response = self.client.get("/login_required_test/fbv/1024/") self.assertEqual(response.content, "1024") def test_cbv_without_args(self): # 没登陆 - response = self.client.get("/test/cbv/1/") + response = self.client.get("/login_required_test/cbv/1/") self.assertTemplateUsed(response, "utils/error.html") # 登陆后 self.client.login(username="test", password="test") - response = self.client.get("/test/cbv/1/") + response = self.client.get("/login_required_test/cbv/1/") self.assertEqual(response.content, "class based view login required test1") def test_cbv_with_args(self): # 没登陆 - response = self.client.get("/test/cbv/1024/", HTTP_X_REQUESTED_WITH='XMLHttpRequest') + response = self.client.get("/login_required_test/cbv/1024/", HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(json.loads(response.content), {"code": 1, "data": u"请先登录"}) # 登陆后 self.client.login(username="test", password="test") - response = self.client.get("/test/cbv/1024/") + response = self.client.get("/login_required_test/cbv/1024/") + self.assertEqual(response.content, "1024") + + +@admin_required +def admin_required_FBV_test_without_args(request): + return HttpResponse("function based view test1") + + +@admin_required +def admin_required_FBC_test_with_args(request, problem_id): + return HttpResponse(problem_id) + + +class AdminRequiredCBVTestWithoutArgs(APIView): + @admin_required + def get(self, request): + return HttpResponse("class based view login required test1") + + +class AdminRequiredCBVTestWithArgs(APIView): + @admin_required + def get(self, request, problem_id): + return HttpResponse(problem_id) + + +class AdminRequiredDecoratorTest(TestCase): + urls = 'account.test_urls' + + def setUp(self): + self.client = Client() + user = User.objects.create(username="test") + user.admin_type = 1 + user.set_password("test") + user.save() + + def test_fbv_without_args(self): + # 没登陆 + response = self.client.get("/admin_required_test/fbv/1/") + self.assertTemplateUsed(response, "utils/error.html") + + # 登陆后 + self.client.login(username="test", password="test") + response = self.client.get("/admin_required_test/fbv/1/") + self.assertEqual(response.content, "function based view test1") + + def test_fbv_with_args(self): + # 没登陆 + response = self.client.get("/admin_required_test/fbv/1024/") + self.assertTemplateUsed(response, "utils/error.html") + + # 登陆后 + self.client.login(username="test", password="test") + response = self.client.get("/admin_required_test/fbv/1024/") + self.assertEqual(response.content, "1024") + + def test_cbv_without_args(self): + # 没登陆 + response = self.client.get("/admin_required_test/cbv/1/") + self.assertTemplateUsed(response, "utils/error.html") + + # 登陆后 + self.client.login(username="test", password="test") + response = self.client.get("/admin_required_test/cbv/1/") + self.assertEqual(response.content, "class based view login required test1") + + def test_cbv_with_args(self): + # 没登陆 + response = self.client.get("/admin_required_test/cbv/1024/", HTTP_X_REQUESTED_WITH='XMLHttpRequest') + self.assertEqual(json.loads(response.content), {"code": 1, "data": u"需要管理员权限"}) + + # 登陆后 + self.client.login(username="test", password="test") + response = self.client.get("/admin_required_test/cbv/1024/") self.assertEqual(response.content, "1024")