Files
onepanel/server/file_server.go
Andrey Melnikov 7235951ec2 chore: codacy docs
2021-08-02 15:08:09 -07:00

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
}