648540858
2024-05-23 2daa59d78ce206308c35294da04cffe5e340143a
支持彻底关闭文档页面 + 修复云端录像偶现callId错误问题
12个文件已修改
1个文件已添加
109 ■■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRecordMp4HookParam.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/MediaServerUtils.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/all-application.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
数据库/2.7.1/初始化-mysql-2.7.1.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
数据库/2.7.1/初始化-postgresql-kingbase-2.7.1.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/conf/SpringDocConfig.java
@@ -7,6 +7,7 @@
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
@@ -18,6 +19,7 @@
 */
@Configuration
@Order(1)
@ConditionalOnProperty(value = "user-settings.doc-enable", havingValue = "true", matchIfMissing = true)
public class SpringDocConfig {
    @Value("${doc.enabled: true}")
src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
@@ -54,6 +54,8 @@
    private Boolean deviceStatusNotify = Boolean.TRUE;
    private Boolean useCustomSsrcForParentInvite = Boolean.TRUE;
    private Boolean docEnable = Boolean.TRUE;
    private String serverId = "000000";
    private String thirdPartyGBIdReg = "[\\s\\S]*";
@@ -315,4 +317,12 @@
    public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) {
        this.registerKeepIntDialog = registerKeepIntDialog;
    }
    public Boolean getDocEnable() {
        return docEnable;
    }
    public void setDocEnable(Boolean docEnable) {
        this.docEnable = docEnable;
    }
}
src/main/java/com/genersoft/iot/vmp/conf/security/JwtAuthenticationFilter.java
@@ -35,10 +35,16 @@
        // å¿½ç•¥ç™»å½•请求的token验证
        String requestURI = request.getRequestURI();
        System.out.println(requestURI);
        if ((requestURI.startsWith("/doc.html") || requestURI.startsWith("/swagger-ui") ) && !userSetting.getDocEnable()) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        if (requestURI.equalsIgnoreCase("/api/user/login")) {
            chain.doFilter(request, response);
            return;
        }
        if (!userSetting.isInterfaceAuthentication()) {
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null, new ArrayList<>() );
            SecurityContextHolder.getContext().setAuthentication(token);
