241 lines
6.3 KiB
Go
241 lines
6.3 KiB
Go
package dal
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"log"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/minio/minio-go/v7"
|
||
"github.com/minio/minio-go/v7/pkg/policy"
|
||
"github.com/minio/minio-go/v7/pkg/set"
|
||
)
|
||
|
||
// GetResourcesList - получить список ресурсов по указанному пути
|
||
func (mc *MinioClient) GetResourcesList(ctx context.Context, prefix string, recursive, withVersions bool) []minio.ObjectInfo {
|
||
var result []minio.ObjectInfo
|
||
|
||
for obj := range mc.client.ListObjects(ctx, mc.BucketName, minio.ListObjectsOptions{
|
||
WithVersions: withVersions,
|
||
WithMetadata: true,
|
||
Prefix: prefix,
|
||
Recursive: recursive,
|
||
}) {
|
||
result = append(result, obj)
|
||
}
|
||
|
||
return result
|
||
}
|
||
|
||
// PutResources - создать папку
|
||
func (mc *MinioClient) PutResources(ctx context.Context, path string) error {
|
||
if !strings.HasSuffix(path, "/") {
|
||
path += "/"
|
||
}
|
||
_, err := mc.client.PutObject(ctx, mc.BucketName, path, nil, 0, minio.PutObjectOptions{
|
||
ContentType: "application/directory",
|
||
})
|
||
mc.err(err)
|
||
|
||
return err
|
||
}
|
||
|
||
// UploadResources - загрузить файл
|
||
func (mc *MinioClient) UploadResources(ctx context.Context, reader io.Reader, size int64, path,
|
||
contentType string) error {
|
||
_, err := mc.client.PutObject(ctx, mc.BucketName, path, reader, size,
|
||
minio.PutObjectOptions{ContentType: contentType})
|
||
mc.err(err)
|
||
|
||
return err
|
||
}
|
||
|
||
// DownloadResources - получить ссылку на скачивание файла
|
||
func (mc *MinioClient) DownloadResources(ctx context.Context, path string) (string, error) {
|
||
href, err := mc.client.PresignedGetObject(ctx, mc.BucketName, path, time.Minute*30, nil)
|
||
mc.err(err)
|
||
return href.String(), err
|
||
}
|
||
|
||
// CopyResources - скопировать ресурсы
|
||
func (mc *MinioClient) CopyResources(ctx context.Context, src, dst string) error {
|
||
_, err := mc.client.CopyObject(ctx, minio.CopyDestOptions{
|
||
Bucket: mc.BucketName,
|
||
Object: dst,
|
||
ReplaceMetadata: true,
|
||
ReplaceTags: true,
|
||
}, minio.CopySrcOptions{
|
||
Bucket: mc.BucketName,
|
||
Object: src,
|
||
})
|
||
|
||
mc.err(err)
|
||
|
||
return err
|
||
}
|
||
|
||
// MoveResources - переместить ресурс
|
||
func (mc *MinioClient) MoveResources(ctx context.Context, src, dst string) error {
|
||
err := mc.CopyResources(ctx, src, dst)
|
||
|
||
if mc.err(err) {
|
||
return err
|
||
}
|
||
|
||
err = mc.DeleteResources(ctx, src, true)
|
||
mc.err(err)
|
||
|
||
return err
|
||
}
|
||
|
||
// DeleteResources - удалить ресурс.
|
||
func (mc *MinioClient) DeleteResources(ctx context.Context, name string, force bool) error {
|
||
if strings.HasSuffix(name, "/") {
|
||
listChan := mc.client.ListObjects(ctx, mc.BucketName, minio.ListObjectsOptions{
|
||
WithVersions: false,
|
||
WithMetadata: false,
|
||
Prefix: name,
|
||
Recursive: true,
|
||
})
|
||
mc.client.RemoveObjects(ctx, mc.BucketName, listChan, minio.RemoveObjectsOptions{})
|
||
}
|
||
|
||
err := mc.client.RemoveObject(ctx, mc.BucketName, name, minio.RemoveObjectOptions{
|
||
ForceDelete: force,
|
||
})
|
||
mc.err(err)
|
||
|
||
return err
|
||
}
|
||
|
||
// PublishResources - опубликовать ресурс. Возвращает публичную ссылку на ресурс.
|
||
//
|
||
// Ссылка на папку не будет работать. Будет получена ошибка: NoSuchKey: The specified key does not exist.
|
||
func (mc *MinioClient) PublishResources(ctx context.Context, path string) (string, error) {
|
||
curPolicy, err := mc.client.GetBucketPolicy(ctx, mc.BucketName)
|
||
if mc.err(err) {
|
||
return "", err
|
||
}
|
||
|
||
var p policy.BucketAccessPolicy
|
||
|
||
if curPolicy == "" {
|
||
policyConsoleStatement := policy.Statement{
|
||
Actions: set.CreateStringSet("*"),
|
||
Conditions: policy.ConditionMap{
|
||
"StringLike": policy.ConditionKeyMap{
|
||
"aws:referer": set.CreateStringSet(fmt.Sprintf("https://console.cloud.yandex.*/folders/*/storage/buckets/%s*", mc.BucketName)),
|
||
},
|
||
},
|
||
Effect: "Allow",
|
||
Principal: policy.User{AWS: set.CreateStringSet("*")},
|
||
Resources: set.CreateStringSet(fmt.Sprintf("arn:aws:s3:::%s/*", mc.BucketName),
|
||
fmt.Sprintf("arn:aws:s3:::%s", mc.BucketName)),
|
||
Sid: "console-statement",
|
||
}
|
||
|
||
policyServiceAccount := policy.Statement{
|
||
Actions: set.CreateStringSet("*"),
|
||
Conditions: nil,
|
||
Effect: "Allow",
|
||
Principal: policy.User{CanonicalUser: set.CreateStringSet("ajelmc4tjbct675tjdh9")},
|
||
Resources: set.CreateStringSet(fmt.Sprintf("arn:aws:s3:::%s/*", mc.BucketName),
|
||
fmt.Sprintf("arn:aws:s3:::%s", mc.BucketName)),
|
||
Sid: "service-account-statement",
|
||
}
|
||
|
||
p = policy.BucketAccessPolicy{Version: "2012-10-17", Statements: []policy.Statement{
|
||
policyConsoleStatement,
|
||
policyServiceAccount,
|
||
}}
|
||
} else {
|
||
err = json.Unmarshal([]byte(curPolicy), &p)
|
||
if mc.err(err) {
|
||
return "", err
|
||
}
|
||
}
|
||
|
||
p.Statements = policy.SetPolicy(p.Statements, policy.BucketPolicyReadOnly, mc.BucketName, path)
|
||
|
||
out, err := json.Marshal(&p)
|
||
if mc.err(err) {
|
||
return "", err
|
||
}
|
||
|
||
err = mc.client.SetBucketPolicy(ctx, mc.BucketName, string(out))
|
||
mc.err(err)
|
||
|
||
if !strings.HasPrefix(path, "/") {
|
||
path = "/" + path
|
||
}
|
||
|
||
href := fmt.Sprintf("%v/%v%v", mc.client.EndpointURL().String(), mc.BucketName, path)
|
||
|
||
return href, err
|
||
}
|
||
|
||
// UnpublishResources - отменить публикацию ресурса
|
||
func (mc *MinioClient) UnpublishResources(ctx context.Context, path string) error {
|
||
curPolicy, err := mc.client.GetBucketPolicy(ctx, mc.BucketName)
|
||
if mc.err(err) {
|
||
return err
|
||
}
|
||
|
||
var p policy.BucketAccessPolicy
|
||
|
||
err = json.Unmarshal([]byte(curPolicy), &p)
|
||
if mc.err(err) {
|
||
return err
|
||
}
|
||
|
||
p.Statements = policy.SetPolicy(p.Statements, policy.BucketPolicyNone, mc.BucketName, path)
|
||
|
||
out, err := json.Marshal(&p)
|
||
if mc.err(err) {
|
||
return err
|
||
}
|
||
|
||
err = mc.client.SetBucketPolicy(ctx, mc.BucketName, string(out))
|
||
mc.err(err)
|
||
|
||
return err
|
||
}
|
||
|
||
func (mc *MinioClient) GetPublicResources(ctx context.Context) ([]string, error) {
|
||
curPolicy, err := mc.client.GetBucketPolicy(ctx, mc.BucketName)
|
||
|
||
log.Println(curPolicy)
|
||
|
||
if mc.err(err) {
|
||
return nil, err
|
||
}
|
||
|
||
var p policy.BucketAccessPolicy
|
||
|
||
if curPolicy == "" {
|
||
return nil, nil
|
||
}
|
||
|
||
err = json.Unmarshal([]byte(curPolicy), &p)
|
||
if mc.err(err) {
|
||
return nil, err
|
||
}
|
||
|
||
policies := policy.GetPolicies(p.Statements, mc.BucketName, "")
|
||
|
||
var result []string
|
||
|
||
for k, v := range policies {
|
||
if v == policy.BucketPolicyReadOnly {
|
||
k = strings.TrimPrefix(k, mc.BucketName+"/")
|
||
k = strings.TrimSuffix(k, "*")
|
||
result = append(result, k)
|
||
}
|
||
}
|
||
|
||
return result, nil
|
||
}
|