package s3 import ( "context" "fmt" "time" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "github.com/chaitin/panda-wiki/config" "github.com/chaitin/panda-wiki/domain" ) type MinioClient struct { *minio.Client config *config.Config } func NewMinioClient(config *config.Config) (*MinioClient, error) { endpoint := config.S3.Endpoint accessKey := config.S3.AccessKey secretKey := config.S3.SecretKey minioClient, err := minio.New(endpoint, &minio.Options{ Creds: credentials.NewStaticV4(accessKey, secretKey, ""), Secure: false, }) if err != nil { return nil, err } // check bucket bucket := domain.Bucket exists, err := minioClient.BucketExists(context.Background(), bucket) if err != nil { return nil, err } if !exists { err = minioClient.MakeBucket(context.Background(), bucket, minio.MakeBucketOptions{ Region: "us-east-1", }) if err != nil { return nil, fmt.Errorf("make bucket: %w", err) } err = minioClient.SetBucketPolicy(context.Background(), bucket, `{ "Version": "2012-10-17", "Statement": [ { "Action": ["s3:GetObject"], "Effect": "Allow", "Principal": "*", "Resource": ["arn:aws:s3:::static-file/*"], "Sid": "PublicRead" } ] }`) if err != nil { return nil, fmt.Errorf("set bucket policy: %w", err) } } return &MinioClient{Client: minioClient, config: config}, nil } // sign url func (c *MinioClient) SignURL(ctx context.Context, bucket, object string, expires time.Duration) (string, error) { url, err := c.PresignedGetObject(ctx, bucket, object, expires, nil) if err != nil { return "", err } return url.String(), nil }