src/main/java/com/genersoft/iot/vmp/conf/security/WebSecurityConfig.java
@@ -117,7 +117,7 @@
                .authorizeRequests()
                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                .antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll()
                .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html").permitAll()
                .antMatchers("/api/user/login", "/index/hook/**", "/swagger-ui/**", "/doc.html#/**").permitAll()
                .anyRequest().authenticated()
                // å¼‚常处理器
                .and()
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -29,6 +29,7 @@
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.utils.MediaServerUtils;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.OtherPsSendInfo;
import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
@@ -47,7 +48,6 @@
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -179,7 +179,7 @@
            }
        });
        if (!"rtp".equals(param.getApp())) {
            Map<String, String> paramMap = urlParamToMap(param.getParams());
            Map<String, String> paramMap = MediaServerUtils.urlParamToMap(param.getParams());
            StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
            if (streamAuthorityInfo != null && streamAuthorityInfo.getCallId() != null && !streamAuthorityInfo.getCallId().equals(paramMap.get("callId"))) {
                return new HookResult(401, "Unauthorized");
@@ -220,7 +220,7 @@
                    logger.info("推流鉴权失败: ç¼ºå°‘必要参数:sign=md5(user表的pushKey)");
                    return new HookResultForOnPublish(401, "Unauthorized");
                }
                Map<String, String> paramMap = urlParamToMap(param.getParams());
                Map<String, String> paramMap = MediaServerUtils.urlParamToMap(param.getParams());
                String sign = paramMap.get("sign");
                if (sign == null) {
                    logger.info("推流鉴权失败: ç¼ºå°‘必要参数:sign=md5(user表的pushKey)");
@@ -898,23 +898,5 @@
        });
        return HookResult.SUCCESS();
    }
    private Map<String, String> urlParamToMap(String params) {
        HashMap<String, String> map = new HashMap<>();
        if (ObjectUtils.isEmpty(params)) {
            return map;
        }
        String[] paramsArray = params.split("&");
        if (paramsArray.length == 0) {
            return map;
        }
        for (String param : paramsArray) {
            String[] paramArray = param.split("=");
            if (paramArray.length == 2) {
                map.put(paramArray[0], paramArray[1]);
            }
        }
        return map;
    }
}
src/main/java/com/genersoft/iot/vmp/media/zlm/dto/hook/OnRecordMp4HookParam.java
@@ -15,6 +15,7 @@
    private String vhost;
    private long start_time;
    private double time_len;
    private String params;
    public String getApp() {
        return app;
@@ -96,6 +97,14 @@
        this.time_len = time_len;
    }
    public String getParams() {
        return params;
    }
    public void setParams(String params) {
        this.params = params;
    }
    @Override
    public String toString() {
        return "OnRecordMp4HookParam{" +
@@ -109,6 +118,7 @@
                ", vhost='" + vhost + '\'' +
                ", start_time=" + start_time +
                ", time_len=" + time_len +
                ", params=" + params +
                '}';
    }
}
src/main/java/com/genersoft/iot/vmp/service/bean/CloudRecordItem.java
@@ -1,6 +1,9 @@
package com.genersoft.iot.vmp.service.bean;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
import com.genersoft.iot.vmp.utils.MediaServerUtils;
import java.util.Map;
/**
 * äº‘端录像数据
@@ -88,6 +91,10 @@
        cloudRecordItem.setMediaServerId(param.getMediaServerId());
        cloudRecordItem.setTimeLen((long) param.getTime_len() * 1000);
        cloudRecordItem.setEndTime((param.getStart_time() + (long)param.getTime_len()) * 1000);
        Map<String, String> paramsMap = MediaServerUtils.urlParamToMap(param.getParams());
        if (paramsMap.get("callId") != null) {
            cloudRecordItem.setCallId(paramsMap.get("callId"));
        }
        return cloudRecordItem;
    }
src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java
@@ -7,7 +7,6 @@
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.media.zlm.AssistRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
import com.genersoft.iot.vmp.media.zlm.dto.StreamAuthorityInfo;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
import com.genersoft.iot.vmp.service.ICloudRecordService;
import com.genersoft.iot.vmp.service.IMediaServerService;
@@ -26,8 +25,12 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.*;
import java.util.*;
import java.time.LocalDate;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Service
@DS("share")
@@ -102,11 +105,7 @@
    @Override
    public void addRecord(OnRecordMp4HookParam param) {
        CloudRecordItem cloudRecordItem = CloudRecordItem.getInstance(param);
        StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
        if (streamAuthorityInfo != null) {
            cloudRecordItem.setCallId(streamAuthorityInfo.getCallId());
        }
        logger.info("[添加录像记录] {}/{} æ–‡ä»¶å¤§å°ï¼š{}, æ—¶é•¿ï¼š {}秒", param.getApp(), param.getStream(), param.getFile_size(),param.getTime_len());
        logger.info("[添加录像记录] {}/{}, callId: {}, æ–‡ä»¶å¤§å°ï¼š{}, æ—¶é•¿ï¼š {}秒", param.getApp(), param.getStream(),cloudRecordItem.getCallId(), param.getFile_size(),param.getTime_len());
        cloudRecordServiceMapper.add(cloudRecordItem);
    }
src/main/java/com/genersoft/iot/vmp/utils/MediaServerUtils.java
New file
@@ -0,0 +1,26 @@
package com.genersoft.iot.vmp.utils;
import org.springframework.util.ObjectUtils;
import java.util.HashMap;
import java.util.Map;
public class MediaServerUtils {
    public static Map<String, String> urlParamToMap(String params) {
        HashMap<String, String> map = new HashMap<>();
        if (ObjectUtils.isEmpty(params)) {
            return map;
        }
        String[] paramsArray = params.split("&");
        if (paramsArray.length == 0) {
            return map;
        }
        for (String param : paramsArray) {
            String[] paramArray = param.split("=");
            if (paramArray.length == 2) {
                map.put(paramArray[0], paramArray[1]);
            }
        }
        return map;
    }
}
src/main/resources/all-application.yml
@@ -241,6 +241,8 @@
    register-again-after-time: 60
    # å›½æ ‡ç»­è®¢æ–¹å¼ï¼Œtrue为续订,每次注册在同一个会话里,false为重新注册,每次使用新的会话
    register-keep-int-dialog: false
    # å¼€å¯æŽ¥å£æ–‡æ¡£é¡µé¢ã€‚ é»˜è®¤å¼€å¯ï¼Œç”Ÿäº§çŽ¯å¢ƒå»ºè®®å…³é—­ï¼Œé‡åˆ°swagger相关的漏洞时也可以关闭
    doc-enable: true
    # è·¨åŸŸé…ç½®ï¼Œä¸é…ç½®æ­¤é¡¹åˆ™å…è®¸æ‰€æœ‰è·¨åŸŸè¯·æ±‚,配置后则只允许配置的页面的地址请求, å¯ä»¥é…ç½®å¤šä¸ª
    allowed-origins:
        - http://localhost:8008
src/main/resources/application-dev.yml
@@ -110,7 +110,4 @@
  auto-apply-play: true
  # è®¾å¤‡/通道状态变化时发送消息
  device-status-notify: true
# [可选] æ—¥å¿—配置, ä¸€èˆ¬ä¸éœ€è¦æ”¹
logging:
  config: classpath:logback-spring.xml
Êý¾Ý¿â/2.7.1/³õʼ»¯-mysql-2.7.1.sql
@@ -166,6 +166,7 @@
                                  hook_alive_interval integer,
                                  record_path character varying(255),
                                  record_day integer default 7,
                                  transcode_suffix character varying(255),
                                  constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
);
Êý¾Ý¿â/2.7.1/³õʼ»¯-postgresql-kingbase-2.7.1.sql
@@ -166,6 +166,7 @@
                                  hook_alive_interval integer,
                                  record_path character varying(255),
                                  record_day integer default 7,
                                  transcode_suffix character varying(255),
                                  constraint uk_media_server_unique_ip_http_port unique (ip, http_port)
);