MM-10516: Added support for PostActions in ephemeral posts (#10258)
* Added support for PostActions in ephemeral posts The general approach is that we take all the metadata that DoPostAction needs to process client DoPostActionRequests, and store it in a serialized, encrypted Cookie field, in the PostAction struct. The client then must send it back, and it is then used to process PostActions as a fallback top the metadata in the database. This PR adds a new config setting, `ServiceSettings.ActionCookieSecret`. In a cluster environment it must be the same for all instances. - Added type PostActionCookie, and a Cookie string to PostAction. - Added App.AddActionCookiesToPost. - Use App.AddActionCookiesToPost in api4.createEphemeralPost, App.SendEphemeralPost, App.UpdateEphemeralPost. - Added App.DoPostActionWithCookie to process incoming requests with cookies. For backward compatibility, it prefers the metadata in the database; falls back to cookie. - Added plugin.API.UpdateEphemeralPost and plugin.API.DeleteEphemeralPost. - Added App.encryptActionCookie/App.decryptActionCookie. * Style * Fixed an unfortunate typo, tested with matterpoll * minor PR feedback * Fixed uninitialized Context * Fixed another test failure * Fixed permission check * Added api test for DoPostActionWithCookie * Replaced config.ActionCookieSecret with Server.PostActionCookieSecret Modeled after AsymetricSigningKey * style * Set DeleteAt in DeleteEphemeralPost * PR feedback * Removed deadwood comment * Added EXPERIMENTAL comment to the 2 APIs in question
Этот коммит содержится в:
@@ -287,6 +287,14 @@ type API interface {
|
||||
// SendEphemeralPost creates an ephemeral post.
|
||||
SendEphemeralPost(userId string, post *model.Post) *model.Post
|
||||
|
||||
// UpdateEphemeralPost updates an ephemeral message previously sent to the user.
|
||||
// EXPERIMENTAL: This API is experimental and can be changed without advance notice.
|
||||
UpdateEphemeralPost(userId string, post *model.Post) *model.Post
|
||||
|
||||
// DeleteEphemeralPost deletes an ephemeral message previously sent to the user.
|
||||
// EXPERIMENTAL: This API is experimental and can be changed without advance notice.
|
||||
DeleteEphemeralPost(userId string, post *model.Post)
|
||||
|
||||
// DeletePost deletes a post.
|
||||
DeletePost(postId string) *model.AppError
|
||||
|
||||
|
||||
@@ -2502,6 +2502,63 @@ func (s *apiRPCServer) SendEphemeralPost(args *Z_SendEphemeralPostArgs, returns
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_UpdateEphemeralPostArgs struct {
|
||||
A string
|
||||
B *model.Post
|
||||
}
|
||||
|
||||
type Z_UpdateEphemeralPostReturns struct {
|
||||
A *model.Post
|
||||
}
|
||||
|
||||
func (g *apiRPCClient) UpdateEphemeralPost(userId string, post *model.Post) *model.Post {
|
||||
_args := &Z_UpdateEphemeralPostArgs{userId, post}
|
||||
_returns := &Z_UpdateEphemeralPostReturns{}
|
||||
if err := g.client.Call("Plugin.UpdateEphemeralPost", _args, _returns); err != nil {
|
||||
log.Printf("RPC call to UpdateEphemeralPost API failed: %s", err.Error())
|
||||
}
|
||||
return _returns.A
|
||||
}
|
||||
|
||||
func (s *apiRPCServer) UpdateEphemeralPost(args *Z_UpdateEphemeralPostArgs, returns *Z_UpdateEphemeralPostReturns) error {
|
||||
if hook, ok := s.impl.(interface {
|
||||
UpdateEphemeralPost(userId string, post *model.Post) *model.Post
|
||||
}); ok {
|
||||
returns.A = hook.UpdateEphemeralPost(args.A, args.B)
|
||||
} else {
|
||||
return encodableError(fmt.Errorf("API UpdateEphemeralPost called but not implemented."))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_DeleteEphemeralPostArgs struct {
|
||||
A string
|
||||
B *model.Post
|
||||
}
|
||||
|
||||
type Z_DeleteEphemeralPostReturns struct {
|
||||
}
|
||||
|
||||
func (g *apiRPCClient) DeleteEphemeralPost(userId string, post *model.Post) {
|
||||
_args := &Z_DeleteEphemeralPostArgs{userId, post}
|
||||
_returns := &Z_DeleteEphemeralPostReturns{}
|
||||
if err := g.client.Call("Plugin.DeleteEphemeralPost", _args, _returns); err != nil {
|
||||
log.Printf("RPC call to DeleteEphemeralPost API failed: %s", err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *apiRPCServer) DeleteEphemeralPost(args *Z_DeleteEphemeralPostArgs, returns *Z_DeleteEphemeralPostReturns) error {
|
||||
if hook, ok := s.impl.(interface {
|
||||
DeleteEphemeralPost(userId string, post *model.Post)
|
||||
}); ok {
|
||||
hook.DeleteEphemeralPost(args.A, args.B)
|
||||
} else {
|
||||
return encodableError(fmt.Errorf("API DeleteEphemeralPost called but not implemented."))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Z_DeletePostArgs struct {
|
||||
A string
|
||||
}
|
||||
|
||||
@@ -2124,6 +2124,35 @@ func (_m *API) SendEphemeralPost(userId string, post *model.Post) *model.Post {
|
||||
return r0
|
||||
}
|
||||
|
||||
// UpdateEphemeralPost provides a mock function with given fields: userId, post
|
||||
func (_m *API) UpdateEphemeralPost(userId string, post *model.Post) *model.Post {
|
||||
ret := _m.Called(userId, post)
|
||||
|
||||
var r0 *model.Post
|
||||
if rf, ok := ret.Get(0).(func(string, *model.Post) *model.Post); ok {
|
||||
r0 = rf(userId, post)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Post)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteEphemeralPost provides a mock function with given fields: userId, post
|
||||
func (_m *API) DeleteEphemeralPost(userId string, post *model.Post) {
|
||||
ret := _m.Called(userId, post)
|
||||
|
||||
if rf, ok := ret.Get(0).(func(string, *model.Post) *model.Post); ok {
|
||||
_ = rf(userId, post)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
_ = ret.Get(0).(*model.Post)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SendMail provides a mock function with given fields: to, subject, htmlBody
|
||||
func (_m *API) SendMail(to string, subject string, htmlBody string) *model.AppError {
|
||||
ret := _m.Called(to, subject, htmlBody)
|
||||
|
||||
Ссылка в новой задаче
Block a user