package tkoss import ( "bufio" "bytes" "fmt" "io" "sandc/pkg/ali" openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" sts20150401 "github.com/alibabacloud-go/sts-20150401/v2/client" "github.com/aliyun/aliyun-oss-go-sdk/oss" ) type StsCredentials struct { RegionId string Bucket string AccessKeyId string AccessKeySecret string Expiration string SecurityToken string } // 定义sts属性 type stsOption struct { policy string roleArn string roleSessionName string } var stsOp = &stsOption{ roleArn: "acs:ram::1280524430176126:role/toukaossram", roleSessionName: "touka_external", policy: `{"Version": "1", "Statement": [{"Action": ["oss:PutObject","oss:GetObject"], "Effect": "Allow", "Resource": ["acs:oss:*:*:toukadc-sg/*"]}]}`, } type Client struct { oss *oss.Client sts *sts20150401.Client stsOption *stsOption regionId string bucket string } func NewClient(accessKeyID, accessKeySecret, regionId, bucket string, options ...oss.ClientOption) (*Client, error) { client, err := oss.New(ali.GetOssEndpointByRegionId(regionId), accessKeyID, accessKeySecret, options...) if err != nil { return nil, fmt.Errorf("init ossclient failed: %w", err) } stsClient, err := sts20150401.NewClient(&openapi.Config{ AccessKeyId: ali.String(accessKeyID), AccessKeySecret: ali.String(accessKeySecret), Endpoint: ali.String(ali.GetStsEndpointByRegionId(regionId)), }) if err != nil { return nil, fmt.Errorf("init sts client failed: %w", err) } return &Client{ oss: client, sts: stsClient, regionId: regionId, bucket: bucket, stsOption: stsOp, }, nil } // UplaodFile 上传文件 func (c *Client) UplaodFile(objectKey, filePath string) error { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return err } // 用于服务端上传文件。 return bucket.PutObjectFromFile(objectKey, filePath) } // UploadByte 上传文件 func (c *Client) UploadByte(objectKey string, data []byte) error { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return err } // 用于服务端上传文件。 return bucket.PutObject(objectKey, bytes.NewReader(data)) } // GenerateSignedUrl 生成临时签名URL func (c *Client) GenerateSignedUrl(objectKey string, expiredInSec int64) (string, error) { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return "", nil } return bucket.SignURL(objectKey, oss.HTTPGet, expiredInSec) } // GetObject 获取文件内容 func (c *Client) GetObject(objectKey string) (io.ReadCloser, error) { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return nil, err } return bucket.GetObject(objectKey) } // GetObjectByte 获取文件byte内容 func (c *Client) GetObjectByte(objectKey string) ([]byte, error) { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return nil, err } reader, err := bucket.GetObject(objectKey) if err != nil { return nil, fmt.Errorf("reader: %w", err) } newReader := bufio.NewReader(reader) body := make([]byte, 0) for { data, err := newReader.ReadBytes('\n') if err == io.EOF { body = append(body, data...) break } if err != nil { return nil, err } body = append(body, data...) } return body, nil } // ListObjectsV2 列举文件 func (c *Client) ListObjectsV2(prefix string) ([]string, error) { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return nil, err } res, err := bucket.ListObjectsV2(oss.Prefix(prefix)) if err != nil { return nil, err } var objectKeys []string for _, object := range res.Objects { objectKeys = append(objectKeys, object.Key) } return objectKeys, nil } // UploadFileBySignedUrl 生成签名URL并通过签名URL上传文件 func (c *Client) UploadFileBySignedUrl(objectKey, filePath string, expiredInSec int64) (string, error) { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return "", err } signedURL, err := bucket.SignURL(objectKey, oss.HTTPPut, expiredInSec) if err != nil { return "", err } err = bucket.PutObjectFromFileWithURL(signedURL, filePath) if err != nil { return "", err } return c.GenerateSignedUrl(objectKey, expiredInSec) } // UploadObjectBySignedUrl 通过签名URL上传文件 func (c *Client) UploadObjectBySignedUrl(objectKey string, file []byte, expiredInSec int64) (string, error) { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return "", err } signedURL, err := bucket.SignURL(objectKey, oss.HTTPPut, expiredInSec) if err != nil { return "", err } // filename := os.GetFileName(objectKey) // 没必要,保留oss默认的objectKey // err = bucket.PutObjectWithURL(signedURL, bytes.NewReader(file), oss.ContentDisposition("attachment;filename="+objectKey)) err = bucket.PutObjectWithURL(signedURL, bytes.NewReader(file)) if err != nil { return "", err } return c.GenerateSignedUrl(objectKey, expiredInSec) } // CopyObject 复制文件 func (c *Client) CopyObject(srcObjectKey, destObjectKey string) error { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return err } _, err = bucket.CopyObject(srcObjectKey, destObjectKey) if err != nil { return err } return nil } // GenerateStsCredentials 生成临时凭证 func (c *Client) GenerateStsCredentials() (*StsCredentials, error) { assumeRoleRequest := &sts20150401.AssumeRoleRequest{ RoleArn: ali.String(c.stsOption.roleArn), RoleSessionName: ali.String(c.stsOption.roleSessionName), Policy: ali.String(c.stsOption.policy), DurationSeconds: ali.Int64(3600), //默认设置1个小时 } res, err := c.sts.AssumeRole(assumeRoleRequest) if err != nil { return nil, err } return &StsCredentials{ RegionId: fmt.Sprintf("oss-%s", c.regionId), Bucket: c.bucket, AccessKeyId: ali.StringValue(res.Body.Credentials.AccessKeyId), AccessKeySecret: ali.StringValue(res.Body.Credentials.AccessKeySecret), Expiration: ali.StringValue(res.Body.Credentials.Expiration), SecurityToken: ali.StringValue(res.Body.Credentials.SecurityToken), }, nil } // DeleteObject 删除文件 func (c *Client) DeleteObject(objectKey string) error { bucket, err := c.oss.Bucket(c.bucket) if err != nil { return err } return bucket.DeleteObject(objectKey) }