mirror of
https://github.com/onepanelio/onepanel.git
synced 2025-09-27 01:56:03 +08:00
118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
api "github.com/onepanelio/core/api/gen"
|
|
v1 "github.com/onepanelio/core/pkg"
|
|
"github.com/onepanelio/core/server/auth"
|
|
"math"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// FileServer is an implementation of the grpc WorkflowServer
|
|
type FileServer struct {
|
|
api.UnimplementedFileServiceServer
|
|
}
|
|
|
|
// NewFileServer creates a new FileServer
|
|
func NewFileServer() *FileServer {
|
|
return &FileServer{}
|
|
}
|
|
|
|
// ListFiles returns a list of files from the configured cloud storage
|
|
// Directories come first, and then it is sorted alphabetically
|
|
func (s *FileServer) ListFiles(ctx context.Context, req *api.ListFilesRequest) (*api.ListFilesResponse, error) {
|
|
// TODO resource is workflows for now, should it be something else?
|
|
client := getClient(ctx)
|
|
allowed, err := auth.IsAuthorized(client, req.Namespace, "list", "argoproj.io", "workflows", "")
|
|
if err != nil || !allowed {
|
|
return nil, err
|
|
}
|
|
|
|
if req.Page < 0 {
|
|
req.Page = 1
|
|
}
|
|
if req.PerPage <= 0 {
|
|
req.PerPage = 15
|
|
}
|
|
|
|
files, err := client.ListFiles(req.Namespace, req.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
apiFiles := make([]*api.File, len(files))
|
|
for i, file := range files {
|
|
apiFiles[i] = &api.File{
|
|
Path: file.Path,
|
|
Name: file.Name,
|
|
Extension: file.Extension,
|
|
Directory: file.Directory,
|
|
Size: file.Size,
|
|
ContentType: file.ContentType,
|
|
LastModified: file.LastModified.UTC().Format(time.RFC3339),
|
|
}
|
|
}
|
|
|
|
sort.SliceStable(apiFiles, func(i, j int) bool {
|
|
lhFile := apiFiles[i]
|
|
rhFile := apiFiles[j]
|
|
|
|
if (lhFile.Directory && rhFile.Directory) ||
|
|
(!lhFile.Directory && !rhFile.Directory) {
|
|
return strings.Compare(strings.ToLower(lhFile.Name), strings.ToLower(rhFile.Name)) < 0
|
|
}
|
|
|
|
if lhFile.Directory {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
})
|
|
|
|
start := (req.Page - 1) * req.PerPage
|
|
if start < 0 {
|
|
start = 0
|
|
}
|
|
|
|
end := int(start + req.PerPage)
|
|
if end > len(apiFiles) {
|
|
end = len(apiFiles)
|
|
}
|
|
parts := apiFiles[start:end]
|
|
|
|
count := len(parts)
|
|
totalCount := len(apiFiles)
|
|
|
|
return &api.ListFilesResponse{
|
|
Count: int32(count),
|
|
Page: req.Page,
|
|
Pages: int32(math.Ceil(float64(totalCount) / float64(req.PerPage))),
|
|
TotalCount: int32(totalCount),
|
|
Files: parts,
|
|
ParentPath: v1.FilePathToParentPath(req.Path),
|
|
}, nil
|
|
}
|
|
|
|
// GetObjectDownloadPresignedURL returns a downloadable url for a given object
|
|
func (s *FileServer) GetObjectDownloadPresignedURL(ctx context.Context, req *api.GetObjectPresignedUrlRequest) (*api.GetPresignedUrlResponse, error) {
|
|
// TODO resource is workflows for now, should it be something else?
|
|
client := getClient(ctx)
|
|
allowed, err := auth.IsAuthorized(client, req.Namespace, "list", "argoproj.io", "workflows", "")
|
|
if err != nil || !allowed {
|
|
return nil, err
|
|
}
|
|
|
|
downloadObj, err := client.GetObjectPresignedURL(req.Namespace, req.Key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &api.GetPresignedUrlResponse{
|
|
Url: downloadObj.URL,
|
|
Size: downloadObj.Size,
|
|
}, nil
|
|
}
|