Просмотр исходного кода

oss-mgr 中添加 OssClientService#getSignedUrl 方法

reghao 1 месяц назад
Родитель
Сommit
c2c1ca2f45

+ 7 - 62
oss-mgr/src/main/java/cn/reghao/oss/mgr/controller/OssSdkController.java

@@ -1,26 +1,18 @@
 package cn.reghao.oss.mgr.controller;
 package cn.reghao.oss.mgr.controller;
 
 
+import cn.reghao.jutil.jdk.web.result.Result;
+import cn.reghao.jutil.jdk.web.result.ResultStatus;
 import cn.reghao.jutil.jdk.web.result.WebResult;
 import cn.reghao.jutil.jdk.web.result.WebResult;
-import cn.reghao.oss.api.constant.ObjectScope;
 import cn.reghao.oss.api.dto.ObjectChannel;
 import cn.reghao.oss.api.dto.ObjectChannel;
 import cn.reghao.oss.api.dto.ObjectInfo;
 import cn.reghao.oss.api.dto.ObjectInfo;
-import cn.reghao.oss.api.dto.ObjectMeta;
 import cn.reghao.oss.api.dto.ServerInfo;
 import cn.reghao.oss.api.dto.ServerInfo;
 import cn.reghao.oss.api.dto.media.VideoInfo;
 import cn.reghao.oss.api.dto.media.VideoInfo;
 import cn.reghao.oss.api.dto.rest.UploadFileRet;
 import cn.reghao.oss.api.dto.rest.UploadFileRet;
 import cn.reghao.oss.api.dto.rest.UploadPrepare;
 import cn.reghao.oss.api.dto.rest.UploadPrepare;
 import cn.reghao.oss.api.dto.rest.UploadPrepareRet;
 import cn.reghao.oss.api.dto.rest.UploadPrepareRet;
-import cn.reghao.oss.api.util.SignatureUtils;
-import cn.reghao.oss.mgr.config.UserContext;
-import cn.reghao.oss.mgr.db.mapper.UploadChannelMapper;
-import cn.reghao.oss.mgr.db.mapper.UserKeyMapper;
-import cn.reghao.oss.mgr.db.mapper.UserNodeMapper;
-import cn.reghao.oss.mgr.db.repository.ObjectRepository;
 import cn.reghao.oss.mgr.model.dto.FileInitRequest;
 import cn.reghao.oss.mgr.model.dto.FileInitRequest;
 import cn.reghao.oss.api.dto.rest.UploadSample;
 import cn.reghao.oss.api.dto.rest.UploadSample;
 import cn.reghao.oss.mgr.model.po.StoreNode;
 import cn.reghao.oss.mgr.model.po.StoreNode;
-import cn.reghao.oss.mgr.model.po.UploadChannel;
-import cn.reghao.oss.mgr.model.po.UserNode;
 import cn.reghao.oss.mgr.service.MetadataService;
 import cn.reghao.oss.mgr.service.MetadataService;
 import cn.reghao.oss.mgr.service.OssClientService;
 import cn.reghao.oss.mgr.service.OssClientService;
 import cn.reghao.oss.mgr.service.UserNodeService;
 import cn.reghao.oss.mgr.service.UserNodeService;
