Files
opencloud/services/storage-users/pkg/task/trash_bin.go
Florian Schade 4f26424db6 [full-ci] enhancement: use reva client pool selectors (#6452)
* enhancement: use reva client pool selectors

register mock service to registry and pass tests

* enhancement: bump reva

* Fix a couple of linter issues

---------

Co-authored-by: Ralf Haferkamp <rhaferkamp@owncloud.com>
2023-06-08 12:41:04 +02:00

119 lines
3.3 KiB
Go

package task
import (
"fmt"
"time"
apiGateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
apiUser "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
apiRpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
apiProvider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/cs3org/reva/v2/pkg/errtypes"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
)
// PurgeTrashBin can be used to purge space trash-bin's,
// the provided executantID must have space access.
// removeBefore specifies how long an item must be in the trash-bin to be deleted,
// items that stay there for a shorter time are ignored and kept in place.
func PurgeTrashBin(executantID *apiUser.UserId, deleteBefore time.Time, spaceType SpaceType, gatewaySelector pool.Selectable[apiGateway.GatewayAPIClient], machineAuthAPIKey string) error {
gatewayClient, err := gatewaySelector.Next()
if err != nil {
return err
}
executantCtx, _, err := utils.Impersonate(executantID, gatewayClient, machineAuthAPIKey)
if err != nil {
return err
}
listStorageSpacesResponse, err := gatewayClient.ListStorageSpaces(executantCtx, &apiProvider.ListStorageSpacesRequest{
Filters: []*apiProvider.ListStorageSpacesRequest_Filter{
{
Type: apiProvider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE,
Term: &apiProvider.ListStorageSpacesRequest_Filter_SpaceType{
SpaceType: string(spaceType),
},
},
},
})
if err != nil {
return err
}
for _, storageSpace := range listStorageSpacesResponse.StorageSpaces {
var (
err error
impersonationID *apiUser.UserId
storageSpaceReference = &apiProvider.Reference{
ResourceId: storageSpace.GetRoot(),
}
)
switch SpaceType(storageSpace.GetSpaceType()) {
case Personal:
impersonationID = storageSpace.GetOwner().GetId()
case Project:
var permissionsMap map[string]*apiProvider.ResourcePermissions
err := utils.ReadJSONFromOpaque(storageSpace.GetOpaque(), "grants", &permissionsMap)
if err != nil {
break
}
for id, permissions := range permissionsMap {
if !permissions.Delete {
continue
}
impersonationID = &apiUser.UserId{
OpaqueId: id,
}
break
}
default:
continue
}
if err != nil {
return err
}
if impersonationID == nil {
return fmt.Errorf("can't impersonate space user for space: %s", storageSpace.GetId().GetOpaqueId())
}
impersonatedCtx, _, err := utils.Impersonate(impersonationID, gatewayClient, machineAuthAPIKey)
if err != nil {
return err
}
listRecycleResponse, err := gatewayClient.ListRecycle(impersonatedCtx, &apiProvider.ListRecycleRequest{Ref: storageSpaceReference})
if err != nil {
return err
}
for _, recycleItem := range listRecycleResponse.GetRecycleItems() {
doDelete := utils.TSToUnixNano(recycleItem.DeletionTime) < utils.TSToUnixNano(utils.TimeToTS(deleteBefore))
if !doDelete {
continue
}
purgeRecycleResponse, err := gatewayClient.PurgeRecycle(impersonatedCtx, &apiProvider.PurgeRecycleRequest{
Ref: storageSpaceReference,
Key: recycleItem.Key,
})
if purgeRecycleResponse.GetStatus().GetCode() != apiRpc.Code_CODE_OK {
return errtypes.NewErrtypeFromStatus(purgeRecycleResponse.Status)
}
if err != nil {
return err
}
}
}
return nil
}