修复公告列表中用户权限判断错误的情况,抽取代码为 decorator。

This commit is contained in:
virusdefender 2015-09-21 12:32:50 +08:00
parent 725d950e27
commit cb0e7cf938
4 changed files with 49 additions and 19 deletions

View File

@ -0,0 +1,43 @@
# coding=utf-8
from functools import wraps
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from utils.shortcuts import error_response, error_page
from account.models import SUPER_ADMIN
from .models import Announcement
def check_user_announcement_permission(func):
@wraps(func)
def _check_user_announcement_permission(*args, **kwargs):
"""
这个函数检测当前用户能否查看这个公告
"""
# CBV 的情况第一个参数是self第二个参数是request
if len(args) == 2:
request = args[-1]
else:
request = args[0]
if "announcement_id" not in kwargs:
return error_page(request, u"参数错误")
announcement_id = kwargs["announcement_id"]
try:
announcement = Announcement.objects.get(id=announcement_id, visible=True)
except Announcement.DoesNotExist:
return error_page(request, u"公告不存在")
# 如果公告是只有部分小组可见的
if not announcement.is_global:
# 用户必须是登录状态的
if not request.user.is_authenticated():
return HttpResponseRedirect("/login/")
if not announcement.groups.filter(id__in=request.user.group_set.all()).exists():
return error_page(request, u"公告不存在")
return func(*args, **kwargs)
return _check_user_announcement_permission

View File

@ -18,7 +18,7 @@ class Announcement(models.Model):
last_update_time = models.DateTimeField(auto_now=True)
# 是否可见 false的话相当于删除
visible = models.BooleanField(default=True)
# 公告可见范围 0是全局可见 1是部分小组可见,需要在下面的字段中存储可见的小组
# 公告可见范围 True 是全局可见 False 是部分小组可见,需要在下面的字段中存储可见的小组
is_global = models.BooleanField()
groups = models.ManyToManyField(Group)

View File

@ -10,27 +10,13 @@ from group.models import Group
from .models import Announcement
from .serializers import (CreateAnnouncementSerializer, AnnouncementSerializer,
EditAnnouncementSerializer)
from .decorators import check_user_announcement_permission
@check_user_announcement_permission
def announcement_page(request, announcement_id):
try:
announcement = Announcement.objects.get(id=announcement_id, visible=True)
except Announcement.DoesNotExist:
return error_page(request, u"公告不存在")
# 公开的公告
if announcement.is_global == 0:
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
else:
if not request.user.is_authenticated():
return error_page(request, u"公告不存在")
# 判断是不是在组里面
if request.user.admin_type == SUPER_ADMIN or request.user == announcement.created_by:
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
else:
if request.user.groups.filter(id__in=[item.id for item in announcement.groups.all()]).exists():
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
else:
return error_page(request, u"公告不存在")
announcement = Announcement.objects.get(id=announcement_id, visible=True)
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
class AnnouncementAdminAPIView(APIView):

View File

@ -3,6 +3,7 @@ from django import template
from announcement.models import Announcement
def public_announcement_list():
return Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time")