@@ -29,8 +21,6 @@ import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
-import java.util.*;
-
 /**
 /**
  * oss 对外提供的接口
  * oss 对外提供的接口
  *
  *
@@ -43,22 +33,12 @@ public class OssSdkController {
     private final OssClientService ossClientService;
     private final OssClientService ossClientService;
     private final MetadataService metadataService;
     private final MetadataService metadataService;
     private final UserNodeService userNodeService;
     private final UserNodeService userNodeService;
-    private final ObjectRepository objectRepository;
-    private final UserKeyMapper userKeyMapper;
-    private final UserNodeMapper userNodeMapper;
-    private final UploadChannelMapper uploadChannelMapper;
 
 
     public OssSdkController(OssClientService ossClientService, MetadataService metadataService,
     public OssSdkController(OssClientService ossClientService, MetadataService metadataService,
-                            UserNodeService userNodeService, ObjectRepository objectRepository,
-                            UserKeyMapper userKeyMapper, UserNodeMapper userNodeMapper,
-                            UploadChannelMapper uploadChannelMapper) {
+                            UserNodeService userNodeService) {
         this.ossClientService = ossClientService;
         this.ossClientService = ossClientService;
         this.metadataService = metadataService;
         this.metadataService = metadataService;
         this.userNodeService = userNodeService;
         this.userNodeService = userNodeService;
-        this.objectRepository = objectRepository;
-        this.userKeyMapper = userKeyMapper;
-        this.userNodeMapper = userNodeMapper;
-        this.uploadChannelMapper = uploadChannelMapper;
     }
     }
 
 
     @Operation(summary = "获取上传对象所需的数据", description = "N")
     @Operation(summary = "获取上传对象所需的数据", description = "N")
@@ -91,47 +71,12 @@ public class OssSdkController {
     @Operation(summary = "获取访问对象所需的签名 URL", description = "N")
     @Operation(summary = "获取访问对象所需的签名 URL", description = "N")
     @GetMapping(value = "/presign", produces = MediaType.APPLICATION_JSON_VALUE)
     @GetMapping(value = "/presign", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getPresignedUrl(@RequestParam("objectId") String objectId, @RequestParam("action") String action) {
     public String getPresignedUrl(@RequestParam("objectId") String objectId, @RequestParam("action") String action) {
-        long loginUser = UserContext.getUserId();
-        ObjectMeta objectMeta = objectRepository.getObjectMetaById(objectId, loginUser);
-        if (objectMeta == null) {
-            return WebResult.failWithMsg("not exist");
-        }
-
-        // 24h
-        int durationInMinutes = 1440;
-        // 2. 计算过期时间(当前时间 + 持续分钟数)
-        long expires = (System.currentTimeMillis() / 1000) + (durationInMinutes * 60L);
-
-        String accessKeyId = userKeyMapper.findByCreateBy(loginUser).getAccessKeyId();
-        // 生成一个短随机数,例如 UUID 的前 8 位或随机 16 进制字符串
-        // 避免重放攻击, 使 url 只能访问一次
-        String nonce = UUID.randomUUID().toString().substring(0, 8);
-
-        // 3. 调用工具类生成签名
-        String sign = SignatureUtils.calculateSignature(accessKeyId, expires, objectId);
-
-        String objectName = objectMeta.getObjectName();
-        List<UploadChannel> uploadChannelList = uploadChannelMapper.findByCreateBy(loginUser);
-        Collections.reverse(uploadChannelList);
-        for (UploadChannel uploadChannel : uploadChannelList) {
-            String prefix = uploadChannel.getPrefix();
-            if (objectName.startsWith(prefix)) {
-                int userNodeId = uploadChannel.getUserNodeId();
-                UserNode userNode = userNodeMapper.findById(userNodeId);
-
-                String protocol = userNode.getProtocol();
-                String domain = userNode.getDomain();
-                String ossUrl = String.format("%s://%s", protocol, domain);
-                String signedParams = String.format("ak=%s&t=%s&nonce=%s&sign=%s", accessKeyId, expires, nonce, sign);;
-
-                // 4. 拼接最终的公网访问 URL
-                // 格式:域名 + objectId + 参数
-                String signedUrl = String.format("%s/%s?%s", ossUrl, objectName, signedParams);
-                return WebResult.success(signedUrl);
-            }
+        Result result = ossClientService.getSignedUrl(objectId, action);
+        if (result.getCode() == ResultStatus.SUCCESS.getCode()) {
+            return WebResult.success(result.getData());
         }
         }
 
 
-        return WebResult.failWithMsg("UserNode not found");
+        return WebResult.result(result);
     }
     }
 
 
     @Operation(summary = "获取 channel", description = "N")
     @Operation(summary = "获取 channel", description = "N")

+ 76 - 5
oss-mgr/src/main/java/cn/reghao/oss/mgr/service/OssClientService.java

@@ -1,5 +1,7 @@
 package cn.reghao.oss.mgr.service;
 package cn.reghao.oss.mgr.service;
 
 
+import cn.reghao.jutil.jdk.web.result.Result;
+import cn.reghao.jutil.jdk.web.result.WebResult;
 import cn.reghao.oss.api.constant.ObjectAction;
 import cn.reghao.oss.api.constant.ObjectAction;
 import cn.reghao.oss.api.constant.ObjectScope;
 import cn.reghao.oss.api.constant.ObjectScope;
 import cn.reghao.oss.api.constant.UploadStatus;
 import cn.reghao.oss.api.constant.UploadStatus;
@@ -7,18 +9,19 @@ import cn.reghao.oss.api.dto.*;
 import cn.reghao.oss.api.dto.media.VideoInfo;
 import cn.reghao.oss.api.dto.media.VideoInfo;
 import cn.reghao.oss.api.iface.StoreService;
 import cn.reghao.oss.api.iface.StoreService;
 import cn.reghao.oss.api.util.JwtUtils;
 import cn.reghao.oss.api.util.JwtUtils;
+import cn.reghao.oss.api.util.SignatureUtils;
 import cn.reghao.oss.mgr.config.UserContext;
 import cn.reghao.oss.mgr.config.UserContext;
 import cn.reghao.oss.mgr.db.mapper.DataBlockMapper;
 import cn.reghao.oss.mgr.db.mapper.DataBlockMapper;
 import cn.reghao.oss.mgr.db.mapper.FileMetaMapper;
 import cn.reghao.oss.mgr.db.mapper.FileMetaMapper;
 import cn.reghao.oss.mgr.db.mapper.UploadTaskMapper;
 import cn.reghao.oss.mgr.db.mapper.UploadTaskMapper;
+import cn.reghao.oss.mgr.db.mapper.UserKeyMapper;
 import cn.reghao.oss.mgr.db.repository.ObjectRepository;
 import cn.reghao.oss.mgr.db.repository.ObjectRepository;
 import cn.reghao.oss.mgr.model.po.*;
 import cn.reghao.oss.mgr.model.po.*;
 import cn.reghao.oss.mgr.rpc.RpcService;
 import cn.reghao.oss.mgr.rpc.RpcService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 
 /**
 /**
  * cn.reghao.oss.sdk.OssClient 的后端实现
  * cn.reghao.oss.sdk.OssClient 的后端实现
@@ -38,12 +41,13 @@ public class OssClientService {
     private final UploadTaskMapper uploadTaskMapper;
     private final UploadTaskMapper uploadTaskMapper;
     private final FileMetaMapper fileMetaMapper;
     private final FileMetaMapper fileMetaMapper;
     private final DataBlockMapper dataBlockMapper;
     private final DataBlockMapper dataBlockMapper;
+    private final UserKeyService userKeyService;
 
 
     public OssClientService(StoreNodeService storeNodeService, ObjectRepository objectRepository,
     public OssClientService(StoreNodeService storeNodeService, ObjectRepository objectRepository,
                               UploadChannelService uploadChannelService, UserNodeService userNodeService,
                               UploadChannelService uploadChannelService, UserNodeService userNodeService,
                               StoreConfigService storeConfigService, RpcService rpcService,
                               StoreConfigService storeConfigService, RpcService rpcService,
                               UploadTaskMapper uploadTaskMapper, FileMetaMapper fileMetaMapper,
                               UploadTaskMapper uploadTaskMapper, FileMetaMapper fileMetaMapper,
-                              DataBlockMapper dataBlockMapper) {
+                              DataBlockMapper dataBlockMapper, UserKeyService userKeyService) {
         this.storeNodeService = storeNodeService;
         this.storeNodeService = storeNodeService;
         this.objectRepository = objectRepository;
         this.objectRepository = objectRepository;
         this.uploadChannelService = uploadChannelService;
         this.uploadChannelService = uploadChannelService;
@@ -53,8 +57,72 @@ public class OssClientService {
         this.uploadTaskMapper = uploadTaskMapper;
         this.uploadTaskMapper = uploadTaskMapper;
         this.fileMetaMapper = fileMetaMapper;
         this.fileMetaMapper = fileMetaMapper;
         this.dataBlockMapper = dataBlockMapper;
         this.dataBlockMapper = dataBlockMapper;
+        this.userKeyService = userKeyService;
     }
     }
 
 
+    public Result getSignedUrl(String objectId, String action) {
+        long loginUser = UserContext.getUserId();
+        ObjectMeta objectMeta = objectRepository.getObjectMetaById(objectId, loginUser);
+        if (objectMeta == null) {
+            return Result.fail("Object not exist");
+        }
+
+        // 24h
+        int durationInMinutes = 1440;
+        // 2. 计算过期时间(当前时间 + 持续分钟数)
+        long expires = (System.currentTimeMillis() / 1000) + (durationInMinutes * 60L);
+
+        UserKey userKey = userKeyService.getUserKey(loginUser);
+        if (userKey == null) {
+            return Result.fail("UserKey not exist");
+        }
+        String accessKeyId = userKey.getAccessKeyId();
+
+        // 生成一个短随机数,例如 UUID 的前 8 位或随机 16 进制字符串
+        // 避免重放攻击, 使 url 只能访问一次
+        String nonce = UUID.randomUUID().toString().substring(0, 8);
+
+        // 3. 调用工具类生成签名
+        String sign = SignatureUtils.calculateSignature(accessKeyId, expires, objectId);
+
+        String objectName = objectMeta.getObjectName();
+        UploadChannel uploadChannel = getUploadChannel(loginUser, objectName);
+        if (uploadChannel == null) {
+            return Result.fail("UploadChannel not found");
+        }
+
+        int userNodeId = uploadChannel.getUserNodeId();
+        UserNode userNode = userNodeService.getUserNode(userNodeId);
+        if (userNode == null) {
+            return Result.fail("UserNode not found");
+        }
+
+        String protocol = userNode.getProtocol();
+        String domain = userNode.getDomain();
+        String ossUrl = String.format("%s://%s", protocol, domain);
+        String signedParams = String.format("ak=%s&t=%s&nonce=%s&sign=%s", accessKeyId, expires, nonce, sign);;
+
+        // 4. 拼接最终的公网访问 URL
+        // 格式:域名 + objectId + 参数
+        String signedUrl = String.format("%s/%s?%s", ossUrl, objectName, signedParams);
+        return Result.success(signedUrl);
+    }
+
+    private UploadChannel getUploadChannel(long loginUser, String objectName) {
+        List<UploadChannel> uploadChannelList = uploadChannelService.getUploadChannelsByCreateBy(loginUser);
+        Collections.reverse(uploadChannelList);
+
+        UploadChannel uploadChannel0 = null;
+        for (UploadChannel uploadChannel : uploadChannelList) {
+            String prefix = uploadChannel.getPrefix();
+            if (objectName.startsWith(prefix)) {
+                uploadChannel0 =  uploadChannel;
+                break;
+            }
+        }
+
+        return uploadChannel0;
+    }
 
 
     public ObjectChannel getChannelByCode(int channelCode) {
     public ObjectChannel getChannelByCode(int channelCode) {
         long loginUser = UserContext.getUserId();
         long loginUser = UserContext.getUserId();
@@ -114,12 +182,15 @@ public class OssClientService {
     }
     }
 
 
     public void checkAndSetScope(String objectId, int scope) {
     public void checkAndSetScope(String objectId, int scope) {
-        ObjectScope objectScope = ObjectScope.getByCode(scope);
+        if (scope != ObjectScope.PUBLIC.getCode()) {
+            scope = ObjectScope.PRIVATE.getCode();
+        }
+
         FileMeta fileMeta = fileMetaMapper.findByObjectId(objectId);
         FileMeta fileMeta = fileMetaMapper.findByObjectId(objectId);
         if (fileMeta != null) {
         if (fileMeta != null) {
             int currentScope = fileMeta.getScope();
             int currentScope = fileMeta.getScope();
             if (currentScope != scope) {
             if (currentScope != scope) {
-                fileMetaMapper.updateScopeByObjectId(objectId, objectScope.getCode());
+                fileMetaMapper.updateScopeByObjectId(objectId, scope);
             }
             }
         }
         }
     }
     }

+ 5 - 0
oss-mgr/src/main/java/cn/reghao/oss/mgr/service/UserKeyService.java

@@ -37,6 +37,11 @@ public class UserKeyService {
     public void regenerate(long ossUser) {
     public void regenerate(long ossUser) {
     }
     }
 
 
+    public UserKey getUserKey(long loginUser) {
+        UserKey userKey = userKeyMapper.findByCreateBy(loginUser);
+        return userKey;
+    }
+
     public List<UserKey> getUserKeys(long ossUser) {
     public List<UserKey> getUserKeys(long ossUser) {
         UserKey userKey = userKeyMapper.findByCreateBy(ossUser);
         UserKey userKey = userKeyMapper.findByCreateBy(ossUser);
         if (userKey == null) {
         if (userKey == null) {