merge master

This commit is contained in:
Michael Barz
2022-01-19 12:30:23 +01:00
parent 6b8a9f9127
commit 4d4dca512b
2 changed files with 32 additions and 129 deletions

View File

@@ -7,7 +7,6 @@ import (
"math"
"net/http"
"net/url"
"path"
"path/filepath"
"strconv"
"strings"
@@ -56,7 +55,7 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending list storage spaces grpc request")
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
@@ -66,7 +65,7 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, &listResponse{})
return
}
g.logger.Error().Err(err).Msg("error sending list storage spaces grpc request")
g.logger.Error().Err(err).Msg(ListStorageSpacesReturnsErr)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
@@ -90,42 +89,42 @@ func (g Graph) GetDrives(w http.ResponseWriter, r *http.Request) {
// GetSingleDrive does a lookup of a single space by spaceId
func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
driveId := chi.URLParam(r, "driveID")
if driveId == "" {
driveID := chi.URLParam(r, "driveID")
if driveID == "" {
err := fmt.Errorf("no valid space id retrieved")
g.logger.Err(err)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
g.logger.Info().Str("driveID", driveId).Msg("Calling GetSingleDrive")
g.logger.Info().Str("driveID", driveID).Msg("Calling GetSingleDrive")
ctx := r.Context()
var filters []*storageprovider.ListStorageSpacesRequest_Filter
filterDriveId := &storageprovider.ListStorageSpacesRequest_Filter{
filterDriveID := &storageprovider.ListStorageSpacesRequest_Filter{
Type: storageprovider.ListStorageSpacesRequest_Filter_TYPE_ID,
Term: &storageprovider.ListStorageSpacesRequest_Filter_Id{
Id: &storageprovider.StorageSpaceId{
OpaqueId: driveId,
OpaqueId: driveID,
},
},
}
filters = append(filters, filterDriveId)
filters = append(filters, filterDriveID)
res, err := g.ListStorageSpacesWithFilters(ctx, filters)
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending list storage spaces grpc request")
g.logger.Error().Err(err).Msg(ListStorageSpacesTransportErr)
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
// the client is doing a lookup for a specific space, therefore we need to return
// not found to the caller
g.logger.Error().Str("driveId", driveId).Msg(fmt.Sprintf("space with id `%s` not found", driveId))
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf("space with id `%s` not found", driveId))
g.logger.Error().Str("driveID", driveID).Msg(fmt.Sprintf(NoSpaceFoundMessage, driveID))
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf(NoSpaceFoundMessage, driveID))
return
}
g.logger.Error().Err(err).Msg("error sending list storage spaces grpc request")
g.logger.Error().Err(err).Msg(ListStorageSpacesReturnsErr)
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
@@ -144,8 +143,8 @@ func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
}
switch num := len(spaces); {
case num == 0:
g.logger.Error().Str("driveId", driveId).Msg("no space found")
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf("space with id `%s` not found", driveId))
g.logger.Error().Str("driveID", driveID).Msg("no space found")
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, fmt.Sprintf(NoSpaceFoundMessage, driveID))
return
case num == 1:
render.Status(r, http.StatusOK)
@@ -157,70 +156,6 @@ func (g Graph) GetSingleDrive(w http.ResponseWriter, r *http.Request) {
}
}
// GetRootDriveChildren implements the Service interface.
func (g Graph) GetRootDriveChildren(w http.ResponseWriter, r *http.Request) {
g.logger.Info().Msg("Calling GetRootDriveChildren")
ctx := r.Context()
client, err := g.GetClient()
if err != nil {
g.logger.Error().Err(err).Msg("could not get client")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
res, err := client.GetHome(ctx, &storageprovider.GetHomeRequest{})
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending get home grpc request")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, res.Status.Message)
return
}
g.logger.Error().Err(err).Msg("error sending get home grpc request")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
lRes, err := client.ListContainer(ctx, &storageprovider.ListContainerRequest{
Ref: &storageprovider.Reference{
Path: res.Path,
},
})
switch {
case err != nil:
g.logger.Error().Err(err).Msg("error sending list container grpc request")
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
return
case res.Status.Code != cs3rpc.Code_CODE_OK:
if res.Status.Code == cs3rpc.Code_CODE_NOT_FOUND {
errorcode.ItemNotFound.Render(w, r, http.StatusNotFound, res.Status.Message)
return
}
if res.Status.Code == cs3rpc.Code_CODE_PERMISSION_DENIED {
// TODO check if we should return 404 to not disclose existing items
errorcode.AccessDenied.Render(w, r, http.StatusForbidden, res.Status.Message)
return
}
g.logger.Error().Err(err).Msg("error sending list container grpc request")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, res.Status.Message)
return
}
files, err := formatDriveItems(lRes.Infos)
if err != nil {
g.logger.Error().Err(err).Msg("error encoding response as json")
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error())
return
}
render.Status(r, http.StatusOK)
render.JSON(w, r, &listResponse{Value: files})
}
// CreateDrive creates a storage drive (space).
func (g Graph) CreateDrive(w http.ResponseWriter, r *http.Request) {
us, ok := ctxpkg.ContextGetUser(r.Context())
@@ -439,18 +374,23 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, mds []*storag
}
// TODO this overwrites the quota that might already have been mapped in cs3StorageSpaceToDrive above ... move this into the cs3StorageSpaceToDrive method?
res.Quota, err = g.getDriveQuota(ctx, space)
if err != nil {
return nil, err
}
responses = append(responses, res)
}
return responses, nil
}
// ListStorageSpacesWithFilters List Storage Spaces using filters
func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter) (*storageprovider.ListStorageSpacesResponse, error) {
client, err := g.GetClient()
if err != nil {
g.logger.Err(err).Msg("error getting grpc client")
return nil, err
}
client := g.GetGatewayClient()
permissions := make(map[string]struct{}, 1)
s := sproto.NewPermissionService("com.owncloud.api.settings", grpc.DefaultClient)
_, err = s.GetPermissionByID(ctx, &sproto.GetPermissionByIDRequest{
_, err := s.GetPermissionByID(ctx, &sproto.GetPermissionByIDRequest{
PermissionId: settingsSvc.ListAllSpacesPermissionID,
})
@@ -472,50 +412,7 @@ func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*stor
}},
Filters: filters,
})
return res, nil
}
func cs3TimestampToTime(t *types.Timestamp) time.Time {
return time.Unix(int64(t.Seconds), int64(t.Nanos))
}
func cs3ResourceToDriveItem(res *storageprovider.ResourceInfo) (*libregraph.DriveItem, error) {
size := new(int64)
*size = int64(res.Size) // uint64 -> int :boom:
name := path.Base(res.Path)
driveItem := &libregraph.DriveItem{
Id: &res.Id.OpaqueId,
Name: &name,
ETag: &res.Etag,
Size: size,
}
if res.Mtime != nil {
lastModified := cs3TimestampToTime(res.Mtime)
driveItem.LastModifiedDateTime = &lastModified
}
if res.Type == storageprovider.ResourceType_RESOURCE_TYPE_FILE {
driveItem.File = &libregraph.OpenGraphFile{ // FIXME We cannot use libregraph.File here because the openapi codegenerator autodetects 'File' as a go type ...
MimeType: &res.MimeType,
}
}
if res.Type == storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER {
driveItem.Folder = &libregraph.Folder{}
}
return driveItem, nil
}
func formatDriveItems(mds []*storageprovider.ResourceInfo) ([]*libregraph.DriveItem, error) {
responses := make([]*libregraph.DriveItem, 0, len(mds))
for i := range mds {
res, err := cs3ResourceToDriveItem(mds[i])
if err != nil {
return nil, err
}
responses = append(responses, res)
}
return responses, nil
return res, err
}
func cs3StorageSpaceToDrive(baseURL *url.URL, space *storageprovider.StorageSpace) (*libregraph.Drive, error) {

View File

@@ -85,3 +85,9 @@ func (g Graph) GetHTTPClient() HTTPClient {
type listResponse struct {
Value interface{} `json:"value,omitempty"`
}
const (
NoSpaceFoundMessage = "space with id `%s` not found"
ListStorageSpacesTransportErr = "transport error sending list storage spaces grpc request"
ListStorageSpacesReturnsErr = "list storage spaces grpc request returns an errorcode in the response"
)