github.com/cs3org/reva/v2@v2.27.7/pkg/storage/utils/middleware/middleware.go (about)

     1  // Copyright 2018-2024 CERN
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package middleware
    20  
    21  import (
    22  	"context"
    23  	"io"
    24  	"net/url"
    25  
    26  	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
    27  	tusd "github.com/tus/tusd/v2/pkg/handler"
    28  
    29  	"github.com/cs3org/reva/v2/pkg/storage"
    30  	"github.com/cs3org/reva/v2/pkg/storage/utils/decomposedfs/upload"
    31  	"github.com/cs3org/reva/v2/pkg/storagespace"
    32  )
    33  
    34  // UnHook is a function that is called after the actual method is executed.
    35  type UnHook func() error
    36  
    37  // Hook is a function that is called before the actual method is executed.
    38  type Hook func(methodName string, ctx context.Context, spaceID string) (context.Context, UnHook, error)
    39  
    40  // FS is a storage.FS implementation that wraps another storage.FS and calls hooks before and after each method.
    41  type FS struct {
    42  	next  storage.FS
    43  	hooks []Hook
    44  }
    45  
    46  func NewFS(next storage.FS, hooks ...Hook) *FS {
    47  	return &FS{
    48  		next:  next,
    49  		hooks: hooks,
    50  	}
    51  }
    52  
    53  // ListUploadSessions returns the upload sessions matching the given filter
    54  func (f *FS) ListUploadSessions(ctx context.Context, filter storage.UploadSessionFilter) ([]storage.UploadSession, error) {
    55  	return f.next.(storage.UploadSessionLister).ListUploadSessions(ctx, filter)
    56  }
    57  
    58  // UseIn tells the tus upload middleware which extensions it supports.
    59  func (f *FS) UseIn(composer *tusd.StoreComposer) {
    60  	f.next.(storage.ComposableFS).UseIn(composer)
    61  }
    62  
    63  // NewUpload returns a new tus Upload instance
    64  func (f *FS) NewUpload(ctx context.Context, info tusd.FileInfo) (upload tusd.Upload, err error) {
    65  	return f.next.(tusd.DataStore).NewUpload(ctx, info)
    66  }
    67  
    68  // NewUpload returns a new tus Upload instance
    69  func (f *FS) GetUpload(ctx context.Context, id string) (upload tusd.Upload, err error) {
    70  	return f.next.(tusd.DataStore).GetUpload(ctx, id)
    71  }
    72  
    73  // AsTerminatableUpload returns a TerminatableUpload
    74  // To implement the termination extension as specified in https://tus.io/protocols/resumable-upload.html#termination
    75  // the storage needs to implement AsTerminatableUpload
    76  func (f *FS) AsTerminatableUpload(up tusd.Upload) tusd.TerminatableUpload {
    77  	return up.(*upload.OcisSession)
    78  }
    79  
    80  // AsLengthDeclarableUpload returns a LengthDeclarableUpload
    81  // To implement the creation-defer-length extension as specified in https://tus.io/protocols/resumable-upload.html#creation
    82  // the storage needs to implement AsLengthDeclarableUpload
    83  func (f *FS) AsLengthDeclarableUpload(up tusd.Upload) tusd.LengthDeclarableUpload {
    84  	return up.(*upload.OcisSession)
    85  }
    86  
    87  // AsConcatableUpload returns a ConcatableUpload
    88  // To implement the concatenation extension as specified in https://tus.io/protocols/resumable-upload.html#concatenation
    89  // the storage needs to implement AsConcatableUpload
    90  func (f *FS) AsConcatableUpload(up tusd.Upload) tusd.ConcatableUpload {
    91  	return up.(*upload.OcisSession)
    92  }
    93  
    94  func (f *FS) GetHome(ctx context.Context) (string, error) {
    95  	var (
    96  		err     error
    97  		unhook  UnHook
    98  		unhooks []UnHook
    99  	)
   100  	for _, hook := range f.hooks {
   101  		ctx, unhook, err = hook("GetHome", ctx, "")
   102  		if err != nil {
   103  			return "", err
   104  		}
   105  		if unhook != nil {
   106  			unhooks = append(unhooks, unhook)
   107  		}
   108  	}
   109  
   110  	res0, res1 := f.next.GetHome(ctx)
   111  
   112  	for _, unhook := range unhooks {
   113  		if err := unhook(); err != nil {
   114  			return "", err
   115  		}
   116  	}
   117  
   118  	return res0, res1
   119  }
   120  
   121  func (f *FS) CreateHome(ctx context.Context) error {
   122  	var (
   123  		err     error
   124  		unhook  UnHook
   125  		unhooks []UnHook
   126  	)
   127  	for _, hook := range f.hooks {
   128  		ctx, unhook, err = hook("CreateHome", ctx, "")
   129  		if err != nil {
   130  			return err
   131  		}
   132  		if unhook != nil {
   133  			unhooks = append(unhooks, unhook)
   134  		}
   135  	}
   136  
   137  	res0 := f.next.CreateHome(ctx)
   138  
   139  	for _, unhook := range unhooks {
   140  		if err := unhook(); err != nil {
   141  			return err
   142  		}
   143  	}
   144  
   145  	return res0
   146  }
   147  
   148  func (f *FS) CreateDir(ctx context.Context, ref *provider.Reference) error {
   149  	var (
   150  		err     error
   151  		unhook  UnHook
   152  		unhooks []UnHook
   153  	)
   154  	for _, hook := range f.hooks {
   155  		ctx, unhook, err = hook("CreateDir", ctx, ref.GetResourceId().GetSpaceId())
   156  		if err != nil {
   157  			return err
   158  		}
   159  		if unhook != nil {
   160  			unhooks = append(unhooks, unhook)
   161  		}
   162  	}
   163  
   164  	res0 := f.next.CreateDir(ctx, ref)
   165  
   166  	for _, unhook := range unhooks {
   167  		if err := unhook(); err != nil {
   168  			return err
   169  		}
   170  	}
   171  
   172  	return res0
   173  }
   174  
   175  func (f *FS) TouchFile(ctx context.Context, ref *provider.Reference, markprocessing bool, mtime string) error {
   176  	var (
   177  		err     error
   178  		unhook  UnHook
   179  		unhooks []UnHook
   180  	)
   181  	for _, hook := range f.hooks {
   182  		ctx, unhook, err = hook("TouchFile", ctx, ref.GetResourceId().GetSpaceId())
   183  		if err != nil {
   184  			return err
   185  		}
   186  		if unhook != nil {
   187  			unhooks = append(unhooks, unhook)
   188  		}
   189  	}
   190  
   191  	res0 := f.next.TouchFile(ctx, ref, markprocessing, mtime)
   192  
   193  	for _, unhook := range unhooks {
   194  		if err := unhook(); err != nil {
   195  			return err
   196  		}
   197  	}
   198  
   199  	return res0
   200  }
   201  
   202  func (f *FS) Delete(ctx context.Context, ref *provider.Reference) error {
   203  	var (
   204  		err     error
   205  		unhook  UnHook
   206  		unhooks []UnHook
   207  	)
   208  	for _, hook := range f.hooks {
   209  		ctx, unhook, err = hook("Delete", ctx, ref.GetResourceId().GetSpaceId())
   210  		if err != nil {
   211  			return err
   212  		}
   213  		if unhook != nil {
   214  			unhooks = append(unhooks, unhook)
   215  		}
   216  	}
   217  
   218  	res0 := f.next.Delete(ctx, ref)
   219  
   220  	for _, unhook := range unhooks {
   221  		if err := unhook(); err != nil {
   222  			return err
   223  		}
   224  	}
   225  
   226  	return res0
   227  }
   228  
   229  func (f *FS) Move(ctx context.Context, oldRef, newRef *provider.Reference) error {
   230  	var (
   231  		err     error
   232  		unhook  UnHook
   233  		unhooks []UnHook
   234  	)
   235  	for _, hook := range f.hooks {
   236  		ctx, unhook, err = hook("Move", ctx, oldRef.GetResourceId().GetSpaceId())
   237  		if err != nil {
   238  			return err
   239  		}
   240  		if unhook != nil {
   241  			unhooks = append(unhooks, unhook)
   242  		}
   243  	}
   244  
   245  	res0 := f.next.Move(ctx, oldRef, newRef)
   246  
   247  	for _, unhook := range unhooks {
   248  		if err := unhook(); err != nil {
   249  			return err
   250  		}
   251  	}
   252  
   253  	return res0
   254  }
   255  
   256  func (f *FS) GetMD(ctx context.Context, ref *provider.Reference, mdKeys, fieldMask []string) (*provider.ResourceInfo, error) {
   257  	var (
   258  		err     error
   259  		unhook  UnHook
   260  		unhooks []UnHook
   261  	)
   262  	for _, hook := range f.hooks {
   263  		ctx, unhook, err = hook("GetMD", ctx, ref.GetResourceId().GetSpaceId())
   264  		if err != nil {
   265  			return nil, err
   266  		}
   267  		if unhook != nil {
   268  			unhooks = append(unhooks, unhook)
   269  		}
   270  	}
   271  
   272  	res0, res1 := f.next.GetMD(ctx, ref, mdKeys, fieldMask)
   273  
   274  	for _, unhook := range unhooks {
   275  		if err := unhook(); err != nil {
   276  			return nil, err
   277  		}
   278  	}
   279  
   280  	return res0, res1
   281  }
   282  
   283  func (f *FS) ListFolder(ctx context.Context, ref *provider.Reference, mdKeys, fieldMask []string) ([]*provider.ResourceInfo, error) {
   284  	var (
   285  		err     error
   286  		unhook  UnHook
   287  		unhooks []UnHook
   288  	)
   289  	for _, hook := range f.hooks {
   290  		ctx, unhook, err = hook("ListFolder", ctx, ref.GetResourceId().GetSpaceId())
   291  		if err != nil {
   292  			return nil, err
   293  		}
   294  		if unhook != nil {
   295  			unhooks = append(unhooks, unhook)
   296  		}
   297  	}
   298  
   299  	res0, res1 := f.next.ListFolder(ctx, ref, mdKeys, fieldMask)
   300  
   301  	for _, unhook := range unhooks {
   302  		if err := unhook(); err != nil {
   303  			return nil, err
   304  		}
   305  	}
   306  
   307  	return res0, res1
   308  }
   309  
   310  func (f *FS) InitiateUpload(ctx context.Context, ref *provider.Reference, uploadLength int64, metadata map[string]string) (map[string]string, error) {
   311  	var (
   312  		err     error
   313  		unhook  UnHook
   314  		unhooks []UnHook
   315  	)
   316  	for _, hook := range f.hooks {
   317  		ctx, unhook, err = hook("InitiateUpload", ctx, ref.GetResourceId().GetSpaceId())
   318  		if err != nil {
   319  			return nil, err
   320  		}
   321  		if unhook != nil {
   322  			unhooks = append(unhooks, unhook)
   323  		}
   324  	}
   325  
   326  	res0, res1 := f.next.InitiateUpload(ctx, ref, uploadLength, metadata)
   327  
   328  	for _, unhook := range unhooks {
   329  		if err := unhook(); err != nil {
   330  			return nil, err
   331  		}
   332  	}
   333  
   334  	return res0, res1
   335  }
   336  
   337  func (f *FS) Upload(ctx context.Context, req storage.UploadRequest, uploadFunc storage.UploadFinishedFunc) (*provider.ResourceInfo, error) {
   338  	var (
   339  		err     error
   340  		unhook  UnHook
   341  		unhooks []UnHook
   342  	)
   343  	for _, hook := range f.hooks {
   344  		ctx, unhook, err = hook("Upload", ctx, req.Ref.GetResourceId().GetSpaceId())
   345  		if err != nil {
   346  			return &provider.ResourceInfo{}, err
   347  		}
   348  		if unhook != nil {
   349  			unhooks = append(unhooks, unhook)
   350  		}
   351  	}
   352  
   353  	res0, res1 := f.next.Upload(ctx, req, uploadFunc)
   354  
   355  	for _, unhook := range unhooks {
   356  		if err := unhook(); err != nil {
   357  			return &provider.ResourceInfo{}, err
   358  		}
   359  	}
   360  
   361  	return res0, res1
   362  }
   363  
   364  func (f *FS) Download(ctx context.Context, ref *provider.Reference, openReaderFunc func(md *provider.ResourceInfo) bool) (*provider.ResourceInfo, io.ReadCloser, error) {
   365  	var (
   366  		err     error
   367  		unhook  UnHook
   368  		unhooks []UnHook
   369  	)
   370  	for _, hook := range f.hooks {
   371  		ctx, unhook, err = hook("Download", ctx, ref.GetResourceId().GetSpaceId())
   372  		if err != nil {
   373  			return nil, nil, err
   374  		}
   375  		if unhook != nil {
   376  			unhooks = append(unhooks, unhook)
   377  		}
   378  	}
   379  
   380  	res0, res1, res2 := f.next.Download(ctx, ref, openReaderFunc)
   381  
   382  	for _, unhook := range unhooks {
   383  		if err := unhook(); err != nil {
   384  			return nil, nil, err
   385  		}
   386  	}
   387  
   388  	return res0, res1, res2
   389  }
   390  
   391  func (f *FS) ListRevisions(ctx context.Context, ref *provider.Reference) ([]*provider.FileVersion, error) {
   392  	var (
   393  		err     error
   394  		unhook  UnHook
   395  		unhooks []UnHook
   396  	)
   397  	for _, hook := range f.hooks {
   398  		ctx, unhook, err = hook("ListRevisions", ctx, ref.GetResourceId().GetSpaceId())
   399  		if err != nil {
   400  			return nil, err
   401  		}
   402  		if unhook != nil {
   403  			unhooks = append(unhooks, unhook)
   404  		}
   405  	}
   406  
   407  	res0, res1 := f.next.ListRevisions(ctx, ref)
   408  
   409  	for _, unhook := range unhooks {
   410  		if err := unhook(); err != nil {
   411  			return nil, err
   412  		}
   413  	}
   414  
   415  	return res0, res1
   416  }
   417  
   418  func (f *FS) DownloadRevision(ctx context.Context, ref *provider.Reference, key string, openReaderFunc func(md *provider.ResourceInfo) bool) (*provider.ResourceInfo, io.ReadCloser, error) {
   419  	var (
   420  		err     error
   421  		unhook  UnHook
   422  		unhooks []UnHook
   423  	)
   424  	for _, hook := range f.hooks {
   425  		ctx, unhook, err = hook("DownloadRevision", ctx, ref.GetResourceId().GetSpaceId())
   426  		if err != nil {
   427  			return nil, nil, err
   428  		}
   429  		if unhook != nil {
   430  			unhooks = append(unhooks, unhook)
   431  		}
   432  	}
   433  
   434  	res0, res1, res2 := f.next.DownloadRevision(ctx, ref, key, openReaderFunc)
   435  
   436  	for _, unhook := range unhooks {
   437  		if err := unhook(); err != nil {
   438  			return nil, nil, err
   439  		}
   440  	}
   441  
   442  	return res0, res1, res2
   443  }
   444  
   445  func (f *FS) RestoreRevision(ctx context.Context, ref *provider.Reference, key string) error {
   446  	var (
   447  		err     error
   448  		unhook  UnHook
   449  		unhooks []UnHook
   450  	)
   451  	for _, hook := range f.hooks {
   452  		ctx, unhook, err = hook("RestoreRevision", ctx, ref.GetResourceId().GetSpaceId())
   453  		if err != nil {
   454  			return err
   455  		}
   456  		if unhook != nil {
   457  			unhooks = append(unhooks, unhook)
   458  		}
   459  	}
   460  
   461  	res0 := f.next.RestoreRevision(ctx, ref, key)
   462  
   463  	for _, unhook := range unhooks {
   464  		if err := unhook(); err != nil {
   465  			return err
   466  		}
   467  	}
   468  
   469  	return res0
   470  }
   471  
   472  func (f *FS) ListRecycle(ctx context.Context, ref *provider.Reference, key, relativePath string) ([]*provider.RecycleItem, error) {
   473  	var (
   474  		err     error
   475  		unhook  UnHook
   476  		unhooks []UnHook
   477  	)
   478  	for _, hook := range f.hooks {
   479  		ctx, unhook, err = hook("ListRecycle", ctx, ref.GetResourceId().GetSpaceId())
   480  		if err != nil {
   481  			return nil, err
   482  		}
   483  		if unhook != nil {
   484  			unhooks = append(unhooks, unhook)
   485  		}
   486  	}
   487  
   488  	res0, res1 := f.next.ListRecycle(ctx, ref, key, relativePath)
   489  
   490  	for _, unhook := range unhooks {
   491  		if err := unhook(); err != nil {
   492  			return nil, err
   493  		}
   494  	}
   495  
   496  	return res0, res1
   497  }
   498  
   499  func (f *FS) RestoreRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string, restoreRef *provider.Reference) error {
   500  	var (
   501  		err     error
   502  		unhook  UnHook
   503  		unhooks []UnHook
   504  	)
   505  	for _, hook := range f.hooks {
   506  		ctx, unhook, err = hook("RestoreRecycleItem", ctx, ref.GetResourceId().GetSpaceId())
   507  		if err != nil {
   508  			return err
   509  		}
   510  		if unhook != nil {
   511  			unhooks = append(unhooks, unhook)
   512  		}
   513  	}
   514  
   515  	res0 := f.next.RestoreRecycleItem(ctx, ref, key, relativePath, restoreRef)
   516  
   517  	for _, unhook := range unhooks {
   518  		if err := unhook(); err != nil {
   519  			return err
   520  		}
   521  	}
   522  
   523  	return res0
   524  }
   525  
   526  func (f *FS) PurgeRecycleItem(ctx context.Context, ref *provider.Reference, key, relativePath string) error {
   527  	var (
   528  		err     error
   529  		unhook  UnHook
   530  		unhooks []UnHook
   531  	)
   532  	for _, hook := range f.hooks {
   533  		ctx, unhook, err = hook("PurgeRecycleItem", ctx, ref.GetResourceId().GetSpaceId())
   534  		if err != nil {
   535  			return err
   536  		}
   537  		if unhook != nil {
   538  			unhooks = append(unhooks, unhook)
   539  		}
   540  	}
   541  
   542  	res0 := f.next.PurgeRecycleItem(ctx, ref, key, relativePath)
   543  
   544  	for _, unhook := range unhooks {
   545  		if err := unhook(); err != nil {
   546  			return err
   547  		}
   548  	}
   549  
   550  	return res0
   551  }
   552  
   553  func (f *FS) EmptyRecycle(ctx context.Context, ref *provider.Reference) error {
   554  	var (
   555  		err     error
   556  		unhook  UnHook
   557  		unhooks []UnHook
   558  	)
   559  	for _, hook := range f.hooks {
   560  		ctx, unhook, err = hook("EmptyRecycle", ctx, ref.GetResourceId().GetSpaceId())
   561  		if err != nil {
   562  			return err
   563  		}
   564  		if unhook != nil {
   565  			unhooks = append(unhooks, unhook)
   566  		}
   567  	}
   568  
   569  	res0 := f.next.EmptyRecycle(ctx, ref)
   570  	for _, unhook := range unhooks {
   571  		_ = unhook()
   572  	}
   573  	return res0
   574  }
   575  
   576  func (f *FS) GetPathByID(ctx context.Context, id *provider.ResourceId) (string, error) {
   577  	var (
   578  		err     error
   579  		unhook  UnHook
   580  		unhooks []UnHook
   581  	)
   582  	for _, hook := range f.hooks {
   583  		ctx, unhook, err = hook("GetPathByID", ctx, id.GetSpaceId())
   584  		if err != nil {
   585  			return "", err
   586  		}
   587  		if unhook != nil {
   588  			unhooks = append(unhooks, unhook)
   589  		}
   590  	}
   591  
   592  	res0, res1 := f.next.GetPathByID(ctx, id)
   593  
   594  	for _, unhook := range unhooks {
   595  		if err := unhook(); err != nil {
   596  			return "", err
   597  		}
   598  	}
   599  
   600  	return res0, res1
   601  }
   602  
   603  func (f *FS) AddGrant(ctx context.Context, ref *provider.Reference, g *provider.Grant) error {
   604  	var (
   605  		err     error
   606  		unhook  UnHook
   607  		unhooks []UnHook
   608  	)
   609  	for _, hook := range f.hooks {
   610  		ctx, unhook, err = hook("AddGrant", ctx, ref.GetResourceId().GetSpaceId())
   611  		if err != nil {
   612  			return err
   613  		}
   614  		if unhook != nil {
   615  			unhooks = append(unhooks, unhook)
   616  		}
   617  	}
   618  
   619  	res0 := f.next.AddGrant(ctx, ref, g)
   620  
   621  	for _, unhook := range unhooks {
   622  		if err := unhook(); err != nil {
   623  			return err
   624  		}
   625  	}
   626  
   627  	return res0
   628  }
   629  
   630  func (f *FS) DenyGrant(ctx context.Context, ref *provider.Reference, g *provider.Grantee) error {
   631  	var (
   632  		err     error
   633  		unhook  UnHook
   634  		unhooks []UnHook
   635  	)
   636  	for _, hook := range f.hooks {
   637  		ctx, unhook, err = hook("DenyGrant", ctx, ref.GetResourceId().GetSpaceId())
   638  		if err != nil {
   639  			return err
   640  		}
   641  		if unhook != nil {
   642  			unhooks = append(unhooks, unhook)
   643  		}
   644  	}
   645  
   646  	res0 := f.next.DenyGrant(ctx, ref, g)
   647  
   648  	for _, unhook := range unhooks {
   649  		if err := unhook(); err != nil {
   650  			return err
   651  		}
   652  	}
   653  
   654  	return res0
   655  }
   656  
   657  func (f *FS) RemoveGrant(ctx context.Context, ref *provider.Reference, g *provider.Grant) error {
   658  	var (
   659  		err     error
   660  		unhook  UnHook
   661  		unhooks []UnHook
   662  	)
   663  	for _, hook := range f.hooks {
   664  		ctx, unhook, err = hook("RemoveGrant", ctx, ref.GetResourceId().GetSpaceId())
   665  		if err != nil {
   666  			return err
   667  		}
   668  		if unhook != nil {
   669  			unhooks = append(unhooks, unhook)
   670  		}
   671  	}
   672  
   673  	res0 := f.next.RemoveGrant(ctx, ref, g)
   674  
   675  	for _, unhook := range unhooks {
   676  		if err := unhook(); err != nil {
   677  			return err
   678  		}
   679  	}
   680  
   681  	return res0
   682  }
   683  
   684  func (f *FS) UpdateGrant(ctx context.Context, ref *provider.Reference, g *provider.Grant) error {
   685  	var (
   686  		err     error
   687  		unhook  UnHook
   688  		unhooks []UnHook
   689  	)
   690  	for _, hook := range f.hooks {
   691  		ctx, unhook, err = hook("UpdateGrant", ctx, ref.GetResourceId().GetSpaceId())
   692  		if err != nil {
   693  			return err
   694  		}
   695  		if unhook != nil {
   696  			unhooks = append(unhooks, unhook)
   697  		}
   698  	}
   699  
   700  	res0 := f.next.UpdateGrant(ctx, ref, g)
   701  
   702  	for _, unhook := range unhooks {
   703  		if err := unhook(); err != nil {
   704  			return err
   705  		}
   706  	}
   707  
   708  	return res0
   709  }
   710  
   711  func (f *FS) ListGrants(ctx context.Context, ref *provider.Reference) ([]*provider.Grant, error) {
   712  	var (
   713  		err     error
   714  		unhook  UnHook
   715  		unhooks []UnHook
   716  	)
   717  	for _, hook := range f.hooks {
   718  		ctx, unhook, err = hook("ListGrants", ctx, ref.GetResourceId().GetSpaceId())
   719  		if err != nil {
   720  			return nil, err
   721  		}
   722  		if unhook != nil {
   723  			unhooks = append(unhooks, unhook)
   724  		}
   725  	}
   726  
   727  	res0, res1 := f.next.ListGrants(ctx, ref)
   728  
   729  	for _, unhook := range unhooks {
   730  		if err := unhook(); err != nil {
   731  			return nil, err
   732  		}
   733  	}
   734  
   735  	return res0, res1
   736  }
   737  
   738  func (f *FS) GetQuota(ctx context.Context, ref *provider.Reference) (uint64, uint64, uint64, error) {
   739  	var (
   740  		err     error
   741  		unhook  UnHook
   742  		unhooks []UnHook
   743  	)
   744  	for _, hook := range f.hooks {
   745  		ctx, unhook, err = hook("GetQuota", ctx, ref.GetResourceId().GetSpaceId())
   746  		if err != nil {
   747  			return 0, 0, 0, err
   748  		}
   749  		if unhook != nil {
   750  			unhooks = append(unhooks, unhook)
   751  		}
   752  	}
   753  
   754  	res0, res1, res2, res3 := f.next.GetQuota(ctx, ref)
   755  
   756  	for _, unhook := range unhooks {
   757  		if err := unhook(); err != nil {
   758  			return 0, 0, 0, err
   759  		}
   760  	}
   761  
   762  	return res0, res1, res2, res3
   763  }
   764  
   765  func (f *FS) CreateReference(ctx context.Context, path string, targetURI *url.URL) error {
   766  	var (
   767  		err     error
   768  		unhook  UnHook
   769  		unhooks []UnHook
   770  	)
   771  	for _, hook := range f.hooks {
   772  		ctx, unhook, err = hook("CreateReference", ctx, "")
   773  		if err != nil {
   774  			return err
   775  		}
   776  		if unhook != nil {
   777  			unhooks = append(unhooks, unhook)
   778  		}
   779  	}
   780  
   781  	res0 := f.next.CreateReference(ctx, path, targetURI)
   782  
   783  	for _, unhook := range unhooks {
   784  		if err := unhook(); err != nil {
   785  			return err
   786  		}
   787  	}
   788  
   789  	return res0
   790  }
   791  
   792  func (f *FS) Shutdown(ctx context.Context) error {
   793  	var (
   794  		err     error
   795  		unhook  UnHook
   796  		unhooks []UnHook
   797  	)
   798  	for _, hook := range f.hooks {
   799  		ctx, unhook, err = hook("Shutdown", ctx, "")
   800  		if err != nil {
   801  			return err
   802  		}
   803  		if unhook != nil {
   804  			unhooks = append(unhooks, unhook)
   805  		}
   806  	}
   807  
   808  	res0 := f.next.Shutdown(ctx)
   809  
   810  	for _, unhook := range unhooks {
   811  		if err := unhook(); err != nil {
   812  			return err
   813  		}
   814  	}
   815  
   816  	return res0
   817  }
   818  
   819  func (f *FS) SetArbitraryMetadata(ctx context.Context, ref *provider.Reference, md *provider.ArbitraryMetadata) error {
   820  	var (
   821  		err     error
   822  		unhook  UnHook
   823  		unhooks []UnHook
   824  	)
   825  	for _, hook := range f.hooks {
   826  		ctx, unhook, err = hook("SetArbitraryMetadata", ctx, ref.GetResourceId().GetSpaceId())
   827  		if err != nil {
   828  			return err
   829  		}
   830  		if unhook != nil {
   831  			unhooks = append(unhooks, unhook)
   832  		}
   833  	}
   834  
   835  	res0 := f.next.SetArbitraryMetadata(ctx, ref, md)
   836  
   837  	for _, unhook := range unhooks {
   838  		if err := unhook(); err != nil {
   839  			return err
   840  		}
   841  	}
   842  
   843  	return res0
   844  }
   845  
   846  func (f *FS) UnsetArbitraryMetadata(ctx context.Context, ref *provider.Reference, keys []string) error {
   847  	var (
   848  		err     error
   849  		unhook  UnHook
   850  		unhooks []UnHook
   851  	)
   852  	for _, hook := range f.hooks {
   853  		ctx, unhook, err = hook("UnsetArbitraryMetadata", ctx, ref.GetResourceId().GetSpaceId())
   854  		if err != nil {
   855  			return err
   856  		}
   857  		if unhook != nil {
   858  			unhooks = append(unhooks, unhook)
   859  		}
   860  	}
   861  
   862  	res0 := f.next.UnsetArbitraryMetadata(ctx, ref, keys)
   863  
   864  	for _, unhook := range unhooks {
   865  		if err := unhook(); err != nil {
   866  			return err
   867  		}
   868  	}
   869  
   870  	return res0
   871  }
   872  
   873  func (f *FS) SetLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error {
   874  	var (
   875  		err     error
   876  		unhook  UnHook
   877  		unhooks []UnHook
   878  	)
   879  	for _, hook := range f.hooks {
   880  		ctx, unhook, err = hook("SetLock", ctx, ref.GetResourceId().GetSpaceId())
   881  		if err != nil {
   882  			return err
   883  		}
   884  		if unhook != nil {
   885  			unhooks = append(unhooks, unhook)
   886  		}
   887  	}
   888  
   889  	res0 := f.next.SetLock(ctx, ref, lock)
   890  
   891  	for _, unhook := range unhooks {
   892  		if err := unhook(); err != nil {
   893  			return err
   894  		}
   895  	}
   896  
   897  	return res0
   898  }
   899  
   900  func (f *FS) GetLock(ctx context.Context, ref *provider.Reference) (*provider.Lock, error) {
   901  	var (
   902  		err     error
   903  		unhook  UnHook
   904  		unhooks []UnHook
   905  	)
   906  	for _, hook := range f.hooks {
   907  		ctx, unhook, err = hook("GetLock", ctx, ref.GetResourceId().GetSpaceId())
   908  		if err != nil {
   909  			return nil, err
   910  		}
   911  		if unhook != nil {
   912  			unhooks = append(unhooks, unhook)
   913  		}
   914  	}
   915  
   916  	res0, res1 := f.next.GetLock(ctx, ref)
   917  
   918  	for _, unhook := range unhooks {
   919  		if err := unhook(); err != nil {
   920  			return nil, err
   921  		}
   922  	}
   923  
   924  	return res0, res1
   925  }
   926  
   927  func (f *FS) RefreshLock(ctx context.Context, ref *provider.Reference, lock *provider.Lock, existingLockID string) error {
   928  	var (
   929  		err     error
   930  		unhook  UnHook
   931  		unhooks []UnHook
   932  	)
   933  	for _, hook := range f.hooks {
   934  		ctx, unhook, err = hook("RefreshLock", ctx, ref.GetResourceId().GetSpaceId())
   935  		if err != nil {
   936  			return err
   937  		}
   938  		if unhook != nil {
   939  			unhooks = append(unhooks, unhook)
   940  		}
   941  	}
   942  
   943  	res0 := f.next.RefreshLock(ctx, ref, lock, existingLockID)
   944  
   945  	for _, unhook := range unhooks {
   946  		if err := unhook(); err != nil {
   947  			return err
   948  		}
   949  	}
   950  
   951  	return res0
   952  }
   953  
   954  func (f *FS) Unlock(ctx context.Context, ref *provider.Reference, lock *provider.Lock) error {
   955  	var (
   956  		err     error
   957  		unhook  UnHook
   958  		unhooks []UnHook
   959  	)
   960  	for _, hook := range f.hooks {
   961  		ctx, unhook, err = hook("Unlock", ctx, ref.GetResourceId().GetSpaceId())
   962  		if err != nil {
   963  			return err
   964  		}
   965  		if unhook != nil {
   966  			unhooks = append(unhooks, unhook)
   967  		}
   968  	}
   969  
   970  	res0 := f.next.Unlock(ctx, ref, lock)
   971  
   972  	for _, unhook := range unhooks {
   973  		if err := unhook(); err != nil {
   974  			return err
   975  		}
   976  	}
   977  
   978  	return res0
   979  }
   980  
   981  func (f *FS) ListStorageSpaces(ctx context.Context, filter []*provider.ListStorageSpacesRequest_Filter, unrestricted bool) ([]*provider.StorageSpace, error) {
   982  	var (
   983  		err     error
   984  		unhook  UnHook
   985  		unhooks []UnHook
   986  	)
   987  	for _, hook := range f.hooks {
   988  		ctx, unhook, err = hook("ListStorageSpaces", ctx, "")
   989  		if err != nil {
   990  			return nil, err
   991  		}
   992  		if unhook != nil {
   993  			unhooks = append(unhooks, unhook)
   994  		}
   995  	}
   996  
   997  	res0, res1 := f.next.ListStorageSpaces(ctx, filter, unrestricted)
   998  
   999  	for _, unhook := range unhooks {
  1000  		if err := unhook(); err != nil {
  1001  			return nil, err
  1002  		}
  1003  	}
  1004  
  1005  	return res0, res1
  1006  }
  1007  
  1008  func (f *FS) CreateStorageSpace(ctx context.Context, req *provider.CreateStorageSpaceRequest) (*provider.CreateStorageSpaceResponse, error) {
  1009  	var (
  1010  		err     error
  1011  		unhook  UnHook
  1012  		unhooks []UnHook
  1013  	)
  1014  	for _, hook := range f.hooks {
  1015  		ctx, unhook, err = hook("CreateStorageSpace", ctx, "")
  1016  		if err != nil {
  1017  			return nil, err
  1018  		}
  1019  		if unhook != nil {
  1020  			unhooks = append(unhooks, unhook)
  1021  		}
  1022  	}
  1023  
  1024  	res0, res1 := f.next.CreateStorageSpace(ctx, req)
  1025  
  1026  	for _, unhook := range unhooks {
  1027  		if err := unhook(); err != nil {
  1028  			return nil, err
  1029  		}
  1030  	}
  1031  
  1032  	return res0, res1
  1033  }
  1034  
  1035  func (f *FS) UpdateStorageSpace(ctx context.Context, req *provider.UpdateStorageSpaceRequest) (*provider.UpdateStorageSpaceResponse, error) {
  1036  	var (
  1037  		unhook  UnHook
  1038  		unhooks []UnHook
  1039  	)
  1040  	for _, hook := range f.hooks {
  1041  		id, err := storagespace.ParseID(req.StorageSpace.GetId().GetOpaqueId())
  1042  		if err != nil {
  1043  			return nil, err
  1044  		}
  1045  		ctx, unhook, err = hook("UpdateStorageSpace", ctx, id.SpaceId)
  1046  		if err != nil {
  1047  			return nil, err
  1048  		}
  1049  		if unhook != nil {
  1050  			unhooks = append(unhooks, unhook)
  1051  		}
  1052  	}
  1053  
  1054  	res0, res1 := f.next.UpdateStorageSpace(ctx, req)
  1055  
  1056  	for _, unhook := range unhooks {
  1057  		if err := unhook(); err != nil {
  1058  			return nil, err
  1059  		}
  1060  	}
  1061  
  1062  	return res0, res1
  1063  }
  1064  
  1065  func (f *FS) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorageSpaceRequest) error {
  1066  	var (
  1067  		err     error
  1068  		unhook  UnHook
  1069  		unhooks []UnHook
  1070  	)
  1071  	for _, hook := range f.hooks {
  1072  		ctx, unhook, err = hook("DeleteStorageSpace", ctx, req.GetId().GetOpaqueId())
  1073  		if err != nil {
  1074  			return err
  1075  		}
  1076  		if unhook != nil {
  1077  			unhooks = append(unhooks, unhook)
  1078  		}
  1079  	}
  1080  
  1081  	res0 := f.next.DeleteStorageSpace(ctx, req)
  1082  
  1083  	for _, unhook := range unhooks {
  1084  		if err := unhook(); err != nil {
  1085  			return err
  1086  		}
  1087  	}
  1088  
  1089  	return res0
  1090  }