[MM-52924] Implement ConfigurationWillBeSaved plugin hook (#23567)
* Implement ConfigurationWillBeSaved plugin hook * Add comment * Update comment * Fix potential nil dereference if plugin environment is unset * Address PR review
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d0ad46b496
Коммит
62a3ee8adc
@@ -1037,6 +1037,42 @@ func (s *hooksRPCServer) GetTopicMetadataByIds(args *Z_GetTopicMetadataByIdsArgs
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
hookNameToId["ConfigurationWillBeSaved"] = ConfigurationWillBeSavedID
|
||||
}
|
||||
|
||||
type Z_ConfigurationWillBeSavedArgs struct {
|
||||
A *model.Config
|
||||
}
|
||||
|
||||
type Z_ConfigurationWillBeSavedReturns struct {
|
||||
A *model.Config
|
||||
B error
|
||||
}
|
||||
|
||||
func (g *hooksRPCClient) ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error) {
|
||||
_args := &Z_ConfigurationWillBeSavedArgs{newCfg}
|
||||
_returns := &Z_ConfigurationWillBeSavedReturns{}
|
||||
if g.implemented[ConfigurationWillBeSavedID] {
|
||||
if err := g.client.Call("Plugin.ConfigurationWillBeSaved", _args, _returns); err != nil {
|
||||
g.log.Error("RPC call ConfigurationWillBeSaved to plugin failed.", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
return _returns.A, _returns.B
|
||||
}
|
||||
|
||||
func (s *hooksRPCServer) ConfigurationWillBeSaved(args *Z_ConfigurationWillBeSavedArgs, returns *Z_ConfigurationWillBeSavedReturns) error {
|
||||
if hook, ok := s.impl.(interface {
|
||||
ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error)
|
||||
}); ok {
|
||||
returns.A, returns.B = hook.ConfigurationWillBeSaved(args.A)
|
||||
returns.B = encodableError(returns.B)
|
||||
} else {
|
||||
return encodableError(fmt.Errorf("Hook ConfigurationWillBeSaved called but not implemented."))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_RegisterCommandArgs struct {
|
||||
A *model.Command
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ const (
|
||||
GetTopicRedirectID = 31
|
||||
GetCollectionMetadataByIdsID = 32
|
||||
GetTopicMetadataByIdsID = 33
|
||||
ConfigurationWillBeSavedID = 34
|
||||
TotalHooksID = iota
|
||||
)
|
||||
|
||||
@@ -336,4 +337,11 @@ type Hooks interface {
|
||||
//
|
||||
// Minimum server version: 7.6
|
||||
GetTopicMetadataByIds(c *Context, topicType string, topicIds []string) (map[string]*model.TopicMetadata, error)
|
||||
|
||||
// ConfigurationWillBeSaved is invoked before saving the configuration to the
|
||||
// backing store.
|
||||
// An error can be returned to reject the operation. Additionally, a new
|
||||
// config object can be returned to be stored in place of the provided one.
|
||||
// Minimum server version: 8.0
|
||||
ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error)
|
||||
}
|
||||
|
||||
@@ -253,3 +253,10 @@ func (hooks *hooksTimerLayer) GetTopicMetadataByIds(c *Context, topicType string
|
||||
hooks.recordTime(startTime, "GetTopicMetadataByIds", _returnsB == nil)
|
||||
return _returnsA, _returnsB
|
||||
}
|
||||
|
||||
func (hooks *hooksTimerLayer) ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error) {
|
||||
startTime := timePkg.Now()
|
||||
_returnsA, _returnsB := hooks.hooksImpl.ConfigurationWillBeSaved(newCfg)
|
||||
hooks.recordTime(startTime, "ConfigurationWillBeSaved", _returnsB == nil)
|
||||
return _returnsA, _returnsB
|
||||
}
|
||||
|
||||
@@ -25,6 +25,32 @@ func (_m *Hooks) ChannelHasBeenCreated(c *plugin.Context, channel *model.Channel
|
||||
_m.Called(c, channel)
|
||||
}
|
||||
|
||||
// ConfigurationWillBeSaved provides a mock function with given fields: newCfg
|
||||
func (_m *Hooks) ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error) {
|
||||
ret := _m.Called(newCfg)
|
||||
|
||||
var r0 *model.Config
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(*model.Config) (*model.Config, error)); ok {
|
||||
return rf(newCfg)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(*model.Config) *model.Config); ok {
|
||||
r0 = rf(newCfg)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Config)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(*model.Config) error); ok {
|
||||
r1 = rf(newCfg)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ExecuteCommand provides a mock function with given fields: c, args
|
||||
func (_m *Hooks) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
|
||||
ret := _m.Called(c, args)
|
||||
|
||||
@@ -138,6 +138,10 @@ type GetTopicMetadataByIdsIFace interface {
|
||||
GetTopicMetadataByIds(c *Context, topicType string, topicIds []string) (map[string]*model.TopicMetadata, error)
|
||||
}
|
||||
|
||||
type ConfigurationWillBeSavedIFace interface {
|
||||
ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error)
|
||||
}
|
||||
|
||||
type HooksAdapter struct {
|
||||
implemented map[int]struct{}
|
||||
productHooks any
|
||||
@@ -430,6 +434,15 @@ func NewAdapter(productHooks any) (*HooksAdapter, error) {
|
||||
return nil, errors.New("hook has GetTopicMetadataByIds method but does not implement plugin.GetTopicMetadataByIds interface")
|
||||
}
|
||||
|
||||
// Assessing the type of the productHooks if it individually implements ConfigurationWillBeSaved interface.
|
||||
tt = reflect.TypeOf((*ConfigurationWillBeSavedIFace)(nil)).Elem()
|
||||
|
||||
if ft.Implements(tt) {
|
||||
a.implemented[ConfigurationWillBeSavedID] = struct{}{}
|
||||
} else if _, ok := ft.MethodByName("ConfigurationWillBeSaved"); ok {
|
||||
return nil, errors.New("hook has ConfigurationWillBeSaved method but does not implement plugin.ConfigurationWillBeSaved interface")
|
||||
}
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
@@ -711,3 +724,12 @@ func (a *HooksAdapter) GetTopicMetadataByIds(c *Context, topicType string, topic
|
||||
return a.productHooks.(GetTopicMetadataByIdsIFace).GetTopicMetadataByIds(c, topicType, topicIds)
|
||||
|
||||
}
|
||||
|
||||
func (a *HooksAdapter) ConfigurationWillBeSaved(newCfg *model.Config) (*model.Config, error) {
|
||||
if _, ok := a.implemented[ConfigurationWillBeSavedID]; !ok {
|
||||
panic("product hooks must implement ConfigurationWillBeSaved")
|
||||
}
|
||||
|
||||
return a.productHooks.(ConfigurationWillBeSavedIFace).ConfigurationWillBeSaved(newCfg)
|
||||
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user