新增多吉云支持

This commit is contained in:
zhaojun
2023-03-05 15:12:26 +08:00
parent 2afb841fd9
commit 456aabb893
3 changed files with 136 additions and 1 deletions

View File

@@ -35,7 +35,8 @@ public enum StorageTypeEnum implements IEnum {
SHAREPOINT_DRIVE("sharepoint", "SharePoint"),
SHAREPOINT_DRIVE_CHINA("sharepoint-china", "SharePoint 世纪互联"),
GOOGLE_DRIVE("google-drive", "Google Drive"),
QINIU("qiniu", "七牛云 KODO");
QINIU("qiniu", "七牛云 KODO"),
DOGE_CLOUD("doge-cloud", "多吉云");
private static final Map<String, StorageTypeEnum> ENUM_MAP = new HashMap<>();

View File

@@ -0,0 +1,43 @@
package im.zhaojun.zfile.module.storage.model.param;
import im.zhaojun.zfile.module.storage.annotation.StorageParamItem;
import im.zhaojun.zfile.module.storage.model.enums.StorageParamTypeEnum;
import lombok.Getter;
import lombok.Setter;
/**
* @author zhaojun
*/
@Getter
@Setter
public class DogeCloudParam extends S3BaseParam {
@StorageParamItem(name = "区域", ignoreInput = true, description = "如下拉列表中没有的区域,或想使用内网地址,可直接输入后回车,如: xxx-cn-beijing.example.com")
private String endPoint;
@StorageParamItem(name = "存储空间名称", ignoreInput = true)
private String bucketName;
@StorageParamItem(name = "S3AccessKey", ignoreInput = true)
private String s3AccessKey;
@StorageParamItem(name = "S3SecretKey", ignoreInput = true)
private String s3SecretKey;
@StorageParamItem(name = "S3SessionToken", ignoreInput = true)
private String s3SessionToken;
@StorageParamItem(name = "存储空间名称", order = 4)
private String originBucketName;
@StorageParamItem(name = "是否是私有空间", type = StorageParamTypeEnum.SWITCH, defaultValue = "true", description = "私有空间会生成带签名的下载链接", ignoreInput = true)
private boolean isPrivate;
@StorageParamItem(name = "下载签名有效期", required = false, defaultValue = "1800", description = "当为私有空间时, 用于下载签名的有效期, 单位为秒, 如不配置则默认为 1800 秒.", ignoreInput = true)
private Integer tokenTime;
@StorageParamItem(name = "是否自动配置 CORS 跨域设置", order = 100, type = StorageParamTypeEnum.SWITCH, defaultValue = "true",
description = "如不配置跨域设置,可能会无法导致无法上传,或上传后看不到文件(某些 S3 存储无需配置此选项,如 Cloudflare R2、Oracle 对象存储)", ignoreInput = true)
private boolean autoConfigCors;
}

View File

@@ -0,0 +1,91 @@
package im.zhaojun.zfile.module.storage.service.impl;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import im.zhaojun.zfile.module.storage.model.enums.StorageTypeEnum;
import im.zhaojun.zfile.module.storage.model.param.DogeCloudParam;
import im.zhaojun.zfile.module.storage.service.base.AbstractS3BaseFileService;
import im.zhaojun.zfile.module.storage.service.base.RefreshTokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
/**
* @author zhaojun
*/
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Slf4j
public class DogeCloudServiceImpl extends AbstractS3BaseFileService<DogeCloudParam> implements RefreshTokenService {
@Override
public void init() {
refreshAccessToken();
BasicSessionCredentials awsCredentials = new BasicSessionCredentials(param.getS3AccessKey(), param.getS3SecretKey(), param.getS3SessionToken());
s3Client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
param.getEndPoint(),
"automatic"))
.build();
}
@Override
public StorageTypeEnum getStorageTypeEnum() {
return StorageTypeEnum.DOGE_CLOUD;
}
@Override
public void refreshAccessToken() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("channel", "OSS_FULL");
jsonObject.put("scopes", param.getOriginBucketName());
String apiDomain = "https://api.dogecloud.com";
String apiPath = "/auth/tmp_token.json";
String token = getToken(apiPath, jsonObject.toJSONString());
HttpResponse httpResponse = HttpUtil.createPost(apiDomain + apiPath)
.body(jsonObject.toJSONString())
.header(Header.AUTHORIZATION, "TOKEN " + param.getAccessKey() + ":" + token).execute();
String body = httpResponse.body();
JSONObject resultJsonObject = JSONObject.parseObject(body);
JSONObject credentials = resultJsonObject.getJSONObject("data").getJSONObject("Credentials");
param.setS3AccessKey(credentials.getString("accessKeyId"));
param.setS3SecretKey(credentials.getString("secretAccessKey"));
param.setS3SessionToken(credentials.getString("sessionToken"));
JSONArray bucketsArray = resultJsonObject.getJSONObject("data").getJSONArray("Buckets");
if (bucketsArray == null || bucketsArray.size() == 0) {
throw new IllegalArgumentException("存储空间名称不存在");
}
JSONObject buckets = bucketsArray.getJSONObject(0);
param.setBucketName(buckets.getString("s3Bucket"));
param.setEndPoint(buckets.getString("s3Endpoint"));
}
private String getToken(String apiPath, String paramsText) {
String signStr = apiPath + "\n" + paramsText;
return SecureUtil.hmacSha1(param.getSecretKey()).digestHex(signStr);
}
}