package logic import ( "context" "strings" "time" "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 Credentials,并附带前端上传所需信息 type StsToken struct { AccessKeyId string `json:"access_key_id"` AccessKeySecret string `json:"access_key_secret"` SecurityToken string `json:"security_token"` 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 formatExpiration(raw string) string { if raw == "" { return raw } t, err := time.Parse(time.RFC3339, raw) if err != nil { return raw } return t.Local().Format(utils.YMDHIS) } func NewPolicyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PolicyLogic { return &PolicyLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func CreateClient(accessKeyId, accessKeySecret, endpoint *string) (*sts20150401.Client, error) { config := &openapi.Config{ AccessKeyId: accessKeyId, AccessKeySecret: accessKeySecret, } config.Endpoint = endpoint return sts20150401.NewClient(config) } func AssumeRole(client *sts20150401.Client, roleArn, roleSessionName string, durationSeconds int64) (*sts20150401.AssumeRoleResponse, error) { assumeRoleRequest := &sts20150401.AssumeRoleRequest{ DurationSeconds: tea.Int64(durationSeconds), RoleArn: tea.String(roleArn), RoleSessionName: tea.String(roleSessionName), } return client.AssumeRoleWithOptions(assumeRoleRequest, &util.RuntimeOptions{}) } 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 := CreateClient(tea.String(accessKeyId), tea.String(accessKeySecret), tea.String(stsEndpoint)) if err != nil { l.Errorf("create STS client: %v", err) return failResponse(utils.Fail), nil } resp, err := AssumeRole(client, roleArn, roleSessionName, expire) 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: formatExpiration(tea.StringValue(cred.Expiration)), Bucket: bucket, Region: region, Endpoint: endpoint, Host: host, Dir: dir, } return okResponse(token), nil }