feat(graph): add more /<driveid>/root/ endpoints

This add support for the following graph routes:

POST /drives/{driveID}/root/createLink
DELETE /drives/{driveID}/root/permissions/{permissionID}
PATCH /drives/{driveID}/root/permissions/{permissionID}
and
POST /drives/{driveID}/root/permissions/{permissionID}/setPassword

This should significantly improve handling of permissions on spaces
as there is no need to figure to the drive's root itemid anymore.

Partial Fix: #8351
This commit is contained in:
Ralf Haferkamp
2024-03-27 20:26:48 +01:00
committed by Ralf Haferkamp
parent 2d643219e3
commit 62dc3f4858
4 changed files with 438 additions and 1 deletions

View File

@@ -82,6 +82,64 @@ func (_c *DriveItemPermissionsProvider_CreateLink_Call) RunAndReturn(run func(co
return _c
}
// CreateSpaceRootLink provides a mock function with given fields: ctx, driveID, createLink
func (_m *DriveItemPermissionsProvider) CreateSpaceRootLink(ctx context.Context, driveID providerv1beta1.ResourceId, createLink libregraph.DriveItemCreateLink) (libregraph.Permission, error) {
ret := _m.Called(ctx, driveID, createLink)
if len(ret) == 0 {
panic("no return value specified for CreateSpaceRootLink")
}
var r0 libregraph.Permission
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, libregraph.DriveItemCreateLink) (libregraph.Permission, error)); ok {
return rf(ctx, driveID, createLink)
}
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, libregraph.DriveItemCreateLink) libregraph.Permission); ok {
r0 = rf(ctx, driveID, createLink)
} else {
r0 = ret.Get(0).(libregraph.Permission)
}
if rf, ok := ret.Get(1).(func(context.Context, providerv1beta1.ResourceId, libregraph.DriveItemCreateLink) error); ok {
r1 = rf(ctx, driveID, createLink)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DriveItemPermissionsProvider_CreateSpaceRootLink_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateSpaceRootLink'
type DriveItemPermissionsProvider_CreateSpaceRootLink_Call struct {
*mock.Call
}
// CreateSpaceRootLink is a helper method to define mock.On call
// - ctx context.Context
// - driveID providerv1beta1.ResourceId
// - createLink libregraph.DriveItemCreateLink
func (_e *DriveItemPermissionsProvider_Expecter) CreateSpaceRootLink(ctx interface{}, driveID interface{}, createLink interface{}) *DriveItemPermissionsProvider_CreateSpaceRootLink_Call {
return &DriveItemPermissionsProvider_CreateSpaceRootLink_Call{Call: _e.mock.On("CreateSpaceRootLink", ctx, driveID, createLink)}
}
func (_c *DriveItemPermissionsProvider_CreateSpaceRootLink_Call) Run(run func(ctx context.Context, driveID providerv1beta1.ResourceId, createLink libregraph.DriveItemCreateLink)) *DriveItemPermissionsProvider_CreateSpaceRootLink_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(providerv1beta1.ResourceId), args[2].(libregraph.DriveItemCreateLink))
})
return _c
}
func (_c *DriveItemPermissionsProvider_CreateSpaceRootLink_Call) Return(_a0 libregraph.Permission, _a1 error) *DriveItemPermissionsProvider_CreateSpaceRootLink_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *DriveItemPermissionsProvider_CreateSpaceRootLink_Call) RunAndReturn(run func(context.Context, providerv1beta1.ResourceId, libregraph.DriveItemCreateLink) (libregraph.Permission, error)) *DriveItemPermissionsProvider_CreateSpaceRootLink_Call {
_c.Call.Return(run)
return _c
}
// DeletePermission provides a mock function with given fields: ctx, itemID, permissionID
func (_m *DriveItemPermissionsProvider) DeletePermission(ctx context.Context, itemID providerv1beta1.ResourceId, permissionID string) error {
ret := _m.Called(ctx, itemID, permissionID)
@@ -130,6 +188,54 @@ func (_c *DriveItemPermissionsProvider_DeletePermission_Call) RunAndReturn(run f
return _c
}
// DeleteSpaceRootPermission provides a mock function with given fields: ctx, driveID, permissionID
func (_m *DriveItemPermissionsProvider) DeleteSpaceRootPermission(ctx context.Context, driveID providerv1beta1.ResourceId, permissionID string) error {
ret := _m.Called(ctx, driveID, permissionID)
if len(ret) == 0 {
panic("no return value specified for DeleteSpaceRootPermission")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, string) error); ok {
r0 = rf(ctx, driveID, permissionID)
} else {
r0 = ret.Error(0)
}
return r0
}
// DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteSpaceRootPermission'
type DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call struct {
*mock.Call
}
// DeleteSpaceRootPermission is a helper method to define mock.On call
// - ctx context.Context
// - driveID providerv1beta1.ResourceId
// - permissionID string
func (_e *DriveItemPermissionsProvider_Expecter) DeleteSpaceRootPermission(ctx interface{}, driveID interface{}, permissionID interface{}) *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call {
return &DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call{Call: _e.mock.On("DeleteSpaceRootPermission", ctx, driveID, permissionID)}
}
func (_c *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call) Run(run func(ctx context.Context, driveID providerv1beta1.ResourceId, permissionID string)) *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(providerv1beta1.ResourceId), args[2].(string))
})
return _c
}
func (_c *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call) Return(_a0 error) *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call) RunAndReturn(run func(context.Context, providerv1beta1.ResourceId, string) error) *DriveItemPermissionsProvider_DeleteSpaceRootPermission_Call {
_c.Call.Return(run)
return _c
}
// Invite provides a mock function with given fields: ctx, resourceId, invite
func (_m *DriveItemPermissionsProvider) Invite(ctx context.Context, resourceId providerv1beta1.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) {
ret := _m.Called(ctx, resourceId, invite)
@@ -361,6 +467,65 @@ func (_c *DriveItemPermissionsProvider_SetPublicLinkPassword_Call) RunAndReturn(
return _c
}
// SetPublicLinkPasswordOnSpaceRoot provides a mock function with given fields: ctx, driveID, permissionID, password
func (_m *DriveItemPermissionsProvider) SetPublicLinkPasswordOnSpaceRoot(ctx context.Context, driveID providerv1beta1.ResourceId, permissionID string, password string) (libregraph.Permission, error) {
ret := _m.Called(ctx, driveID, permissionID, password)
if len(ret) == 0 {
panic("no return value specified for SetPublicLinkPasswordOnSpaceRoot")
}
var r0 libregraph.Permission
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, string, string) (libregraph.Permission, error)); ok {
return rf(ctx, driveID, permissionID, password)
}
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, string, string) libregraph.Permission); ok {
r0 = rf(ctx, driveID, permissionID, password)
} else {
r0 = ret.Get(0).(libregraph.Permission)
}
if rf, ok := ret.Get(1).(func(context.Context, providerv1beta1.ResourceId, string, string) error); ok {
r1 = rf(ctx, driveID, permissionID, password)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPublicLinkPasswordOnSpaceRoot'
type DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call struct {
*mock.Call
}
// SetPublicLinkPasswordOnSpaceRoot is a helper method to define mock.On call
// - ctx context.Context
// - driveID providerv1beta1.ResourceId
// - permissionID string
// - password string
func (_e *DriveItemPermissionsProvider_Expecter) SetPublicLinkPasswordOnSpaceRoot(ctx interface{}, driveID interface{}, permissionID interface{}, password interface{}) *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call {
return &DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call{Call: _e.mock.On("SetPublicLinkPasswordOnSpaceRoot", ctx, driveID, permissionID, password)}
}
func (_c *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call) Run(run func(ctx context.Context, driveID providerv1beta1.ResourceId, permissionID string, password string)) *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(providerv1beta1.ResourceId), args[2].(string), args[3].(string))
})
return _c
}
func (_c *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call) Return(_a0 libregraph.Permission, _a1 error) *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call) RunAndReturn(run func(context.Context, providerv1beta1.ResourceId, string, string) (libregraph.Permission, error)) *DriveItemPermissionsProvider_SetPublicLinkPasswordOnSpaceRoot_Call {
_c.Call.Return(run)
return _c
}
// SpaceRootInvite provides a mock function with given fields: ctx, driveID, invite
func (_m *DriveItemPermissionsProvider) SpaceRootInvite(ctx context.Context, driveID providerv1beta1.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) {
ret := _m.Called(ctx, driveID, invite)
@@ -478,6 +643,65 @@ func (_c *DriveItemPermissionsProvider_UpdatePermission_Call) RunAndReturn(run f
return _c
}
// UpdateSpaceRootPermission provides a mock function with given fields: ctx, driveID, permissionID, newPermission
func (_m *DriveItemPermissionsProvider) UpdateSpaceRootPermission(ctx context.Context, driveID providerv1beta1.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error) {
ret := _m.Called(ctx, driveID, permissionID, newPermission)
if len(ret) == 0 {
panic("no return value specified for UpdateSpaceRootPermission")
}
var r0 libregraph.Permission
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, string, libregraph.Permission) (libregraph.Permission, error)); ok {
return rf(ctx, driveID, permissionID, newPermission)
}
if rf, ok := ret.Get(0).(func(context.Context, providerv1beta1.ResourceId, string, libregraph.Permission) libregraph.Permission); ok {
r0 = rf(ctx, driveID, permissionID, newPermission)
} else {
r0 = ret.Get(0).(libregraph.Permission)
}
if rf, ok := ret.Get(1).(func(context.Context, providerv1beta1.ResourceId, string, libregraph.Permission) error); ok {
r1 = rf(ctx, driveID, permissionID, newPermission)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateSpaceRootPermission'
type DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call struct {
*mock.Call
}
// UpdateSpaceRootPermission is a helper method to define mock.On call
// - ctx context.Context
// - driveID providerv1beta1.ResourceId
// - permissionID string
// - newPermission libregraph.Permission
func (_e *DriveItemPermissionsProvider_Expecter) UpdateSpaceRootPermission(ctx interface{}, driveID interface{}, permissionID interface{}, newPermission interface{}) *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call {
return &DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call{Call: _e.mock.On("UpdateSpaceRootPermission", ctx, driveID, permissionID, newPermission)}
}
func (_c *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call) Run(run func(ctx context.Context, driveID providerv1beta1.ResourceId, permissionID string, newPermission libregraph.Permission)) *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(providerv1beta1.ResourceId), args[2].(string), args[3].(libregraph.Permission))
})
return _c
}
func (_c *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call) Return(_a0 libregraph.Permission, _a1 error) *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call) RunAndReturn(run func(context.Context, providerv1beta1.ResourceId, string, libregraph.Permission) (libregraph.Permission, error)) *DriveItemPermissionsProvider_UpdateSpaceRootPermission_Call {
_c.Call.Return(run)
return _c
}
// NewDriveItemPermissionsProvider creates a new instance of DriveItemPermissionsProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewDriveItemPermissionsProvider(t interface {

