qinchao 4 vuotta sitten
vanhempi
commit
dfea810670

+ 19 - 1
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/ExamController.java

@@ -77,6 +77,8 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.util.*;
 import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -311,6 +313,13 @@ public class ExamController extends ControllerSupport {
                 Map<String, String> properties = getProperties(bean.getId(), propertyKeyList);
                 bean.setProperties(properties);
             }
+
+            DynamicEnumManager manager = ExamProperty.getDynamicEnumManager();
+            DynamicEnum ipLimit = manager.getByName("IP_LIMIT");
+
+            ExamPropertyEntity propertyEntity = examPropertyRepo.findByExamIdAndKeyId(next.getId(), ipLimit.getId());
+            boolean ipLimited = null != propertyEntity && StringUtils.isNotBlank(propertyEntity.getValue()) && Boolean.parseBoolean(propertyEntity.getValue());
+            bean.setIpLimitSettingsEnabled(ipLimited);
         }
 
         PageInfo<ExamDomain> ret = new PageInfo<>(page, list);
@@ -1473,8 +1482,17 @@ public class ExamController extends ControllerSupport {
             if (StringUtils.isBlank(ip)) {
                 msg.append("  IP地址不能为空");
                 hasError = true;
+            } else {
+                String reg = "^(?:(?:1[0-9][0-9]\\.)|(?:2[0-4][0-9]\\.)|(?:25[0-5]\\.)|(?:[1-9][0-9]\\.)|(?:[0-9/*]\\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9/*]))$";
+                Pattern pattern = Pattern.compile(reg);
+                Matcher matcher = pattern.matcher(ip);
+                if (matcher.find()) {
+                    entity.setIp(ip);
+                } else {
+                    msg.append("  ip格式不正确");
+                    hasError = true;
+                }
             }
-            entity.setIp(ip);
 
             if (StringUtils.isBlank(line[1])) {
                 msg.append("  限制类型不能为空");

+ 12 - 0
examcloud-core-examwork-api-provider/src/main/java/cn/com/qmth/examcloud/core/examwork/api/controller/bean/ExamDomain.java

@@ -101,6 +101,11 @@ public class ExamDomain implements JsonSerializable {
 	 */
 	private Boolean specialSettingsEnabled;
 
+	/**
+	 * 是否开启特殊设置
+	 */
+	private Boolean ipLimitSettingsEnabled;
+
 	/**
 	 * 特殊设置类型
 	 */
@@ -253,4 +258,11 @@ public class ExamDomain implements JsonSerializable {
 		this.specialSettingsEnabled = specialSettingsEnabled;
 	}
 
+	public Boolean getIpLimitSettingsEnabled() {
+		return ipLimitSettingsEnabled;
+	}
+
+	public void setIpLimitSettingsEnabled(Boolean ipLimitSettingsEnabled) {
+		this.ipLimitSettingsEnabled = ipLimitSettingsEnabled;
+	}
 }

+ 1 - 1
examcloud-core-examwork-dao/src/main/java/cn/com/qmth/examcloud/core/examwork/dao/ExamIpLimitRepo.java

@@ -16,7 +16,7 @@ public interface ExamIpLimitRepo extends JpaRepository<ExamIpLimitEntity, Long>,
 
 	@Query(value = "SELECT count(1) from ec_e_exam_ip_limit t where t.exam_id = ?1 " +
 			"AND t.limit_type = ?2 AND ?3 REGEXP t.ip ",nativeQuery = true)
-	int countByExamIdAndLimitTypeAndIp(Long examId, Integer limitType, String ip);
+	int countByExamIdAndLimitTypeAndIp(Long examId, String limitType, String ip);
 
 	@Modifying
 	@Transactional

+ 50 - 38
examcloud-core-examwork-service/src/main/java/cn/com/qmth/examcloud/core/examwork/service/impl/ExamServiceImpl.java

@@ -881,59 +881,71 @@ public class ExamServiceImpl implements ExamService {
 
     @Override
     public boolean getIpLimited(String realIp, Long examId, User accessUser) {
-        //是否开启Ip限制
-        ExamPropertyCacheBean ipLimitProperty = CacheHelper.getExamProperty(examId, "IP_LIMIT");
-        boolean ipLimited = ipLimitProperty!=null && StringUtil.isTrue(ipLimitProperty.getValue());
-
         DynamicEnumManager manager = ExamProperty.getDynamicEnumManager();
-        DynamicEnum ipTotalLimit = manager.getByName("IP_TOTAL_LIMIT");
-        DynamicEnum ipCenterLimit = manager.getByName("IP_CENTER_LIMIT");
+        DynamicEnum ipLimit = manager.getByName("IP_LIMIT");
 
+        //是否开启Ip限制
+        Boolean ipLimited = getExamLimitProperty(examId, ipLimit.getId(), false);
         if (ipLimited) {
             //整体控制
+            DynamicEnum ipTotalLimit = manager.getByName("IP_TOTAL_LIMIT");
             Boolean totalLimit = getExamLimitProperty(examId, ipTotalLimit.getId(), false);
             if (totalLimit) {
                 //在白名单中
-                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId, IpLimitType.HAS_ACCESS.getId(),realIp);
-                if (count>0) {
-                    //学习中心访问控制
-                    Boolean centerLimit = getExamLimitProperty(examId,ipCenterLimit.getId(), false);
-                    if (centerLimit) {
-                        StudentCacheBean studentCache = CacheHelper.getStudent(accessUser.getUserId());
-                        Long orgId = studentCache.getOrgId();
-                        String key = "IP_" + orgId;
-                        String value = redisClient.get(key, String.class);
-                        //机构是否在时间范围内登陆过
-                        if (value != null) {
-                            @SuppressWarnings("unchecked")
-                            Set<String> userKeyList = JsonUtil.fromJson(value, Set.class);
-
-                            for (String userKey : userKeyList) {
-                                User curUser = redisClient.get(userKey, User.class);
-                                if (null != curUser) {
-                                    String clientIp = curUser.getClientIp();
-                                    if (null != clientIp) {
-                                        // IP取前三段
-                                        clientIp = clientIp.substring(0, clientIp.lastIndexOf(".") + 1);
-                                        if (realIp.startsWith(clientIp)) {
-                                            return false;
-                                        }
-                                    }
-                                }
+                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId, IpLimitType.HAS_ACCESS.name(),realIp);
+                if (count == 0) {
+                    return true;
+                } else {
+                    return getCenterLimit(manager, examId, accessUser.getUserId(), realIp);
+                }
+            } else {
+                //在黑名单中
+                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId, IpLimitType.NO_ACCESS.name(), realIp);
+                if (count > 0){
+                    return true;
+                } else {
+                    return getCenterLimit(manager, examId, accessUser.getUserId(), realIp);
+                }
 
+            }
+        }
+        return false;
+    }
+
+    private boolean getCenterLimit(DynamicEnumManager manager, Long examId, Long studentId, String realIp) {
+        //学习中心访问控制
+        DynamicEnum ipCenterLimit = manager.getByName("IP_CENTER_LIMIT");
+        Boolean centerLimit = getExamLimitProperty(examId,ipCenterLimit.getId(), false);
+        if (centerLimit) {
+            StudentCacheBean studentCache = CacheHelper.getStudent(studentId);
+            Long orgId = studentCache.getOrgId();
+            String key = "IP_" + orgId;
+            String value = redisClient.get(key, String.class);
+            //机构是否在时间范围内登陆过
+            if (value != null) {
+                @SuppressWarnings("unchecked")
+                Set<String> userKeyList = JsonUtil.fromJson(value, Set.class);
+
+                for (String userKey : userKeyList) {
+                    User curUser = redisClient.get(userKey, User.class);
+                    if (null != curUser) {
+                        String clientIp = curUser.getClientIp();
+                        if (null != clientIp) {
+                            // IP取前三段
+                            clientIp = clientIp.substring(0, clientIp.lastIndexOf(".") + 1);
+                            if (!realIp.startsWith(clientIp)) {
+                                return true;
                             }
                         }
+                    } else {
+                        return true;
                     }
                 }
             } else {
-                //不在黑名单中
-                int count = examIpLimitRepo.countByExamIdAndLimitTypeAndIp(examId,IpLimitType.NO_ACCESS.getId(), realIp);
-                return count > 0;
+                return true;
             }
-            return true;
-        } else {
-            return false;
         }
+        return false;
     }
 
     @Override