diff --git a/pkg/storage/utils/eosfs/config.go b/pkg/storage/utils/eosfs/config.go index 5b6838e6967..917c5ef194b 100644 --- a/pkg/storage/utils/eosfs/config.go +++ b/pkg/storage/utils/eosfs/config.go @@ -168,4 +168,7 @@ type Config struct { // TokenExpiry stores in seconds the time after which generated tokens will expire // Default is 3600 TokenExpiry int + + // Paths of all the hooks to run after a home folder has been created for a user + OnPostCreateHomeHooks []string `mapstructure:"on_post_create_home_hooks"` } diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index 197bbcf1da6..86f027223f9 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -150,12 +150,13 @@ func (c *Config) init() { } type eosfs struct { - c eosclient.EOSClient - conf *Config - chunkHandler *chunking.ChunkHandler - singleUserAuth eosclient.Authorization - userIDCache *ttlcache.Cache - tokenCache gcache.Cache + c eosclient.EOSClient + conf *Config + chunkHandler *chunking.ChunkHandler + singleUserAuth eosclient.Authorization + userIDCache *ttlcache.Cache + tokenCache gcache.Cache + postCreateHomeHooks []PostCreateHomeHook } // NewEOSFS returns a storage.FS interface implementation that connects to an EOS instance @@ -1430,36 +1431,36 @@ func (fs *eosfs) createShadowHome(ctx context.Context) error { return nil } -func (fs *eosfs) createNominalHome(ctx context.Context) error { +func (fs *eosfs) createNominalHome(ctx context.Context) (string, error) { home := fs.wrap(ctx, "/") u, err := getUser(ctx) if err != nil { - return errors.Wrap(err, "eosfs: no user in ctx") + return "", errors.Wrap(err, "eosfs: no user in ctx") } auth, err := fs.getUserAuth(ctx, u, "") if err != nil { - return err + return "", err } rootAuth, err := fs.getRootAuth(ctx) if err != nil { - return nil + return "", nil } _, err = fs.c.GetFileInfoByPath(ctx, rootAuth, home) if err == nil { // home already exists - return nil + return "", nil } if _, ok := err.(errtypes.IsNotFound); !ok { - return errors.Wrap(err, "eosfs: error verifying if user home directory exists") + return "", errors.Wrap(err, "eosfs: error verifying if user home directory exists") } err = fs.createUserDir(ctx, u, home, false) if err != nil { err := errors.Wrap(err, "eosfs: error creating user dir") - return err + return "", err } // set quota for user @@ -1475,10 +1476,10 @@ func (fs *eosfs) createNominalHome(ctx context.Context) error { err = fs.c.SetQuota(ctx, rootAuth, quotaInfo) if err != nil { err := errors.Wrap(err, "eosfs: error setting quota") - return err + return "", err } - return err + return home, nil } func (fs *eosfs) CreateHome(ctx context.Context) error { @@ -1486,7 +1487,9 @@ func (fs *eosfs) CreateHome(ctx context.Context) error { return errtypes.NotSupported("eosfs: create home not supported") } - if err := fs.createNominalHome(ctx); err != nil { + var err error + var home string + if home, err = fs.createNominalHome(ctx); err != nil { return errors.Wrap(err, "eosfs: error creating nominal home") } @@ -1494,6 +1497,14 @@ func (fs *eosfs) CreateHome(ctx context.Context) error { return errors.Wrap(err, "eosfs: error creating shadow home") } + user := ctxpkg.ContextMustGetUser(ctx) + for _, hook := range fs.postCreateHomeHooks { + err := hook.OnPostCreateHome(user, home) + if err != nil { + return err + } + } + return nil } diff --git a/pkg/storage/utils/eosfs/hooks.go b/pkg/storage/utils/eosfs/hooks.go new file mode 100644 index 00000000000..dcfcfcf7fb6 --- /dev/null +++ b/pkg/storage/utils/eosfs/hooks.go @@ -0,0 +1,35 @@ +package eosfs + +import ( + "plugin" + + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + "github.com/cs3org/reva/pkg/errtypes" + "github.com/pkg/errors" +) + +type PostCreateHomeHook interface { + OnPostCreateHome(*userpb.User, string) error +} + +func (fs *eosfs) createPostCreateHomeHooks() error { + for _, path := range fs.conf.OnPostCreateHomeHooks { + plug, err := plugin.Open(path) + if err != nil { + return errors.Wrapf(err, "error opening go plugin in %s", path) + } + symHook, err := plug.Lookup("PostCreateHomeHook") + if err != nil { + return errors.Wrapf(err, "error finding PostCreateHomeHook in plugin %s", path) + } + + var hook PostCreateHomeHook + hook, ok := symHook.(PostCreateHomeHook) + if !ok { + return errtypes.InternalError("plugin for PostCreateHomeHook not recognised") + } + + fs.postCreateHomeHooks = append(fs.postCreateHomeHooks, hook) + } + return nil +}