View File

@@ -36,9 +36,13 @@ type DriveItemPermissionsProvider interface {
ListPermissions(ctx context.Context, itemID storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error)
ListSpaceRootPermissions(ctx context.Context, driveID storageprovider.ResourceId) (libregraph.CollectionOfPermissionsWithAllowedValues, error)
DeletePermission(ctx context.Context, itemID storageprovider.ResourceId, permissionID string) error
DeleteSpaceRootPermission(ctx context.Context, driveID storageprovider.ResourceId, permissionID string) error
UpdatePermission(ctx context.Context, itemID storageprovider.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error)
UpdateSpaceRootPermission(ctx context.Context, driveID storageprovider.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error)
CreateLink(ctx context.Context, driveItemID storageprovider.ResourceId, createLink libregraph.DriveItemCreateLink) (libregraph.Permission, error)
CreateSpaceRootLink(ctx context.Context, driveID storageprovider.ResourceId, createLink libregraph.DriveItemCreateLink) (libregraph.Permission, error)
SetPublicLinkPassword(ctx context.Context, driveItemID storageprovider.ResourceId, permissionID string, password string) (libregraph.Permission, error)
SetPublicLinkPasswordOnSpaceRoot(ctx context.Context, driveID storageprovider.ResourceId, permissionID string, password string) (libregraph.Permission, error)
}
// DriveItemPermissionsService contains the production business logic for everything that relates to permissions on drive items.
@@ -354,6 +358,25 @@ func (s DriveItemPermissionsService) DeletePermission(ctx context.Context, itemI
return errorcode.New(errorcode.GeneralException, "failed to delete permission")
}
func (s DriveItemPermissionsService) DeleteSpaceRootPermission(ctx context.Context, driveID storageprovider.ResourceId, permissionID string) error {
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return err
}
space, err := utils.GetSpace(ctx, storagespace.FormatResourceID(driveID), gatewayClient)
if err != nil {
return err
}
if space.SpaceType != "project" {
return errorcode.New(errorcode.InvalidRequest, "unsupported space type")
}
rootResourceID := space.GetRoot()
return s.DeletePermission(ctx, *rootResourceID, permissionID)
}
func (s DriveItemPermissionsService) UpdatePermission(ctx context.Context, itemID storageprovider.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error) {
oldPermission, sharedResourceID, err := s.getPermissionByID(ctx, permissionID, &itemID)
if err != nil {
@@ -384,6 +407,25 @@ func (s DriveItemPermissionsService) UpdatePermission(ctx context.Context, itemI
return *updatedPermission, nil
}
func (s DriveItemPermissionsService) UpdateSpaceRootPermission(ctx context.Context, driveID storageprovider.ResourceId, permissionID string, newPermission libregraph.Permission) (libregraph.Permission, error) {
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return libregraph.Permission{}, err
}
space, err := utils.GetSpace(ctx, storagespace.FormatResourceID(driveID), gatewayClient)
if err != nil {
return libregraph.Permission{}, err
}
if space.SpaceType != "project" {
return libregraph.Permission{}, errorcode.New(errorcode.InvalidRequest, "unsupported space type")
}
rootResourceID := space.GetRoot()
return s.UpdatePermission(ctx, *rootResourceID, permissionID, newPermission)
}
// DriveItemPermissionsService is the api that registers the http endpoints which expose needed operation to the graph api.
// the business logic is delegated to the permissions service and further down to the cs3 client.
type DriveItemPermissionsApi struct {
@@ -532,6 +574,33 @@ func (api DriveItemPermissionsApi) DeletePermission(w http.ResponseWriter, r *ht
render.NoContent(w, r)
}
func (api DriveItemPermissionsApi) DeleteSpaceRootPermission(w http.ResponseWriter, r *http.Request) {
driveID, err := parseIDParam(r, "driveID")
if err != nil {
msg := "could not parse driveID"
api.logger.Debug().Err(err).Msg(msg)
errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg)
return
}
permissionID, err := url.PathUnescape(chi.URLParam(r, "permissionID"))
if err != nil {
api.logger.Debug().Err(err).Msg("could not parse permissionID")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid permissionID")
return
}
ctx := r.Context()
err = api.driveItemPermissionsService.DeleteSpaceRootPermission(ctx, driveID, permissionID)
if err != nil {
errorcode.RenderError(w, r, err)
return
}
render.Status(r, http.StatusNoContent)
render.NoContent(w, r)
}
func (api DriveItemPermissionsApi) UpdatePermission(w http.ResponseWriter, r *http.Request) {
_, itemID, err := GetDriveAndItemIDParam(r, &api.logger)
if err != nil {
@@ -569,3 +638,42 @@ func (api DriveItemPermissionsApi) UpdatePermission(w http.ResponseWriter, r *ht
render.Status(r, http.StatusOK)
render.JSON(w, r, &updatedPermission)
}
func (api DriveItemPermissionsApi) UpdateSpaceRootPermission(w http.ResponseWriter, r *http.Request) {
driveID, err := parseIDParam(r, "driveID")
if err != nil {
msg := "could not parse driveID"
api.logger.Debug().Err(err).Msg(msg)
errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg)
return
}
permissionID, err := url.PathUnescape(chi.URLParam(r, "permissionID"))
if err != nil {
api.logger.Debug().Err(err).Msg("could not parse permissionID")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid permissionID")
return
}
permission := libregraph.Permission{}
if err = StrictJSONUnmarshal(r.Body, &permission); err != nil {
api.logger.Debug().Err(err).Interface("Body", r.Body).Msg("failed unmarshalling request body")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid request body")
return
}
ctx := r.Context()
if err = validate.StructCtx(ctx, permission); err != nil {
api.logger.Debug().Err(err).Interface("Body", r.Body).Msg("invalid request body")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
return
}
updatedPermission, err := api.driveItemPermissionsService.UpdateSpaceRootPermission(ctx, driveID, permissionID, permission)
if err != nil {
errorcode.RenderError(w, r, err)
return
}
render.Status(r, http.StatusOK)
render.JSON(w, r, &updatedPermission)
}

View File

@@ -12,6 +12,7 @@ import (
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
@@ -94,6 +95,24 @@ func (s DriveItemPermissionsService) CreateLink(ctx context.Context, driveItemID
return *perm, nil
}
func (s DriveItemPermissionsService) CreateSpaceRootLink(ctx context.Context, driveID storageprovider.ResourceId, createLink libregraph.DriveItemCreateLink) (libregraph.Permission, error) {
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return libregraph.Permission{}, err
}
space, err := utils.GetSpace(ctx, storagespace.FormatResourceID(driveID), gatewayClient)
if err != nil {
return libregraph.Permission{}, err
}
if space.SpaceType != "project" {
return libregraph.Permission{}, errorcode.New(errorcode.InvalidRequest, "unsupported space type")
}
rootResourceID := space.GetRoot()
return s.CreateLink(ctx, *rootResourceID, createLink)
}
func (s DriveItemPermissionsService) SetPublicLinkPassword(ctx context.Context, driveItemId storageprovider.ResourceId, permissionID string, password string) (libregraph.Permission, error) {
publicShare, err := s.getCS3PublicShareByID(ctx, permissionID)
if err != nil {
@@ -114,6 +133,23 @@ func (s DriveItemPermissionsService) SetPublicLinkPassword(ctx context.Context,
return *permission, nil
}
func (s DriveItemPermissionsService) SetPublicLinkPasswordOnSpaceRoot(ctx context.Context, driveID storageprovider.ResourceId, permissionID string, password string) (libregraph.Permission, error) {
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
return libregraph.Permission{}, err
}
space, err := utils.GetSpace(ctx, storagespace.FormatResourceID(driveID), gatewayClient)
if err != nil {
return libregraph.Permission{}, err
}
if space.SpaceType != "project" {
return libregraph.Permission{}, errorcode.New(errorcode.InvalidRequest, "unsupported space type")
}
rootResourceID := space.GetRoot()
return s.SetPublicLinkPassword(ctx, *rootResourceID, permissionID, password)
}
// CreateLink creates a public link on the cs3 api
func (api DriveItemPermissionsApi) CreateLink(w http.ResponseWriter, r *http.Request) {
logger := api.logger.SubloggerWithRequestID(r.Context())
@@ -142,6 +178,35 @@ func (api DriveItemPermissionsApi) CreateLink(w http.ResponseWriter, r *http.Req
render.JSON(w, r, perm)
}
func (api DriveItemPermissionsApi) CreateSpaceRootLink(w http.ResponseWriter, r *http.Request) {
logger := api.logger.SubloggerWithRequestID(r.Context())
logger.Info().Msg("calling create link")
driveID, err := parseIDParam(r, "driveID")
if err != nil {
msg := "could not parse driveID"
api.logger.Debug().Err(err).Msg(msg)
errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg)
return
}
var createLink libregraph.DriveItemCreateLink
if err = StrictJSONUnmarshal(r.Body, &createLink); err != nil {
logger.Error().Err(err).Interface("body", r.Body).Msg("could not create link: invalid body schema definition")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid body schema definition")
return
}
perm, err := api.driveItemPermissionsService.CreateSpaceRootLink(r.Context(), driveID, createLink)
if err != nil {
errorcode.RenderError(w, r, err)
return
}
render.Status(r, http.StatusOK)
render.JSON(w, r, perm)
}
// SetLinkPassword sets public link password on the cs3 api
func (api DriveItemPermissionsApi) SetLinkPassword(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
@@ -175,6 +240,40 @@ func (api DriveItemPermissionsApi) SetLinkPassword(w http.ResponseWriter, r *htt
render.JSON(w, r, newPermission)
}
func (api DriveItemPermissionsApi) SetSpaceRootLinkPassword(w http.ResponseWriter, r *http.Request) {
driveID, err := parseIDParam(r, "driveID")
if err != nil {
msg := "could not parse driveID"
api.logger.Debug().Err(err).Msg(msg)
errorcode.InvalidRequest.Render(w, r, http.StatusUnprocessableEntity, msg)
return
}
permissionID, err := url.PathUnescape(chi.URLParam(r, "permissionID"))
if err != nil {
api.logger.Debug().Err(err).Msg("could not parse permissionID")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid permissionID")
return
}
password := &libregraph.SharingLinkPassword{}
if err = StrictJSONUnmarshal(r.Body, password); err != nil {
api.logger.Debug().Err(err).Interface("Body", r.Body).Msg("failed unmarshalling request body")
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid request body")
return
}
ctx := r.Context()
newPermission, err := api.driveItemPermissionsService.SetPublicLinkPasswordOnSpaceRoot(ctx, driveID, permissionID, password.GetPassword())
if err != nil {
errorcode.RenderError(w, r, err)
return
}
render.Status(r, http.StatusOK)
render.JSON(w, r, newPermission)
}
func (s DriveItemPermissionsService) updatePublicLinkPermission(ctx context.Context, permissionID string, itemID *providerv1beta1.ResourceId, newPermission *libregraph.Permission) (perm *libregraph.Permission, err error) {
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {

View File

@@ -236,13 +236,20 @@ func NewService(opts ...Option) (Graph, error) {
r.Route("/root", func(r chi.Router) {
r.Post("/children", drivesDriveItemApi.CreateDriveItem)
r.Post("/invite", driveItemPermissionsApi.SpaceRootInvite)
r.Post("/createLink", driveItemPermissionsApi.CreateSpaceRootLink)
r.Route("/permissions", func(r chi.Router) {
r.Get("/", driveItemPermissionsApi.ListSpaceRootPermissions)
r.Route("/{permissionID}", func(r chi.Router) {
r.Delete("/", driveItemPermissionsApi.DeleteSpaceRootPermission)
r.Patch("/", driveItemPermissionsApi.UpdateSpaceRootPermission)
r.Post("/setPassword", driveItemPermissionsApi.SetLinkPassword)
})
})
})
r.Route("/items/{itemID}", func(r chi.Router) {
r.Delete("/", drivesDriveItemApi.DeleteDriveItem)
r.Post("/invite", driveItemPermissionsApi.Invite)
r.Post("/createLink", driveItemPermissionsApi.CreateLink)
r.Route("/permissions", func(r chi.Router) {
r.Get("/", driveItemPermissionsApi.ListPermissions)
r.Route("/{permissionID}", func(r chi.Router) {
@@ -251,7 +258,6 @@ func NewService(opts ...Option) (Graph, error) {
r.Post("/setPassword", driveItemPermissionsApi.SetLinkPassword)
})
})
r.Post("/createLink", driveItemPermissionsApi.CreateLink)
})
})
})