github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/api4/webhook_test.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"bytes"
     8  	"net/http"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  )
    15  
    16  func TestCreateIncomingWebhook(t *testing.T) {
    17  	th := Setup().InitBasic().InitSystemAdmin()
    18  	defer th.TearDown()
    19  	Client := th.Client
    20  
    21  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
    22  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = true })
    23  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = true })
    24  
    25  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    26  	defer func() {
    27  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    28  	}()
    29  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    30  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    31  
    32  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
    33  
    34  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
    35  	CheckNoError(t, resp)
    36  
    37  	if rhook.ChannelId != hook.ChannelId {
    38  		t.Fatal("channel ids didn't match")
    39  	}
    40  
    41  	if rhook.UserId != th.SystemAdminUser.Id {
    42  		t.Fatal("user ids didn't match")
    43  	}
    44  
    45  	if rhook.TeamId != th.BasicTeam.Id {
    46  		t.Fatal("team ids didn't match")
    47  	}
    48  
    49  	hook.ChannelId = "junk"
    50  	_, resp = th.SystemAdminClient.CreateIncomingWebhook(hook)
    51  	CheckNotFoundStatus(t, resp)
    52  
    53  	hook.ChannelId = th.BasicChannel.Id
    54  	th.LoginTeamAdmin()
    55  	_, resp = Client.CreateIncomingWebhook(hook)
    56  	CheckNoError(t, resp)
    57  
    58  	th.LoginBasic()
    59  	_, resp = Client.CreateIncomingWebhook(hook)
    60  	CheckForbiddenStatus(t, resp)
    61  
    62  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    63  
    64  	_, resp = Client.CreateIncomingWebhook(hook)
    65  	CheckNoError(t, resp)
    66  
    67  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = false })
    68  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = false })
    69  
    70  	_, resp = Client.CreateIncomingWebhook(hook)
    71  	CheckNoError(t, resp)
    72  
    73  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
    74  	_, resp = Client.CreateIncomingWebhook(hook)
    75  	CheckNotImplementedStatus(t, resp)
    76  }
    77  
    78  func TestGetIncomingWebhooks(t *testing.T) {
    79  	th := Setup().InitBasic().InitSystemAdmin()
    80  	defer th.TearDown()
    81  	Client := th.Client
    82  
    83  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
    84  
    85  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    86  	defer func() {
    87  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    88  	}()
    89  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    90  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    91  
    92  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
    93  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
    94  	CheckNoError(t, resp)
    95  
    96  	hooks, resp := th.SystemAdminClient.GetIncomingWebhooks(0, 1000, "")
    97  	CheckNoError(t, resp)
    98  
    99  	found := false
   100  	for _, h := range hooks {
   101  		if rhook.Id == h.Id {
   102  			found = true
   103  		}
   104  	}
   105  
   106  	if !found {
   107  		t.Fatal("missing hook")
   108  	}
   109  
   110  	hooks, resp = th.SystemAdminClient.GetIncomingWebhooks(0, 1, "")
   111  	CheckNoError(t, resp)
   112  
   113  	if len(hooks) != 1 {
   114  		t.Fatal("should only be 1")
   115  	}
   116  
   117  	hooks, resp = th.SystemAdminClient.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   118  	CheckNoError(t, resp)
   119  
   120  	found = false
   121  	for _, h := range hooks {
   122  		if rhook.Id == h.Id {
   123  			found = true
   124  		}
   125  	}
   126  
   127  	if !found {
   128  		t.Fatal("missing hook")
   129  	}
   130  
   131  	hooks, resp = th.SystemAdminClient.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
   132  	CheckNoError(t, resp)
   133  
   134  	if len(hooks) != 0 {
   135  		t.Fatal("no hooks should be returned")
   136  	}
   137  
   138  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   139  	CheckForbiddenStatus(t, resp)
   140  
   141  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   142  
   143  	_, resp = Client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   144  	CheckNoError(t, resp)
   145  
   146  	_, resp = Client.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
   147  	CheckForbiddenStatus(t, resp)
   148  
   149  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   150  	CheckForbiddenStatus(t, resp)
   151  
   152  	Client.Logout()
   153  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   154  	CheckUnauthorizedStatus(t, resp)
   155  }
   156  
   157  func TestGetIncomingWebhook(t *testing.T) {
   158  	th := Setup().InitBasic().InitSystemAdmin()
   159  	defer th.TearDown()
   160  	Client := th.SystemAdminClient
   161  
   162  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   163  
   164  	var resp *model.Response
   165  	var rhook *model.IncomingWebhook
   166  	var hook *model.IncomingWebhook
   167  
   168  	t.Run("WhenHookExists", func(t *testing.T) {
   169  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   170  		rhook, resp = Client.CreateIncomingWebhook(hook)
   171  		CheckNoError(t, resp)
   172  
   173  		hook, resp = Client.GetIncomingWebhook(rhook.Id, "")
   174  		CheckOKStatus(t, resp)
   175  	})
   176  
   177  	t.Run("WhenHookDoesNotExist", func(t *testing.T) {
   178  		hook, resp = Client.GetIncomingWebhook(model.NewId(), "")
   179  		CheckNotFoundStatus(t, resp)
   180  	})
   181  
   182  	t.Run("WhenInvalidHookID", func(t *testing.T) {
   183  		hook, resp = Client.GetIncomingWebhook("abc", "")
   184  		CheckBadRequestStatus(t, resp)
   185  	})
   186  
   187  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   188  		th.LoginBasic()
   189  		Client = th.Client
   190  
   191  		_, resp = Client.GetIncomingWebhook(rhook.Id, "")
   192  		CheckForbiddenStatus(t, resp)
   193  	})
   194  }
   195  
   196  func TestDeleteIncomingWebhook(t *testing.T) {
   197  	th := Setup().InitBasic().InitSystemAdmin()
   198  	defer th.TearDown()
   199  	Client := th.SystemAdminClient
   200  
   201  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   202  
   203  	var resp *model.Response
   204  	var rhook *model.IncomingWebhook
   205  	var hook *model.IncomingWebhook
   206  	var status bool
   207  
   208  	t.Run("WhenInvalidHookID", func(t *testing.T) {
   209  		status, resp = Client.DeleteIncomingWebhook("abc")
   210  		CheckBadRequestStatus(t, resp)
   211  	})
   212  
   213  	t.Run("WhenHookDoesNotExist", func(t *testing.T) {
   214  		status, resp = Client.DeleteIncomingWebhook(model.NewId())
   215  		CheckNotFoundStatus(t, resp)
   216  	})
   217  
   218  	t.Run("WhenHookExists", func(t *testing.T) {
   219  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   220  		rhook, resp = Client.CreateIncomingWebhook(hook)
   221  		CheckNoError(t, resp)
   222  
   223  		if status, resp = Client.DeleteIncomingWebhook(rhook.Id); !status {
   224  			t.Fatal("Delete should have succeeded")
   225  		} else {
   226  			CheckOKStatus(t, resp)
   227  		}
   228  
   229  		// Get now should not return this deleted hook
   230  		_, resp = Client.GetIncomingWebhook(rhook.Id, "")
   231  		CheckNotFoundStatus(t, resp)
   232  	})
   233  
   234  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   235  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   236  		rhook, resp = Client.CreateIncomingWebhook(hook)
   237  		CheckNoError(t, resp)
   238  
   239  		th.LoginBasic()
   240  		Client = th.Client
   241  
   242  		_, resp = Client.DeleteIncomingWebhook(rhook.Id)
   243  		CheckForbiddenStatus(t, resp)
   244  	})
   245  }
   246  
   247  func TestCreateOutgoingWebhook(t *testing.T) {
   248  	th := Setup().InitBasic().InitSystemAdmin()
   249  	defer th.TearDown()
   250  	Client := th.Client
   251  
   252  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   253  
   254  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   255  	defer func() {
   256  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   257  	}()
   258  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   259  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   260  
   261  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   262  
   263  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   264  	CheckNoError(t, resp)
   265  
   266  	if rhook.ChannelId != hook.ChannelId {
   267  		t.Fatal("channel ids didn't match")
   268  	} else if rhook.CreatorId != th.SystemAdminUser.Id {
   269  		t.Fatal("user ids didn't match")
   270  	} else if rhook.TeamId != th.BasicChannel.TeamId {
   271  		t.Fatal("team ids didn't match")
   272  	}
   273  
   274  	hook.ChannelId = "junk"
   275  	_, resp = th.SystemAdminClient.CreateOutgoingWebhook(hook)
   276  	CheckNotFoundStatus(t, resp)
   277  
   278  	hook.ChannelId = th.BasicChannel.Id
   279  	th.LoginTeamAdmin()
   280  	_, resp = Client.CreateOutgoingWebhook(hook)
   281  	CheckNoError(t, resp)
   282  
   283  	th.LoginBasic()
   284  	_, resp = Client.CreateOutgoingWebhook(hook)
   285  	CheckForbiddenStatus(t, resp)
   286  
   287  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   288  
   289  	_, resp = Client.CreateOutgoingWebhook(hook)
   290  	CheckNoError(t, resp)
   291  
   292  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   293  	_, resp = Client.CreateOutgoingWebhook(hook)
   294  	CheckNotImplementedStatus(t, resp)
   295  }
   296  
   297  func TestGetOutgoingWebhooks(t *testing.T) {
   298  	th := Setup().InitBasic().InitSystemAdmin()
   299  	defer th.TearDown()
   300  	Client := th.Client
   301  
   302  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   303  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   304  	defer func() {
   305  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   306  	}()
   307  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   308  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   309  
   310  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   311  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   312  	CheckNoError(t, resp)
   313  
   314  	hooks, resp := th.SystemAdminClient.GetOutgoingWebhooks(0, 1000, "")
   315  	CheckNoError(t, resp)
   316  
   317  	found := false
   318  	for _, h := range hooks {
   319  		if rhook.Id == h.Id {
   320  			found = true
   321  		}
   322  	}
   323  
   324  	if !found {
   325  		t.Fatal("missing hook")
   326  	}
   327  
   328  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooks(0, 1, "")
   329  	CheckNoError(t, resp)
   330  
   331  	if len(hooks) != 1 {
   332  		t.Fatal("should only be 1")
   333  	}
   334  
   335  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   336  	CheckNoError(t, resp)
   337  
   338  	found = false
   339  	for _, h := range hooks {
   340  		if rhook.Id == h.Id {
   341  			found = true
   342  		}
   343  	}
   344  
   345  	if !found {
   346  		t.Fatal("missing hook")
   347  	}
   348  
   349  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
   350  	CheckNoError(t, resp)
   351  
   352  	if len(hooks) != 0 {
   353  		t.Fatal("no hooks should be returned")
   354  	}
   355  
   356  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   357  	CheckNoError(t, resp)
   358  
   359  	found = false
   360  	for _, h := range hooks {
   361  		if rhook.Id == h.Id {
   362  			found = true
   363  		}
   364  	}
   365  
   366  	if !found {
   367  		t.Fatal("missing hook")
   368  	}
   369  
   370  	hooks, resp = th.SystemAdminClient.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
   371  	CheckForbiddenStatus(t, resp)
   372  
   373  	_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
   374  	CheckForbiddenStatus(t, resp)
   375  
   376  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   377  
   378  	_, resp = Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   379  	CheckNoError(t, resp)
   380  
   381  	_, resp = Client.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
   382  	CheckForbiddenStatus(t, resp)
   383  
   384  	_, resp = Client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   385  	CheckNoError(t, resp)
   386  
   387  	_, resp = Client.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
   388  	CheckForbiddenStatus(t, resp)
   389  
   390  	_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
   391  	CheckForbiddenStatus(t, resp)
   392  
   393  	Client.Logout()
   394  	_, resp = Client.GetOutgoingWebhooks(0, 1000, "")
   395  	CheckUnauthorizedStatus(t, resp)
   396  }
   397  
   398  func TestGetOutgoingWebhook(t *testing.T) {
   399  	th := Setup().InitBasic().InitSystemAdmin()
   400  	defer th.TearDown()
   401  	Client := th.Client
   402  
   403  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   404  
   405  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   406  
   407  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   408  	CheckNoError(t, resp)
   409  
   410  	getHook, resp := th.SystemAdminClient.GetOutgoingWebhook(rhook.Id)
   411  	CheckNoError(t, resp)
   412  	if getHook.Id != rhook.Id {
   413  		t.Fatal("failed to retrieve the correct outgoing hook")
   414  	}
   415  
   416  	_, resp = Client.GetOutgoingWebhook(rhook.Id)
   417  	CheckForbiddenStatus(t, resp)
   418  
   419  	nonExistentHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id}
   420  	_, resp = th.SystemAdminClient.GetOutgoingWebhook(nonExistentHook.Id)
   421  	CheckNotFoundStatus(t, resp)
   422  
   423  	nonExistentHook.Id = model.NewId()
   424  	_, resp = th.SystemAdminClient.GetOutgoingWebhook(nonExistentHook.Id)
   425  	CheckInternalErrorStatus(t, resp)
   426  }
   427  
   428  func TestUpdateIncomingHook(t *testing.T) {
   429  	th := Setup().InitBasic().InitSystemAdmin()
   430  	defer th.TearDown()
   431  	Client := th.Client
   432  
   433  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   434  
   435  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   436  	defer func() {
   437  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   438  	}()
   439  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   440  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   441  
   442  	hook1 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   443  
   444  	createdHook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook1)
   445  	CheckNoError(t, resp)
   446  
   447  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = false })
   448  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = false })
   449  
   450  	t.Run("UpdateIncomingHook, overrides disabled", func(t *testing.T) {
   451  		createdHook.DisplayName = "hook2"
   452  		createdHook.Description = "description"
   453  		createdHook.ChannelId = th.BasicChannel2.Id
   454  		createdHook.Username = "username"
   455  		createdHook.IconURL = "icon"
   456  
   457  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   458  		CheckNoError(t, resp)
   459  		if updatedHook != nil {
   460  			if updatedHook.DisplayName != "hook2" {
   461  				t.Fatal("Hook name is not updated")
   462  			}
   463  
   464  			if updatedHook.Description != "description" {
   465  				t.Fatal("Hook description is not updated")
   466  			}
   467  
   468  			if updatedHook.ChannelId != th.BasicChannel2.Id {
   469  				t.Fatal("Hook channel is not updated")
   470  			}
   471  
   472  			if updatedHook.Username != "" {
   473  				t.Fatal("Hook username was incorrectly updated")
   474  			}
   475  
   476  			if updatedHook.IconURL != "" {
   477  				t.Fatal("Hook icon was incorrectly updated")
   478  			}
   479  		} else {
   480  			t.Fatal("should not be nil")
   481  		}
   482  
   483  		//updatedHook, _ = th.App.GetIncomingWebhook(createdHook.Id)
   484  		assert.Equal(t, updatedHook.ChannelId, createdHook.ChannelId)
   485  	})
   486  
   487  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostUsernameOverride = true })
   488  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnablePostIconOverride = true })
   489  
   490  	t.Run("UpdateIncomingHook", func(t *testing.T) {
   491  		createdHook.DisplayName = "hook2"
   492  		createdHook.Description = "description"
   493  		createdHook.ChannelId = th.BasicChannel2.Id
   494  		createdHook.Username = "username"
   495  		createdHook.IconURL = "icon"
   496  
   497  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   498  		CheckNoError(t, resp)
   499  		if updatedHook != nil {
   500  			if updatedHook.DisplayName != "hook2" {
   501  				t.Fatal("Hook name is not updated")
   502  			}
   503  
   504  			if updatedHook.Description != "description" {
   505  				t.Fatal("Hook description is not updated")
   506  			}
   507  
   508  			if updatedHook.ChannelId != th.BasicChannel2.Id {
   509  				t.Fatal("Hook channel is not updated")
   510  			}
   511  
   512  			if updatedHook.Username != "username" {
   513  				t.Fatal("Hook username is not updated")
   514  			}
   515  
   516  			if updatedHook.IconURL != "icon" {
   517  				t.Fatal("Hook icon is not updated")
   518  			}
   519  		} else {
   520  			t.Fatal("should not be nil")
   521  		}
   522  
   523  		//updatedHook, _ = th.App.GetIncomingWebhook(createdHook.Id)
   524  		assert.Equal(t, updatedHook.ChannelId, createdHook.ChannelId)
   525  	})
   526  
   527  	t.Run("RetainCreateAt", func(t *testing.T) {
   528  		hook2 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, CreateAt: 100}
   529  
   530  		createdHook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook2)
   531  		CheckNoError(t, resp)
   532  
   533  		createdHook.DisplayName = "Name2"
   534  
   535  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   536  		CheckNoError(t, resp)
   537  		if updatedHook != nil {
   538  			if updatedHook.CreateAt != createdHook.CreateAt {
   539  				t.Fatal("failed - hook create at should not be changed")
   540  			}
   541  		} else {
   542  			t.Fatal("should not be nil")
   543  		}
   544  	})
   545  
   546  	t.Run("ModifyUpdateAt", func(t *testing.T) {
   547  		createdHook.DisplayName = "Name3"
   548  
   549  		updatedHook, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   550  		CheckNoError(t, resp)
   551  		if updatedHook != nil {
   552  			if updatedHook.UpdateAt == createdHook.UpdateAt {
   553  				t.Fatal("failed - hook updateAt is not updated")
   554  			}
   555  		} else {
   556  			t.Fatal("should not be nil")
   557  		}
   558  	})
   559  
   560  	t.Run("UpdateNonExistentHook", func(t *testing.T) {
   561  		nonExistentHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   562  
   563  		_, resp := th.SystemAdminClient.UpdateIncomingWebhook(nonExistentHook)
   564  		CheckNotFoundStatus(t, resp)
   565  
   566  		nonExistentHook.Id = model.NewId()
   567  		_, resp = th.SystemAdminClient.UpdateIncomingWebhook(nonExistentHook)
   568  		CheckNotFoundStatus(t, resp)
   569  	})
   570  
   571  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
   572  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   573  		CheckForbiddenStatus(t, resp)
   574  	})
   575  
   576  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   577  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   578  
   579  	t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
   580  		th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   581  
   582  		t.Run("UpdateHookOfSameUser", func(t *testing.T) {
   583  			sameUserHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, UserId: th.BasicUser2.Id}
   584  
   585  			sameUserHook, resp := Client.CreateIncomingWebhook(sameUserHook)
   586  			CheckNoError(t, resp)
   587  
   588  			_, resp = Client.UpdateIncomingWebhook(sameUserHook)
   589  			CheckNoError(t, resp)
   590  		})
   591  
   592  		t.Run("UpdateHookOfDifferentUser", func(t *testing.T) {
   593  			_, resp := Client.UpdateIncomingWebhook(createdHook)
   594  			CheckForbiddenStatus(t, resp)
   595  		})
   596  	})
   597  
   598  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   599  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   600  
   601  	Client.Logout()
   602  	th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
   603  	th.LoginBasic2()
   604  	t.Run("UpdateByDifferentUser", func(t *testing.T) {
   605  		updatedHook, resp := Client.UpdateIncomingWebhook(createdHook)
   606  		CheckNoError(t, resp)
   607  		if updatedHook.UserId == th.BasicUser2.Id {
   608  			t.Fatal("Hook's creator userId is not retained")
   609  		}
   610  	})
   611  
   612  	t.Run("IncomingHooksDisabled", func(t *testing.T) {
   613  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false })
   614  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   615  		CheckNotImplementedStatus(t, resp)
   616  		CheckErrorMessage(t, resp, "api.incoming_webhook.disabled.app_error")
   617  	})
   618  
   619  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   620  
   621  	t.Run("PrivateChannel", func(t *testing.T) {
   622  		privateChannel := th.CreatePrivateChannel()
   623  		Client.Logout()
   624  		th.LoginBasic()
   625  		createdHook.ChannelId = privateChannel.Id
   626  
   627  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   628  		CheckForbiddenStatus(t, resp)
   629  	})
   630  
   631  	t.Run("UpdateToNonExistentChannel", func(t *testing.T) {
   632  		createdHook.ChannelId = "junk"
   633  		_, resp := th.SystemAdminClient.UpdateIncomingWebhook(createdHook)
   634  		CheckNotFoundStatus(t, resp)
   635  	})
   636  
   637  	team := th.CreateTeamWithClient(Client)
   638  	user := th.CreateUserWithClient(Client)
   639  	th.LinkUserToTeam(user, team)
   640  	Client.Logout()
   641  	Client.Login(user.Id, user.Password)
   642  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   643  		_, resp := Client.UpdateIncomingWebhook(createdHook)
   644  		CheckUnauthorizedStatus(t, resp)
   645  	})
   646  }
   647  
   648  func TestRegenOutgoingHookToken(t *testing.T) {
   649  	th := Setup().InitBasic().InitSystemAdmin()
   650  	defer th.TearDown()
   651  	Client := th.Client
   652  
   653  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   654  
   655  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   656  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   657  	CheckNoError(t, resp)
   658  
   659  	_, resp = th.SystemAdminClient.RegenOutgoingHookToken("junk")
   660  	CheckBadRequestStatus(t, resp)
   661  
   662  	//investigate why is act weird on jenkins
   663  	// _, resp = th.SystemAdminClient.RegenOutgoingHookToken("")
   664  	// CheckNotFoundStatus(t, resp)
   665  
   666  	regenHookToken, resp := th.SystemAdminClient.RegenOutgoingHookToken(rhook.Id)
   667  	CheckNoError(t, resp)
   668  	if regenHookToken.Token == rhook.Token {
   669  		t.Fatal("regen didn't work properly")
   670  	}
   671  
   672  	_, resp = Client.RegenOutgoingHookToken(rhook.Id)
   673  	CheckForbiddenStatus(t, resp)
   674  
   675  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   676  	_, resp = th.SystemAdminClient.RegenOutgoingHookToken(rhook.Id)
   677  	CheckNotImplementedStatus(t, resp)
   678  }
   679  
   680  func TestUpdateOutgoingHook(t *testing.T) {
   681  	th := Setup().InitBasic().InitSystemAdmin()
   682  	defer th.TearDown()
   683  	Client := th.Client
   684  
   685  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   686  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   687  	defer func() {
   688  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   689  	}()
   690  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   691  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   692  
   693  	createdHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   694  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
   695  
   696  	createdHook, resp := th.SystemAdminClient.CreateOutgoingWebhook(createdHook)
   697  	CheckNoError(t, resp)
   698  
   699  	t.Run("UpdateOutgoingWebhook", func(t *testing.T) {
   700  		createdHook.DisplayName = "Cats"
   701  		createdHook.Description = "Get me some cats"
   702  
   703  		updatedHook, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   704  		CheckNoError(t, resp)
   705  		if updatedHook.DisplayName != "Cats" {
   706  			t.Fatal("did not update")
   707  		}
   708  		if updatedHook.Description != "Get me some cats" {
   709  			t.Fatal("did not update")
   710  		}
   711  	})
   712  
   713  	t.Run("OutgoingHooksDisabled", func(t *testing.T) {
   714  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   715  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   716  		CheckNotImplementedStatus(t, resp)
   717  	})
   718  
   719  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   720  	t.Run("RetainCreateAt", func(t *testing.T) {
   721  		hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   722  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
   723  
   724  		createdHook2, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook2)
   725  		CheckNoError(t, resp)
   726  		createdHook2.DisplayName = "Name2"
   727  
   728  		updatedHook2, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook2)
   729  		CheckNoError(t, resp)
   730  
   731  		if updatedHook2.CreateAt != createdHook2.CreateAt {
   732  			t.Fatal("failed - hook create at should not be changed")
   733  		}
   734  	})
   735  
   736  	t.Run("ModifyUpdateAt", func(t *testing.T) {
   737  		createdHook.DisplayName = "Name3"
   738  
   739  		updatedHook2, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   740  		CheckNoError(t, resp)
   741  
   742  		if updatedHook2.UpdateAt == createdHook.UpdateAt {
   743  			t.Fatal("failed - hook updateAt is not updated")
   744  		}
   745  	})
   746  
   747  	t.Run("UpdateNonExistentHook", func(t *testing.T) {
   748  		nonExistentHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   749  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
   750  
   751  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(nonExistentHook)
   752  		CheckNotFoundStatus(t, resp)
   753  
   754  		nonExistentHook.Id = model.NewId()
   755  		_, resp = th.SystemAdminClient.UpdateOutgoingWebhook(nonExistentHook)
   756  		CheckInternalErrorStatus(t, resp)
   757  	})
   758  
   759  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
   760  		_, resp := Client.UpdateOutgoingWebhook(createdHook)
   761  		CheckForbiddenStatus(t, resp)
   762  	})
   763  
   764  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   765  	hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   766  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats2"}}
   767  
   768  	createdHook2, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook2)
   769  	CheckNoError(t, resp)
   770  
   771  	_, resp = Client.UpdateOutgoingWebhook(createdHook2)
   772  	CheckForbiddenStatus(t, resp)
   773  
   774  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   775  	th.AddPermissionToRole(model.PERMISSION_MANAGE_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   776  
   777  	Client.Logout()
   778  	th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
   779  	th.LoginBasic2()
   780  	t.Run("RetainHookCreator", func(t *testing.T) {
   781  		createdHook.DisplayName = "Basic user 2"
   782  		updatedHook, resp := Client.UpdateOutgoingWebhook(createdHook)
   783  		CheckNoError(t, resp)
   784  		if updatedHook.DisplayName != "Basic user 2" {
   785  			t.Fatal("should apply the change")
   786  		}
   787  		if updatedHook.CreatorId != th.SystemAdminUser.Id {
   788  			t.Fatal("hook creator should not be changed")
   789  		}
   790  	})
   791  
   792  	t.Run("UpdateToExistingTriggerWordAndCallback", func(t *testing.T) {
   793  		t.Run("OnSameChannel", func(t *testing.T) {
   794  			createdHook.TriggerWords = []string{"rats"}
   795  
   796  			_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   797  			CheckBadRequestStatus(t, resp)
   798  		})
   799  
   800  		t.Run("OnDifferentChannel", func(t *testing.T) {
   801  			createdHook.TriggerWords = []string{"cats"}
   802  			createdHook.ChannelId = th.BasicChannel2.Id
   803  
   804  			_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   805  			CheckNoError(t, resp)
   806  		})
   807  	})
   808  
   809  	t.Run("UpdateToNonExistentChannel", func(t *testing.T) {
   810  		createdHook.ChannelId = "junk"
   811  
   812  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   813  		CheckNotFoundStatus(t, resp)
   814  	})
   815  
   816  	t.Run("UpdateToPrivateChannel", func(t *testing.T) {
   817  		privateChannel := th.CreatePrivateChannel()
   818  		createdHook.ChannelId = privateChannel.Id
   819  
   820  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   821  		CheckForbiddenStatus(t, resp)
   822  	})
   823  
   824  	t.Run("UpdateToBlankTriggerWordAndChannel", func(t *testing.T) {
   825  		createdHook.ChannelId = ""
   826  		createdHook.TriggerWords = nil
   827  
   828  		_, resp := th.SystemAdminClient.UpdateOutgoingWebhook(createdHook)
   829  		CheckInternalErrorStatus(t, resp)
   830  	})
   831  
   832  	team := th.CreateTeamWithClient(Client)
   833  	user := th.CreateUserWithClient(Client)
   834  	th.LinkUserToTeam(user, team)
   835  	Client.Logout()
   836  	Client.Login(user.Id, user.Password)
   837  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   838  		_, resp := Client.UpdateOutgoingWebhook(createdHook)
   839  		CheckUnauthorizedStatus(t, resp)
   840  	})
   841  }
   842  
   843  func TestDeleteOutgoingHook(t *testing.T) {
   844  	th := Setup().InitBasic().InitSystemAdmin()
   845  	defer th.TearDown()
   846  	Client := th.SystemAdminClient
   847  
   848  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
   849  
   850  	var resp *model.Response
   851  	var rhook *model.OutgoingWebhook
   852  	var hook *model.OutgoingWebhook
   853  	var status bool
   854  
   855  	t.Run("WhenInvalidHookID", func(t *testing.T) {
   856  		status, resp = Client.DeleteOutgoingWebhook("abc")
   857  		CheckBadRequestStatus(t, resp)
   858  	})
   859  
   860  	t.Run("WhenHookDoesNotExist", func(t *testing.T) {
   861  		status, resp = Client.DeleteOutgoingWebhook(model.NewId())
   862  		CheckInternalErrorStatus(t, resp)
   863  	})
   864  
   865  	t.Run("WhenHookExists", func(t *testing.T) {
   866  		hook = &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   867  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
   868  		rhook, resp = Client.CreateOutgoingWebhook(hook)
   869  		CheckNoError(t, resp)
   870  
   871  		if status, resp = Client.DeleteOutgoingWebhook(rhook.Id); !status {
   872  			t.Fatal("Delete should have succeeded")
   873  		} else {
   874  			CheckOKStatus(t, resp)
   875  		}
   876  
   877  		// Get now should not return this deleted hook
   878  		_, resp = Client.GetIncomingWebhook(rhook.Id, "")
   879  		CheckNotFoundStatus(t, resp)
   880  	})
   881  
   882  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   883  		hook = &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   884  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"dogs"}}
   885  		rhook, resp = Client.CreateOutgoingWebhook(hook)
   886  		CheckNoError(t, resp)
   887  
   888  		th.LoginBasic()
   889  		Client = th.Client
   890  
   891  		_, resp = Client.DeleteOutgoingWebhook(rhook.Id)
   892  		CheckForbiddenStatus(t, resp)
   893  	})
   894  }
   895  
   896  func TestCommandWebhooks(t *testing.T) {
   897  	th := Setup().InitBasic().InitSystemAdmin()
   898  	defer th.TearDown()
   899  
   900  	Client := th.SystemAdminClient
   901  
   902  	cmd := &model.Command{
   903  		CreatorId: th.BasicUser.Id,
   904  		TeamId:    th.BasicTeam.Id,
   905  		URL:       "http://nowhere.com",
   906  		Method:    model.COMMAND_METHOD_POST,
   907  		Trigger:   "delayed"}
   908  
   909  	cmd, _ = Client.CreateCommand(cmd)
   910  	args := &model.CommandArgs{
   911  		TeamId:    th.BasicTeam.Id,
   912  		UserId:    th.BasicUser.Id,
   913  		ChannelId: th.BasicChannel.Id,
   914  	}
   915  	hook, err := th.App.CreateCommandWebhook(cmd.Id, args)
   916  	if err != nil {
   917  		t.Fatal(err)
   918  	}
   919  
   920  	if resp, _ := http.Post(Client.Url+"/hooks/commands/123123123123", "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)); resp.StatusCode != http.StatusNotFound {
   921  		t.Fatal("expected not-found for non-existent hook")
   922  	}
   923  
   924  	if resp, err := http.Post(Client.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"invalid`)); err != nil || resp.StatusCode != http.StatusBadRequest {
   925  		t.Fatal(err)
   926  	}
   927  
   928  	for i := 0; i < 5; i++ {
   929  		if resp, err := http.Post(Client.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)); err != nil || resp.StatusCode != http.StatusOK {
   930  			t.Fatal(err)
   931  		}
   932  	}
   933  
   934  	if resp, _ := http.Post(Client.Url+"/hooks/commands/"+hook.Id, "application/json", bytes.NewBufferString(`{"text":"this is a test"}`)); resp.StatusCode != http.StatusBadRequest {
   935  		t.Fatal("expected error for sixth usage")
   936  	}
   937  }