Browse Source

oss-mgr 中添加 OssClientService#getSignedUrl 方法

reghao 1 month ago
parent
commit
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;
 
+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.oss.api.constant.ObjectScope;
 import cn.reghao.oss.api.dto.ObjectChannel;
 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.media.VideoInfo;
 import cn.reghao.oss.api.dto.rest.UploadFileRet;
 import cn.reghao.oss.api.dto.rest.UploadPrepare;
 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.api.dto.rest.UploadSample;
 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.OssClientService;
 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.web.bind.annotation.*;
 
-import java.util.*;
-
 /**
  * oss 对外提供的接口
  *
@@ -43,22 +33,12 @@ public class OssSdkController {
     private final OssClientService ossClientService;
     private final MetadataService metadataService;
     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,
-                            UserNodeService userNodeService, ObjectRepository objectRepository,
-                            UserKeyMapper userKeyMapper, UserNodeMapper userNodeMapper,
-                            UploadChannelMapper uploadChannelMapper) {
+                            UserNodeService userNodeService) {
         this.ossClientService = ossClientService;
         this.metadataService = metadataService;
         this.userNodeService = userNodeService;
-        this.objectRepository = objectRepository;
-        this.userKeyMapper = userKeyMapper;
-        this.userNodeMapper = userNodeMapper;
-        this.uploadChannelMapper = uploadChannelMapper;
     }
 
     @Operation(summary = "获取上传对象所需的数据", description = "N")
@@ -91,47 +71,12 @@ public class OssSdkController {
     @Operation(summary = "获取访问对象所需的签名 URL", description = "N")
     @GetMapping(value = "/presign", produces = MediaType.APPLICATION_JSON_VALUE)
     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")

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

@@ -1,5 +1,7 @@
 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.ObjectScope;
 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.iface.StoreService;
 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.db.mapper.DataBlockMapper;
 import cn.reghao.oss.mgr.db.mapper.FileMetaMapper;
 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.model.po.*;
 import cn.reghao.oss.mgr.rpc.RpcService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 /**
  * cn.reghao.oss.sdk.OssClient 的后端实现
@@ -38,12 +41,13 @@ public class OssClientService {
     private final UploadTaskMapper uploadTaskMapper;
     private final FileMetaMapper fileMetaMapper;
     private final DataBlockMapper dataBlockMapper;
+    private final UserKeyService userKeyService;
 
     public OssClientService(StoreNodeService storeNodeService, ObjectRepository objectRepository,
                               UploadChannelService uploadChannelService, UserNodeService userNodeService,
                               StoreConfigService storeConfigService, RpcService rpcService,
                               UploadTaskMapper uploadTaskMapper, FileMetaMapper fileMetaMapper,
-                              DataBlockMapper dataBlockMapper) {
+                              DataBlockMapper dataBlockMapper, UserKeyService userKeyService) {
         this.storeNodeService = storeNodeService;
         this.objectRepository = objectRepository;
         this.uploadChannelService = uploadChannelService;
@@ -53,8 +57,72 @@ public class OssClientService {
         this.uploadTaskMapper = uploadTaskMapper;
         this.fileMetaMapper = fileMetaMapper;
         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) {
         long loginUser = UserContext.getUserId();
@@ -114,12 +182,15 @@ public class OssClientService {
     }
 
     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);
         if (fileMeta != null) {
             int currentScope = fileMeta.getScope();
             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 UserKey getUserKey(long loginUser) {
+        UserKey userKey = userKeyMapper.findByCreateBy(loginUser);
+        return userKey;
+    }
+
     public List<UserKey> getUserKeys(long ossUser) {
         UserKey userKey = userKeyMapper.findByCreateBy(ossUser);
         if (userKey == null) {