PLT-6019: Add APIv4 Endpoint for restoring Channels (#6263)
Этот коммит содержится в:
коммит произвёл
Joram Wilander
родитель
34728f748b
Коммит
0a20e8d326
@@ -29,6 +29,7 @@ func InitChannel() {
|
||||
BaseRoutes.Channel.Handle("", ApiSessionRequired(getChannel)).Methods("GET")
|
||||
BaseRoutes.Channel.Handle("", ApiSessionRequired(updateChannel)).Methods("PUT")
|
||||
BaseRoutes.Channel.Handle("/patch", ApiSessionRequired(patchChannel)).Methods("PUT")
|
||||
BaseRoutes.Channel.Handle("/restore", ApiSessionRequired(restoreChannel)).Methods("POST")
|
||||
BaseRoutes.Channel.Handle("", ApiSessionRequired(deleteChannel)).Methods("DELETE")
|
||||
BaseRoutes.Channel.Handle("/stats", ApiSessionRequired(getChannelStats)).Methods("GET")
|
||||
BaseRoutes.Channel.Handle("/pinned", ApiSessionRequired(getPinnedPosts)).Methods("GET")
|
||||
@@ -180,6 +181,36 @@ func patchChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func restoreChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
c.RequireChannelId()
|
||||
if c.Err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var channel *model.Channel
|
||||
var err *model.AppError
|
||||
if channel, err = app.GetChannel(c.Params.ChannelId); err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
teamId := channel.TeamId
|
||||
|
||||
if !app.SessionHasPermissionToTeam(c.Session, teamId, model.PERMISSION_MANAGE_TEAM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_TEAM)
|
||||
return
|
||||
}
|
||||
|
||||
channel, err = app.RestoreChannel(channel)
|
||||
if err != nil {
|
||||
c.Err = err
|
||||
return
|
||||
}
|
||||
|
||||
c.LogAudit("name=" + channel.Name)
|
||||
w.Write([]byte(channel.ToJson()))
|
||||
|
||||
}
|
||||
|
||||
func CanManageChannel(c *Context, channel *model.Channel) bool {
|
||||
if channel.Type == model.CHANNEL_OPEN && !app.SessionHasPermissionToChannel(c.Session, channel.Id, model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES)
|
||||
|
||||
@@ -1067,6 +1067,32 @@ func TestDeleteChannel(t *testing.T) {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
|
||||
func TestRestoreChannel(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
defer TearDown()
|
||||
Client := th.Client
|
||||
|
||||
publicChannel1 := th.CreatePublicChannel()
|
||||
Client.DeleteChannel(publicChannel1.Id)
|
||||
|
||||
privateChannel1 := th.CreatePrivateChannel()
|
||||
Client.DeleteChannel(privateChannel1.Id)
|
||||
|
||||
_, resp := Client.RestoreChannel(publicChannel1.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
_, resp = Client.RestoreChannel(privateChannel1.Id)
|
||||
CheckForbiddenStatus(t, resp)
|
||||
|
||||
th.LoginTeamAdmin()
|
||||
|
||||
_, resp = Client.RestoreChannel(publicChannel1.Id)
|
||||
CheckOKStatus(t, resp)
|
||||
|
||||
_, resp = Client.RestoreChannel(privateChannel1.Id)
|
||||
CheckOKStatus(t, resp)
|
||||
}
|
||||
|
||||
func TestGetChannelByName(t *testing.T) {
|
||||
th := Setup().InitBasic().InitSystemAdmin()
|
||||
defer TearDown()
|
||||
|
||||
@@ -285,6 +285,14 @@ func UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) {
|
||||
}
|
||||
}
|
||||
|
||||
func RestoreChannel(channel *model.Channel) (*model.Channel, *model.AppError) {
|
||||
if result := <-Srv.Store.Channel().Restore(channel.Id, model.GetMillis()); result.Err != nil {
|
||||
return nil, result.Err
|
||||
} else {
|
||||
return channel, nil
|
||||
}
|
||||
}
|
||||
|
||||
func PatchChannel(channel *model.Channel, patch *model.ChannelPatch, userId string) (*model.Channel, *model.AppError) {
|
||||
oldChannelDisplayName := channel.DisplayName
|
||||
oldChannelHeader := channel.Header
|
||||
|
||||
@@ -1217,6 +1217,16 @@ func (c *Client4) PatchChannel(channelId string, patch *ChannelPatch) (*Channel,
|
||||
}
|
||||
}
|
||||
|
||||
// RestoreChannel restores a previously deleted channel. Any missing fields are not updated.
|
||||
func (c *Client4) RestoreChannel(channelId string) (*Channel, *Response) {
|
||||
if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/restore", ""); err != nil {
|
||||
return nil, &Response{StatusCode: r.StatusCode, Error: err}
|
||||
} else {
|
||||
defer closeBody(r)
|
||||
return ChannelFromJson(r.Body), BuildResponse(r)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateDirectChannel creates a direct message channel based on the two user
|
||||
// ids provided.
|
||||
func (c *Client4) CreateDirectChannel(userId1, userId2 string) (*Channel, *Response) {
|
||||
|
||||
@@ -440,6 +440,10 @@ func (s SqlChannelStore) Delete(channelId string, time int64) StoreChannel {
|
||||
return s.SetDeleteAt(channelId, time, time)
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) Restore(channelId string, time int64) StoreChannel {
|
||||
return s.SetDeleteAt(channelId, 0, time)
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) SetDeleteAt(channelId string, deleteAt int64, updateAt int64) StoreChannel {
|
||||
storeChannel := make(StoreChannel, 1)
|
||||
|
||||
|
||||
@@ -364,6 +364,34 @@ func TestChannelStoreGetForPost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSqlChannelStoreRestore(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
o1 := model.Channel{}
|
||||
o1.TeamId = model.NewId()
|
||||
o1.DisplayName = "Channel1"
|
||||
o1.Name = "a" + model.NewId() + "b"
|
||||
o1.Type = model.CHANNEL_OPEN
|
||||
Must(store.Channel().Save(&o1))
|
||||
|
||||
if r := <-store.Channel().Delete(o1.Id, model.GetMillis()); r.Err != nil {
|
||||
t.Fatal(r.Err)
|
||||
}
|
||||
|
||||
if r := <-store.Channel().Get(o1.Id, false); r.Data.(*model.Channel).DeleteAt == 0 {
|
||||
t.Fatal("should have been deleted")
|
||||
}
|
||||
|
||||
if r := <-store.Channel().Restore(o1.Id, model.GetMillis()); r.Err != nil {
|
||||
t.Fatal(r.Err)
|
||||
}
|
||||
|
||||
if r := <-store.Channel().Get(o1.Id, false); r.Data.(*model.Channel).DeleteAt != 0 {
|
||||
t.Fatal("should have been restored")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestChannelStoreDelete(t *testing.T) {
|
||||
Setup()
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ type ChannelStore interface {
|
||||
InvalidateChannelByName(teamId, name string)
|
||||
GetFromMaster(id string) StoreChannel
|
||||
Delete(channelId string, time int64) StoreChannel
|
||||
Restore(channelId string, time int64) StoreChannel
|
||||
SetDeleteAt(channelId string, deleteAt int64, updateAt int64) StoreChannel
|
||||
PermanentDeleteByTeam(teamId string) StoreChannel
|
||||
PermanentDelete(channelId string) StoreChannel
|
||||
|
||||
Ссылка в новой задаче
Block a user