package logic import ( "context" "strings" "lone-services/pkg/utils" chore "lone-services/rpc/chore/pb" "lone-services/services/chore/internal/svc" openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" sts20150401 "github.com/alibabacloud-go/sts-20150401/v2/client" util "github.com/alibabacloud-go/tea-utils/v2/service" "github.com/alibabacloud-go/tea/tea" "github.com/zeromicro/go-zero/core/logx" ) type PolicyLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } // StsToken 对齐阿里云 STS 返回字段,并附带前端上传所需信息 type StsToken struct { AccessKeyId string `json:"AccessKeyId"` AccessKeySecret string `json:"AccessKeySecret"` SecurityToken string `json:"SecurityToken"` Expiration string `json:"Expiration"` Bucket string `json:"bucket"` Region string `json:"region"` Endpoint string `json:"endpoint"` Host string `json:"host"` Dir string `json:"dir"` } func NewPolicyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PolicyLogic { return &PolicyLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *PolicyLogic) Policy(in *chore.PolicyReq) (*chore.Response, error) { accessKeyId := utils.GetConfigString("oss.accessKeyId") accessKeySecret := utils.GetConfigString("oss.accessKeySecret") roleArn := utils.GetConfigString("oss.roleArn") roleSessionName := utils.GetConfigString("oss.roleSessionName") stsEndpoint := utils.GetConfigString("oss.stsEndpoint") region := utils.GetConfigString("oss.region") bucket := utils.GetConfigString("oss.bucketName") dir := utils.GetConfigString("oss.dir") endpoint := utils.GetConfigString("oss.endpoint") host := utils.GetConfigString("oss.host") if accessKeyId == utils.StringEmpty || accessKeySecret == utils.StringEmpty || roleArn == utils.StringEmpty { l.Errorf("oss config missing: accessKeyId/accessKeySecret/roleArn") return failResponse(utils.Fail), nil } if roleSessionName == utils.StringEmpty { roleSessionName = "chore-oss-upload" } if stsEndpoint == utils.StringEmpty { stsEndpoint = "sts.cn-hangzhou.aliyuncs.com" } if bucket == utils.StringEmpty { bucket = "lone-images" } if region == utils.StringEmpty { region = "oss-cn-hangzhou" } if endpoint == utils.StringEmpty { endpoint = "https://lone-images.oss-accelerate.aliyuncs.com" } if host == utils.StringEmpty { host = "https://images.ailuowan.com" } if !strings.HasPrefix(endpoint, "http") { endpoint = "https://" + endpoint } if !strings.HasPrefix(host, "http") { host = "https://" + host } expire := int64(utils.GetConfigInt("oss.expireSeconds")) if expire < 1 { expire = 3600 } client, err := createStsClient(accessKeyId, accessKeySecret, stsEndpoint) if err != nil { l.Errorf("create STS client: %v", err) return failResponse(utils.Fail), nil } assumeRoleRequest := &sts20150401.AssumeRoleRequest{ DurationSeconds: tea.Int64(expire), RoleArn: tea.String(roleArn), RoleSessionName: tea.String(roleSessionName), } resp, err := client.AssumeRoleWithOptions(assumeRoleRequest, &util.RuntimeOptions{}) if err != nil { l.Errorf("AssumeRole: %v", err) return failResponse(utils.Fail), nil } if resp == nil || resp.Body == nil || resp.Body.Credentials == nil { l.Errorf("AssumeRole empty credentials") return failResponse(utils.Fail), nil } cred := resp.Body.Credentials token := StsToken{ AccessKeyId: tea.StringValue(cred.AccessKeyId), AccessKeySecret: tea.StringValue(cred.AccessKeySecret), SecurityToken: tea.StringValue(cred.SecurityToken), Expiration: tea.StringValue(cred.Expiration), Bucket: bucket, Region: region, Endpoint: endpoint, Host: host, Dir: dir, } return okResponse(token), nil } func createStsClient(accessKeyId, accessKeySecret, endpoint string) (*sts20150401.Client, error) { config := &openapi.Config{ AccessKeyId: tea.String(accessKeyId), AccessKeySecret: tea.String(accessKeySecret), Endpoint: tea.String(endpoint), } return sts20150401.NewClient(config) }