瀏覽代碼

Merge branch 'Test' into 'Release'

Test



See merge request !1334

huangyong 4 年之前
父節點
當前提交
f627b35bcf

+ 6 - 9
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/dao/PaperDao.java

@@ -19,23 +19,20 @@ import java.util.List;
 @Transactional
 public interface PaperDao extends PagingAndSortingRepository<Paper, Long>, JpaSpecificationExecutor<Paper>, UpdateAdapter<Paper, Long> {
 
-    Paper findById(long paperId);
+    @Query("select p from Paper p where p.isDeleted = false and p.id = :paperId")
+    Paper findById(@Param("paperId") long paperId);
 
-    @Query("select p from Paper p,Paper2Case t2c where t2c.caseId=:caseId and t2c.paperId=p.id and p.isDeleted=0 and p.isPublic=1")
+    @Query("select p from Paper p,Paper2Case t2c where t2c.caseId=:caseId and t2c.paperId=p.id and p.isDeleted=false and p.isPublic=true ")
     Page<Paper> findByCaseId(@Param("caseId") Long caseId, Pageable pageable);
 
-    @Query("select p from Paper p,Paper2Case t2c where t2c.caseId=:caseId and t2c.paperId=p.id and p.isDeleted=0 and p.isPublic=0 " +
+    @Query("select p from Paper p,Paper2Case t2c where t2c.caseId=:caseId and t2c.paperId=p.id and p.isDeleted=false and p.isPublic=false " +
             "and p.ownerId=:ownerId")
     Page<Paper> findByCaseIdPrivate(@Param("caseId") Long caseId,
                                     @Param("ownerId") Long ownerId, Pageable pageable);
 
-    @Query("select p from Paper p where p.ownerId = :ownerId and p.isDeleted = 0 and p.isPublic = 0")
+    @Query("select p from Paper p where p.ownerId = :ownerId and p.isDeleted = false and p.isPublic = false")
     List<Paper> findByIsDeletedAndPrivacy(Long ownerId);
 
-    @Query("select p from Paper p where p.isDeleted = 0 and p.isPublic =1")
+    @Query("select p from Paper p where p.isDeleted = false and p.isPublic = true")
     List<Paper> findByIsDeletedAndPublicity();
-
-//    @Query("select p from Paper p where p.ownerId=:ownerId")
-//    Page<Paper> findByOwnerId(@Param("ownerId")long ownerId, String keyword, Pageable pageable);
-
 }

+ 3 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/models/Paper.java

@@ -2,6 +2,7 @@ package cn.iselab.mooctest.site.models;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.hibernate.annotations.UpdateTimestamp;
 
 import javax.persistence.*;
 import java.sql.Timestamp;
@@ -31,7 +32,8 @@ public class Paper {
     @Column(name = "difficult")
     private Byte difficult;
 
-    @Column(name = "update_time", columnDefinition = "TIMESTAMP default CURRENT_TIMESTAMP")
+    @UpdateTimestamp
+    @Column(name = "update_time")
     private Timestamp updateTime;
 
     @Column(name = "is_public")

+ 4 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ExamController.java

@@ -7,6 +7,7 @@ import cn.iselab.mooctest.site.models.instancePermission.ExamPermission;
 import cn.iselab.mooctest.site.web.data.*;
 import cn.iselab.mooctest.site.web.data.response.ResponseVO;
 import cn.iselab.mooctest.site.web.exception.HttpBadRequestException;
+import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
 import cn.iselab.mooctest.site.web.exception.ServerException;
 import cn.iselab.mooctest.site.web.logic.*;
 import com.google.gson.Gson;
@@ -145,7 +146,6 @@ public class ExamController extends BaseSearchController {
         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         LOG.info(String.format("[用户访问试卷页面] 用户名:%s, 用户id: %d, 考试名:%s, 考试id: %d,访问时间:%s",
                 currentUser.getName(),currentUser.getId(),examVO.getName(),examVO.getId(),df.format(date)));
-
         examVO = visitControlLogic.setVOVisitControlAttr(examVO,EntityTypeEnum.EXAM,examId);
 
         return examVO;
@@ -169,6 +169,9 @@ public class ExamController extends BaseSearchController {
             throw new UnauthenticatedException("forbidden");
         }
         PaperVO paperVO = paperLogic.getPaperById(paperId, null);
+        if (paperVO == null) {
+            throw new HttpNotFoundException("试卷不存在");
+        }
         if ( paperVO.getCaseBlocks().size() < 1) {
             throw new HttpBadRequestException("不能绑定空试卷");
         }

+ 52 - 3
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/PaperController.java

@@ -1,7 +1,12 @@
 package cn.iselab.mooctest.site.web.ctrl;
 
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
+import cn.iselab.mooctest.site.models.Exam;
+import cn.iselab.mooctest.site.web.data.ExamVO;
 import cn.iselab.mooctest.site.web.data.SearchConditionVO;
+import cn.iselab.mooctest.site.web.exception.HttpNotFoundException;
+import cn.iselab.mooctest.site.web.logic.ExamLogic;
+import cn.iselab.mooctest.site.web.logic.RoleLogic;
 import cn.iselab.mooctest.site.web.response.ErrorResult;
 import cn.iselab.mooctest.site.web.response.StatusCode;
 import cn.iselab.mooctest.site.web.response.SuccessResult;
@@ -37,16 +42,60 @@ public class PaperController extends BaseSearchController{
     PaperLogic paperLogic;
     @Autowired
     DetailStatisticsLogic detailStatisticsLogic;
+    @Autowired
+    RoleLogic roleLogic;
+    @Autowired
+    ExamLogic examLogic;
 
     @RequiresPermissions("paper:view")
     @RequestMapping(value = "api/paper/{paperId}", method = RequestMethod.GET)
     public PaperVO getPaperById(@PathVariable Long paperId, @RequestParam(value = "examId", required = false) Long examId) {
+        // 试卷应该,只有管理员或者作者可以进入。
         Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute("userId");
-        String permissionStr = userId.toString() + ":paper:view:" + paperId.toString();
-        if (!SecurityUtils.getSubject().isPermitted(new PaperPermission(permissionStr))) {
+        String permissionStr = userId.toString() + ":paper:*:" + paperId.toString();
+        boolean isPaperOwner = SecurityUtils.getSubject().isPermitted(new PaperPermission(permissionStr));
+        boolean isAdmin = roleLogic.isAdmin(userId);
+        boolean isStudentFromExam = (examId != null);
+
+        // come from paper page
+        if (!isPaperOwner && !isAdmin && !isStudentFromExam) {
             throw new UnauthenticatedException("forbidden");
         }
-        return paperLogic.getPaperById(paperId, examId);
+
+        /*
+          admin and owner can view any time.
+          participant only view after upcoming state.
+         */
+        if (isStudentFromExam) {
+            ExamVO exam = examLogic.getExamById(examId);
+            boolean isExamOwner = exam.getManagerId().equals(userId);
+            boolean isExamOwnerOrParticipant = examLogic.checkTaskViewPermission(userId, examId);
+            if (!isAdmin && !isExamOwner) {
+                if (exam.getStatus().equals(Exam.STATUS_UPCOMING)) {
+                    throw new UnauthenticatedException("forbidden");
+                } else if (!isExamOwnerOrParticipant) {
+                    throw new UnauthenticatedException("forbidden");
+                }
+            }
+        }
+
+        PaperVO paperVO = paperLogic.getPaperById(paperId, examId);
+        if (paperVO == null) {
+            throw new HttpNotFoundException(String.format("paper %s not exists", paperId));
+        }
+        return paperVO;
+    }
+
+    private void foo(boolean isAdmin, ExamVO exam, boolean isExamOwner, boolean isExamOwnerOrParticipant) {
+        if (exam.getStatus().equals(Exam.STATUS_UPCOMING)) {
+            if (!isExamOwner && !isAdmin) {
+                throw new UnauthenticatedException("forbidden");
+            }
+        } else {
+            if (!isExamOwner && !isAdmin && !isExamOwnerOrParticipant) {
+                throw new UnauthenticatedException("forbidden");
+            }
+        }
     }
 
     @RequiresPermissions("paper:create")

+ 2 - 4
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/ctrl/ThemeController.java

@@ -2,7 +2,6 @@ package cn.iselab.mooctest.site.web.ctrl;
 
 import cn.iselab.mooctest.site.common.constant.Constants;
 import cn.iselab.mooctest.site.common.constant.UrlConstants;
-import cn.iselab.mooctest.site.common.enums.RoleType;
 import cn.iselab.mooctest.site.models.ThemeDetail;
 import cn.iselab.mooctest.site.web.data.*;
 import cn.iselab.mooctest.site.web.data.response.ResponseVO;
@@ -13,7 +12,6 @@ import cn.iselab.mooctest.site.web.logic.ExamLogic;
 import cn.iselab.mooctest.site.web.logic.GroupLogic;
 import cn.iselab.mooctest.site.web.logic.ThemeLogic;
 import com.google.gson.Gson;
-import io.lettuce.core.dynamic.annotation.Param;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -21,7 +19,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.*;
 import org.springframework.web.bind.annotation.*;
 
-import javax.websocket.server.PathParam;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -436,8 +433,9 @@ public class ThemeController extends BaseSearchController {
         Map<String, String> excludeCondition;
 
         if(searchConditionVO.getColumnFilters()==null){
-            if(!roleLogic.getRoleIdsByUserId(userId).contains((long) RoleType.ADMIN.getCode()))
+            if(!roleLogic.isAdmin(userId)) {
                 throw new HttpForbiddenException(String.format("Cannot list all courses, userId: %s", userId));
+            }
             extraCondition = new HashMap<>();
             excludeCondition = new HashMap<>();
         } else{

+ 5 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/RoleVO.java

@@ -1,5 +1,6 @@
 package cn.iselab.mooctest.site.web.data;
 
+import cn.iselab.mooctest.site.common.enums.RoleType;
 import com.fasterxml.jackson.annotation.JsonInclude;
 
 /**
@@ -38,4 +39,8 @@ public class RoleVO extends BaseVO {
     public void setCreateTime(Long createTime) {
         this.createTime = createTime;
     }
+
+    public boolean isAdmin() {
+        return getId() == RoleType.ADMIN.getCode();
+    }
 }

+ 1 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/data/ScoreVO.java

@@ -14,5 +14,6 @@ public class ScoreVO {
     //假如要支持一个考试对应多个试卷,需要增加paperId字段,assignTask表需要增加paperId字段
     private Long examId;
     private Double totalScore;
+    private String resultPdf;
     private List<AssignedCase> caseScoreList;
 }

+ 8 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/RoleLogic.java

@@ -1,5 +1,6 @@
 package cn.iselab.mooctest.site.web.logic;
 
+import cn.iselab.mooctest.site.common.enums.RoleType;
 import cn.iselab.mooctest.site.web.data.RoleVO;
 
 import java.util.List;
@@ -13,4 +14,11 @@ public interface RoleLogic {
     List<RoleVO> getRolesByUserName(Long userId);
 
     List<Long> getRoleIdsByUserId(long userId);
+
+    /**
+     * @param userId 用户编号
+     * @return 是否是管理员
+     */
+    boolean isAdmin(Long userId);
+
 }

+ 8 - 1
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/ExamLogicImpl.java

@@ -16,6 +16,7 @@ import cn.iselab.mooctest.site.service.*;
 import cn.iselab.mooctest.site.service.enums.ExamTypeEnum;
 import cn.iselab.mooctest.site.service.instancePermission.ExamPermissionService;
 import cn.iselab.mooctest.site.service.validation.ValidateResult;
+import cn.iselab.mooctest.site.util.MD5Util.MD5Util;
 import cn.iselab.mooctest.site.util.data.CacheUtil;
 import cn.iselab.mooctest.site.util.data.Converter;
 import cn.iselab.mooctest.site.web.data.*;
@@ -292,7 +293,7 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
                 vo.setWorkerId(participant.getId());
                 vo.setAssignedCases(assignedCaseVOWrapper.wrap(submitRecordService.wrapAssignedCases(assignedTask)));
                 vo.setResultZip(ossLogic.zipFilePath(participant.getName()+"_"+assignedTask.getName()+".zip"));
-                vo.setResultPdf(ossLogic.pdfFilePath(participant.getName()+"_"+assignedTask.getName()+".pdf"));
+                vo.setResultPdf(ossLogic.pdfFilePath(MD5Util.string2MD5(participant.getName()+"_"+assignedTask.getName())+".pdf"));
                 return vo;
             });
         return assignedTaskVOs;
@@ -342,10 +343,16 @@ public class ExamLogicImpl extends BaseLogic implements ExamLogic {
         if (submitRecord == null) {
             throw new AssignedTaskNotExistException("该学生本次考试的成绩不存在");
         }
+        UserDTOForMT user = userService.findByUserId(participantId);
+        if (user == null) {
+            throw new AssignedTaskNotExistException("该学生不存在");
+        }
         ScoreVO scoreVO = scoreVOWrapper.wrap(submitRecord);
+        scoreVO.setResultPdf(ossLogic.pdfFilePath(user.getName()+"_"+submitRecord.getName()));
         return scoreVO;
     }
 
+    @Override
     public List<Double> getScoreList(Long examId) {
         return submitRecordService.getScoreList(examId);
     }

+ 3 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/PaperLogicImpl.java

@@ -59,6 +59,9 @@ public class PaperLogicImpl extends BaseLogic implements PaperLogic {
     @Override
     public PaperVO getPaperById(long paperId, Long examId) {
         Paper paper = paperService.getById(paperId);
+        if (paper == null) {
+            return null;
+        }
         PaperVO paperVO;
         if (examId == null) {
             paperVO = paperVOWrapper.wrap(paper);

+ 6 - 0
mooctest-site-server/src/main/java/cn/iselab/mooctest/site/web/logic/impl/RoleLogicImpl.java

@@ -1,5 +1,6 @@
 package cn.iselab.mooctest.site.web.logic.impl;
 
+import cn.iselab.mooctest.site.common.enums.RoleType;
 import cn.iselab.mooctest.site.models.Role;
 import cn.iselab.mooctest.site.service.RoleService;
 import cn.iselab.mooctest.site.web.data.RoleVO;
@@ -39,4 +40,9 @@ public class RoleLogicImpl extends BaseLogic implements RoleLogic {
     public List<Long> getRoleIdsByUserId(long userId) {
         return roleService.getRoleIdsOfUser(userId);
     }
+
+    @Override
+    public boolean isAdmin(Long userId) {
+        return getRolesByUserName(userId).stream().anyMatch(RoleVO::isAdmin);
+    }
 }

+ 4 - 2
mooctest-site-server/src/test/java/cn/iselab/mooctest/site/web/logic/impl/ExamLogicImplTest.java

@@ -32,8 +32,7 @@ import java.util.*;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyList;
+import static org.mockito.Matchers.*;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 /**
@@ -355,8 +354,11 @@ public class ExamLogicImplTest {
     public void test_getScoreBy(){
         SubmitRecord at = new SubmitRecord();
         ScoreVO scoreVO = new ScoreVO();
+        UserDTOForMT user = new UserDTOForMT();
+        user.setName("TEST");
         when(submitRecordService.getAssignedTask(examVO.getId(),userId)).thenReturn(at);
         when(scoreVOWrapper.wrap(at)).thenReturn(scoreVO);
+        when(userService.findByUserId(anyLong())).thenReturn(user);
 
         ScoreVO result = examLogic.getScoreBy(examVO.getId(),userId);
         assertEquals(scoreVO,result);