1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package s3
- import (
- "context"
- "io"
- "time"
- "github.com/aws/aws-sdk-go-v2/aws"
- "github.com/aws/aws-sdk-go-v2/config"
- "github.com/aws/aws-sdk-go-v2/credentials"
- "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
- "github.com/aws/aws-sdk-go-v2/service/s3"
- "github.com/pkg/errors"
- storepb "github.com/usememos/memos/proto/gen/store"
- )
- type Client struct {
- Client *s3.Client
- Bucket *string
- }
- func NewClient(ctx context.Context, s3Config *storepb.StorageS3Config) (*Client, error) {
- cfg, err := config.LoadDefaultConfig(ctx,
- config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(s3Config.AccessKeyId, s3Config.AccessKeySecret, "")),
- config.WithRegion(s3Config.Region),
- )
- if err != nil {
- return nil, errors.Wrap(err, "failed to load s3 config")
- }
- client := s3.NewFromConfig(cfg, func(o *s3.Options) {
- o.BaseEndpoint = aws.String(s3Config.Endpoint)
- })
- return &Client{
- Client: client,
- Bucket: aws.String(s3Config.Bucket),
- }, nil
- }
- // UploadObject uploads an object to S3.
- func (c *Client) UploadObject(ctx context.Context, key string, fileType string, content io.Reader) (string, error) {
- uploader := manager.NewUploader(c.Client)
- putInput := s3.PutObjectInput{
- Bucket: c.Bucket,
- Key: aws.String(key),
- ContentType: aws.String(fileType),
- Body: content,
- }
- result, err := uploader.Upload(ctx, &putInput)
- if err != nil {
- return "", err
- }
- resultKey := result.Key
- if resultKey == nil || *resultKey == "" {
- return "", errors.New("failed to get file key")
- }
- return *resultKey, nil
- }
- // PresignGetObject presigns an object in S3.
- func (c *Client) PresignGetObject(ctx context.Context, key string) (string, error) {
- presignClient := s3.NewPresignClient(c.Client)
- presignResult, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{
- Bucket: aws.String(*c.Bucket),
- Key: aws.String(key),
- }, func(opts *s3.PresignOptions) {
- // Set the expiration time of the presigned URL to 5 days.
- // Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
- opts.Expires = time.Duration(5 * 24 * time.Hour)
- })
- if err != nil {
- return "", errors.Wrap(err, "failed to presign put object")
- }
- return presignResult.URL, nil
- }
- // DeleteObject deletes an object in S3.
- func (c *Client) DeleteObject(ctx context.Context, key string) error {
- _, err := c.Client.DeleteObject(ctx, &s3.DeleteObjectInput{
- Bucket: c.Bucket,
- Key: aws.String(key),
- })
- if err != nil {
- return errors.Wrap(err, "failed to delete object")
- }
- return nil
- }
|