github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/api4/webhook_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/masterhung0112/hk_server/v5/model"
    13  )
    14  
    15  func TestCreateIncomingWebhook(t *testing.T) {
    16  	th := Setup(t).InitBasic()
    17  	defer th.TearDown()
    18  	Client := th.Client
    19  
    20  	th.App.UpdateConfig(func(cfg *model.Config) {
    21  		*cfg.ServiceSettings.EnableIncomingWebhooks = true
    22  		*cfg.ServiceSettings.EnablePostUsernameOverride = true
    23  		*cfg.ServiceSettings.EnablePostIconOverride = true
    24  	})
    25  
    26  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    27  	defer func() {
    28  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    29  	}()
    30  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
    31  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    32  
    33  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
    34  
    35  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
    36  	CheckNoError(t, resp)
    37  
    38  	require.Equal(t, hook.ChannelId, rhook.ChannelId, "channel ids didn't match")
    39  	require.Equal(t, th.SystemAdminUser.Id, rhook.UserId, "user ids didn't match")
    40  	require.Equal(t, th.BasicTeam.Id, rhook.TeamId, "team ids didn't match")
    41  
    42  	hook.ChannelId = "junk"
    43  	_, resp = th.SystemAdminClient.CreateIncomingWebhook(hook)
    44  	CheckNotFoundStatus(t, resp)
    45  
    46  	hook.ChannelId = th.BasicChannel.Id
    47  	th.LoginTeamAdmin()
    48  	_, resp = Client.CreateIncomingWebhook(hook)
    49  	CheckNoError(t, resp)
    50  
    51  	th.LoginBasic()
    52  	_, resp = Client.CreateIncomingWebhook(hook)
    53  	CheckForbiddenStatus(t, resp)
    54  
    55  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
    56  
    57  	_, resp = Client.CreateIncomingWebhook(hook)
    58  	CheckNoError(t, resp)
    59  
    60  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = false })
    61  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = false })
    62  
    63  	_, resp = Client.CreateIncomingWebhook(hook)
    64  	CheckNoError(t, resp)
    65  
    66  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
    67  		hook.UserId = th.BasicUser2.Id
    68  		defer func() { hook.UserId = "" }()
    69  
    70  		newHook, response := client.CreateIncomingWebhook(hook)
    71  		CheckNoError(t, response)
    72  		require.Equal(t, th.BasicUser2.Id, newHook.UserId)
    73  	}, "Create an incoming webhook for a different user")
    74  
    75  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
    76  		hook.UserId = "invalid-user"
    77  		defer func() { hook.UserId = "" }()
    78  
    79  		_, response := client.CreateIncomingWebhook(hook)
    80  		CheckNotFoundStatus(t, response)
    81  	}, "Create an incoming webhook for an invalid user")
    82  
    83  	t.Run("Create an incoming webhook for a different user without permissions", func(t *testing.T) {
    84  		hook.UserId = th.BasicUser2.Id
    85  		defer func() { hook.UserId = "" }()
    86  
    87  		_, response := Client.CreateIncomingWebhook(hook)
    88  		CheckForbiddenStatus(t, response)
    89  	})
    90  
    91  	t.Run("Create an incoming webhook in local mode without providing user", func(t *testing.T) {
    92  		hook.UserId = ""
    93  
    94  		_, response := th.LocalClient.CreateIncomingWebhook(hook)
    95  		CheckBadRequestStatus(t, response)
    96  	})
    97  
    98  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = false })
    99  	_, resp = Client.CreateIncomingWebhook(hook)
   100  	CheckNotImplementedStatus(t, resp)
   101  }
   102  
   103  func TestCreateIncomingWebhook_BypassTeamPermissions(t *testing.T) {
   104  	th := Setup(t).InitBasic()
   105  	defer th.TearDown()
   106  
   107  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   108  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   109  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   110  
   111  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   112  	defer th.RestoreDefaultRolePermissions(defaultRolePermissions)
   113  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.SYSTEM_USER_ROLE_ID)
   114  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   115  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   116  
   117  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   118  
   119  	rhook, resp := th.Client.CreateIncomingWebhook(hook)
   120  	CheckNoError(t, resp)
   121  
   122  	require.Equal(t, rhook.ChannelId, hook.ChannelId)
   123  	require.Equal(t, rhook.UserId, th.BasicUser.Id)
   124  	require.Equal(t, rhook.TeamId, th.BasicTeam.Id)
   125  
   126  	team := th.CreateTeam()
   127  	team.AllowOpenInvite = false
   128  	th.Client.UpdateTeam(team)
   129  	th.SystemAdminClient.RemoveTeamMember(team.Id, th.BasicUser.Id)
   130  	channel := th.CreateChannelWithClientAndTeam(th.SystemAdminClient, model.CHANNEL_OPEN, team.Id)
   131  
   132  	hook = &model.IncomingWebhook{ChannelId: channel.Id}
   133  	rhook, resp = th.Client.CreateIncomingWebhook(hook)
   134  	CheckForbiddenStatus(t, resp)
   135  }
   136  
   137  func TestGetIncomingWebhooks(t *testing.T) {
   138  	th := Setup(t).InitBasic()
   139  	defer th.TearDown()
   140  	Client := th.Client
   141  
   142  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   143  
   144  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   145  	defer func() {
   146  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   147  	}()
   148  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   149  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   150  
   151  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   152  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
   153  	CheckNoError(t, resp)
   154  
   155  	hooks, resp := th.SystemAdminClient.GetIncomingWebhooks(0, 1000, "")
   156  	CheckNoError(t, resp)
   157  
   158  	found := false
   159  	for _, h := range hooks {
   160  		if rhook.Id == h.Id {
   161  			found = true
   162  		}
   163  	}
   164  
   165  	require.True(t, found, "missing hook")
   166  
   167  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   168  		hooks, resp = client.GetIncomingWebhooks(0, 1, "")
   169  		CheckNoError(t, resp)
   170  
   171  		require.Len(t, hooks, 1, "should only be 1 hook")
   172  
   173  		hooks, resp = client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   174  		CheckNoError(t, resp)
   175  
   176  		found = false
   177  		for _, h := range hooks {
   178  			if rhook.Id == h.Id {
   179  				found = true
   180  			}
   181  		}
   182  
   183  		require.True(t, found, "missing hook")
   184  
   185  		hooks, resp = client.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
   186  		CheckNoError(t, resp)
   187  
   188  		require.Empty(t, hooks, "no hooks should be returned")
   189  	})
   190  
   191  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   192  	CheckForbiddenStatus(t, resp)
   193  
   194  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   195  
   196  	_, resp = Client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   197  	CheckNoError(t, resp)
   198  
   199  	_, resp = Client.GetIncomingWebhooksForTeam(model.NewId(), 0, 1000, "")
   200  	CheckForbiddenStatus(t, resp)
   201  
   202  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   203  	CheckForbiddenStatus(t, resp)
   204  
   205  	Client.Logout()
   206  	_, resp = Client.GetIncomingWebhooks(0, 1000, "")
   207  	CheckUnauthorizedStatus(t, resp)
   208  }
   209  
   210  func TestGetIncomingWebhooksListByUser(t *testing.T) {
   211  	th := Setup(t).InitBasic()
   212  	defer th.TearDown()
   213  	BasicClient := th.Client
   214  	th.LoginBasic()
   215  
   216  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   217  
   218  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   219  	defer func() {
   220  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   221  	}()
   222  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   223  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.SYSTEM_USER_ROLE_ID)
   224  
   225  	// Basic user webhook
   226  	bHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicTeam.Id, UserId: th.BasicUser.Id}
   227  	basicHook, resp := BasicClient.CreateIncomingWebhook(bHook)
   228  	CheckNoError(t, resp)
   229  
   230  	basicHooks, resp := BasicClient.GetIncomingWebhooks(0, 1000, "")
   231  	CheckNoError(t, resp)
   232  	assert.Equal(t, 1, len(basicHooks))
   233  	assert.Equal(t, basicHook.Id, basicHooks[0].Id)
   234  
   235  	// Admin User webhook
   236  	aHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicTeam.Id, UserId: th.SystemAdminUser.Id}
   237  	_, resp = th.SystemAdminClient.CreateIncomingWebhook(aHook)
   238  	CheckNoError(t, resp)
   239  
   240  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   241  		adminHooks, rresp := client.GetIncomingWebhooks(0, 1000, "")
   242  		CheckNoError(t, rresp)
   243  		assert.Equal(t, 2, len(adminHooks))
   244  	})
   245  
   246  	//Re-check basic user that has no MANAGE_OTHERS permission
   247  	filteredHooks, resp := BasicClient.GetIncomingWebhooks(0, 1000, "")
   248  	CheckNoError(t, resp)
   249  	assert.Equal(t, 1, len(filteredHooks))
   250  	assert.Equal(t, basicHook.Id, filteredHooks[0].Id)
   251  }
   252  
   253  func TestGetIncomingWebhooksByTeam(t *testing.T) {
   254  	th := Setup(t).InitBasic()
   255  	defer th.TearDown()
   256  	BasicClient := th.Client
   257  
   258  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   259  
   260  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   261  	defer func() {
   262  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   263  	}()
   264  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   265  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   266  
   267  	// Basic user webhook
   268  	bHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicTeam.Id, UserId: th.BasicUser.Id}
   269  	basicHook, resp := BasicClient.CreateIncomingWebhook(bHook)
   270  	CheckNoError(t, resp)
   271  
   272  	basicHooks, resp := BasicClient.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   273  	CheckNoError(t, resp)
   274  	assert.Equal(t, 1, len(basicHooks))
   275  	assert.Equal(t, basicHook.Id, basicHooks[0].Id)
   276  
   277  	// Admin User webhook
   278  	aHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicTeam.Id, UserId: th.SystemAdminUser.Id}
   279  	_, resp = th.SystemAdminClient.CreateIncomingWebhook(aHook)
   280  	CheckNoError(t, resp)
   281  
   282  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   283  		adminHooks, rresp := client.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   284  		CheckNoError(t, rresp)
   285  		assert.Equal(t, 2, len(adminHooks))
   286  	})
   287  
   288  	//Re-check basic user that has no MANAGE_OTHERS permission
   289  	filteredHooks, resp := BasicClient.GetIncomingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   290  	CheckNoError(t, resp)
   291  	assert.Equal(t, 1, len(filteredHooks))
   292  	assert.Equal(t, basicHook.Id, filteredHooks[0].Id)
   293  }
   294  
   295  func TestGetIncomingWebhook(t *testing.T) {
   296  	th := Setup(t).InitBasic()
   297  	defer th.TearDown()
   298  
   299  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   300  
   301  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   302  	rhook, resp := th.SystemAdminClient.CreateIncomingWebhook(hook)
   303  	CheckNoError(t, resp)
   304  
   305  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   306  		hook, resp = client.GetIncomingWebhook(rhook.Id, "")
   307  		CheckOKStatus(t, resp)
   308  	}, "WhenHookExists")
   309  
   310  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   311  		hook, resp = client.GetIncomingWebhook(model.NewId(), "")
   312  		CheckNotFoundStatus(t, resp)
   313  	}, "WhenHookDoesNotExist")
   314  
   315  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   316  		hook, resp = client.GetIncomingWebhook("abc", "")
   317  		CheckBadRequestStatus(t, resp)
   318  	}, "WhenInvalidHookID")
   319  
   320  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   321  		th.LoginBasic()
   322  		_, resp = th.Client.GetIncomingWebhook(rhook.Id, "")
   323  		CheckForbiddenStatus(t, resp)
   324  	})
   325  }
   326  
   327  func TestDeleteIncomingWebhook(t *testing.T) {
   328  	th := Setup(t).InitBasic()
   329  	defer th.TearDown()
   330  
   331  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   332  
   333  	var resp *model.Response
   334  	var rhook *model.IncomingWebhook
   335  	var hook *model.IncomingWebhook
   336  	var status bool
   337  
   338  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   339  		status, resp = client.DeleteIncomingWebhook("abc")
   340  		CheckBadRequestStatus(t, resp)
   341  	}, "WhenInvalidHookID")
   342  
   343  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   344  		status, resp = client.DeleteIncomingWebhook(model.NewId())
   345  		CheckNotFoundStatus(t, resp)
   346  	}, "WhenHookDoesNotExist")
   347  
   348  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   349  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   350  		// This request is performed by a system admin in both local
   351  		// and sysadmin cases as it's not currently possible to create
   352  		// a webhook via local mode
   353  		rhook, resp = th.SystemAdminClient.CreateIncomingWebhook(hook)
   354  		CheckNoError(t, resp)
   355  
   356  		status, resp = client.DeleteIncomingWebhook(rhook.Id)
   357  		require.True(t, status, "Delete should have succeeded")
   358  
   359  		CheckOKStatus(t, resp)
   360  
   361  		// Get now should not return this deleted hook
   362  		_, resp = client.GetIncomingWebhook(rhook.Id, "")
   363  		CheckNotFoundStatus(t, resp)
   364  	}, "WhenHookExists")
   365  
   366  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
   367  		hook = &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   368  		rhook, resp = th.SystemAdminClient.CreateIncomingWebhook(hook)
   369  		CheckNoError(t, resp)
   370  
   371  		th.LoginBasic()
   372  		_, resp = th.Client.DeleteIncomingWebhook(rhook.Id)
   373  		CheckForbiddenStatus(t, resp)
   374  	})
   375  }
   376  
   377  func TestCreateOutgoingWebhook(t *testing.T) {
   378  	th := Setup(t).InitBasic()
   379  	defer th.TearDown()
   380  	Client := th.Client
   381  
   382  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   383  
   384  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   385  	defer func() {
   386  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   387  	}()
   388  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   389  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   390  
   391  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}, Username: "some-user-name", IconURL: "http://some-icon-url/"}
   392  
   393  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   394  	CheckNoError(t, resp)
   395  
   396  	assert.Equal(t, hook.ChannelId, rhook.ChannelId, "channel ids didn't match")
   397  	assert.Equal(t, th.SystemAdminUser.Id, rhook.CreatorId, "user ids didn't match")
   398  	assert.Equal(t, th.BasicChannel.TeamId, rhook.TeamId, "team ids didn't match")
   399  
   400  	hook.ChannelId = "junk"
   401  	_, resp = th.SystemAdminClient.CreateOutgoingWebhook(hook)
   402  	CheckNotFoundStatus(t, resp)
   403  
   404  	hook.ChannelId = th.BasicChannel.Id
   405  	th.LoginTeamAdmin()
   406  	_, resp = Client.CreateOutgoingWebhook(hook)
   407  	CheckNoError(t, resp)
   408  
   409  	th.LoginBasic()
   410  	_, resp = Client.CreateOutgoingWebhook(hook)
   411  	CheckForbiddenStatus(t, resp)
   412  
   413  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   414  
   415  	_, resp = Client.CreateOutgoingWebhook(hook)
   416  	CheckNoError(t, resp)
   417  
   418  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   419  		hook.CreatorId = th.BasicUser2.Id
   420  		defer func() { hook.CreatorId = "" }()
   421  
   422  		newHook, response := client.CreateOutgoingWebhook(hook)
   423  		CheckNoError(t, response)
   424  		require.Equal(t, th.BasicUser2.Id, newHook.CreatorId)
   425  	}, "Create an outgoing webhook for a different user")
   426  
   427  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   428  		hook.CreatorId = "invalid-user"
   429  		defer func() { hook.CreatorId = "" }()
   430  
   431  		_, response := client.CreateOutgoingWebhook(hook)
   432  		CheckNotFoundStatus(t, response)
   433  	}, "Create an incoming webhook for an invalid user")
   434  
   435  	t.Run("Create an outgoing webhook for a different user without permissions", func(t *testing.T) {
   436  		hook.CreatorId = th.BasicUser2.Id
   437  		defer func() { hook.CreatorId = "" }()
   438  
   439  		_, response := Client.CreateOutgoingWebhook(hook)
   440  		CheckForbiddenStatus(t, response)
   441  	})
   442  
   443  	t.Run("Create an outgoing webhook in local mode without providing user", func(t *testing.T) {
   444  		hook.CreatorId = ""
   445  
   446  		_, response := th.LocalClient.CreateOutgoingWebhook(hook)
   447  		CheckBadRequestStatus(t, response)
   448  	})
   449  
   450  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   451  	_, resp = Client.CreateOutgoingWebhook(hook)
   452  	CheckNotImplementedStatus(t, resp)
   453  }
   454  
   455  func TestGetOutgoingWebhooks(t *testing.T) {
   456  	th := Setup(t).InitBasic()
   457  	defer th.TearDown()
   458  
   459  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   460  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   461  	defer func() {
   462  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   463  	}()
   464  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   465  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   466  
   467  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   468  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   469  	CheckNoError(t, resp)
   470  
   471  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   472  		hooks, rresp := client.GetOutgoingWebhooks(0, 1000, "")
   473  		CheckNoError(t, rresp)
   474  
   475  		found := false
   476  		for _, h := range hooks {
   477  			if rhook.Id == h.Id {
   478  				found = true
   479  			}
   480  		}
   481  
   482  		require.True(t, found, "missing hook")
   483  
   484  		hooks, rresp = client.GetOutgoingWebhooks(0, 1, "")
   485  		CheckNoError(t, rresp)
   486  
   487  		require.Len(t, hooks, 1, "should only be 1 hook")
   488  
   489  		hooks, rresp = client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   490  		CheckNoError(t, rresp)
   491  
   492  		found = false
   493  		for _, h := range hooks {
   494  			if rhook.Id == h.Id {
   495  				found = true
   496  			}
   497  		}
   498  
   499  		require.True(t, found, "missing hook")
   500  
   501  		hooks, rresp = client.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
   502  		CheckNoError(t, rresp)
   503  
   504  		require.Empty(t, hooks, "no hooks should be returned")
   505  
   506  		hooks, rresp = client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   507  		CheckNoError(t, rresp)
   508  
   509  		found = false
   510  		for _, h := range hooks {
   511  			if rhook.Id == h.Id {
   512  				found = true
   513  			}
   514  		}
   515  
   516  		require.True(t, found, "missing hook")
   517  
   518  		_, rresp = client.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
   519  		CheckForbiddenStatus(t, rresp)
   520  	})
   521  
   522  	_, resp = th.Client.GetOutgoingWebhooks(0, 1000, "")
   523  	CheckForbiddenStatus(t, resp)
   524  
   525  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   526  
   527  	_, resp = th.Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   528  	CheckNoError(t, resp)
   529  
   530  	_, resp = th.Client.GetOutgoingWebhooksForTeam(model.NewId(), 0, 1000, "")
   531  	CheckForbiddenStatus(t, resp)
   532  
   533  	_, resp = th.Client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   534  	CheckNoError(t, resp)
   535  
   536  	_, resp = th.Client.GetOutgoingWebhooksForChannel(model.NewId(), 0, 1000, "")
   537  	CheckForbiddenStatus(t, resp)
   538  
   539  	_, resp = th.Client.GetOutgoingWebhooks(0, 1000, "")
   540  	CheckForbiddenStatus(t, resp)
   541  
   542  	th.Client.Logout()
   543  	_, resp = th.Client.GetOutgoingWebhooks(0, 1000, "")
   544  	CheckUnauthorizedStatus(t, resp)
   545  }
   546  
   547  func TestGetOutgoingWebhooksByTeam(t *testing.T) {
   548  	th := Setup(t).InitBasic()
   549  	defer th.TearDown()
   550  
   551  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   552  
   553  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   554  	defer func() {
   555  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   556  	}()
   557  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   558  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   559  
   560  	// Basic user webhook
   561  	bHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   562  	basicHook, resp := th.Client.CreateOutgoingWebhook(bHook)
   563  	CheckNoError(t, resp)
   564  
   565  	basicHooks, resp := th.Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   566  	CheckNoError(t, resp)
   567  	assert.Equal(t, 1, len(basicHooks))
   568  	assert.Equal(t, basicHook.Id, basicHooks[0].Id)
   569  
   570  	// Admin User webhook
   571  	aHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   572  	_, resp = th.SystemAdminClient.CreateOutgoingWebhook(aHook)
   573  	CheckNoError(t, resp)
   574  
   575  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   576  		adminHooks, rresp := client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   577  		CheckNoError(t, rresp)
   578  		assert.Equal(t, 2, len(adminHooks))
   579  	})
   580  
   581  	//Re-check basic user that has no MANAGE_OTHERS permission
   582  	filteredHooks, resp := th.Client.GetOutgoingWebhooksForTeam(th.BasicTeam.Id, 0, 1000, "")
   583  	CheckNoError(t, resp)
   584  	assert.Equal(t, 1, len(filteredHooks))
   585  	assert.Equal(t, basicHook.Id, filteredHooks[0].Id)
   586  }
   587  
   588  func TestGetOutgoingWebhooksByChannel(t *testing.T) {
   589  	th := Setup(t).InitBasic()
   590  	defer th.TearDown()
   591  
   592  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   593  
   594  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   595  	defer func() {
   596  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   597  	}()
   598  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   599  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   600  
   601  	// Basic user webhook
   602  	bHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   603  	basicHook, resp := th.Client.CreateOutgoingWebhook(bHook)
   604  	CheckNoError(t, resp)
   605  
   606  	basicHooks, resp := th.Client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   607  	CheckNoError(t, resp)
   608  	assert.Equal(t, 1, len(basicHooks))
   609  	assert.Equal(t, basicHook.Id, basicHooks[0].Id)
   610  
   611  	// Admin User webhook
   612  	aHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   613  	_, resp = th.SystemAdminClient.CreateOutgoingWebhook(aHook)
   614  	CheckNoError(t, resp)
   615  
   616  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   617  		adminHooks, rresp := client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   618  		CheckNoError(t, rresp)
   619  		assert.Equal(t, 2, len(adminHooks))
   620  	})
   621  
   622  	//Re-check basic user that has no MANAGE_OTHERS permission
   623  	filteredHooks, resp := th.Client.GetOutgoingWebhooksForChannel(th.BasicChannel.Id, 0, 1000, "")
   624  	CheckNoError(t, resp)
   625  	assert.Equal(t, 1, len(filteredHooks))
   626  	assert.Equal(t, basicHook.Id, filteredHooks[0].Id)
   627  }
   628  
   629  func TestGetOutgoingWebhooksListByUser(t *testing.T) {
   630  	th := Setup(t).InitBasic()
   631  	defer th.TearDown()
   632  	th.LoginBasic()
   633  
   634  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   635  
   636  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   637  	defer func() {
   638  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   639  	}()
   640  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   641  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.SYSTEM_USER_ROLE_ID)
   642  
   643  	// Basic user webhook
   644  	bHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   645  	basicHook, resp := th.Client.CreateOutgoingWebhook(bHook)
   646  	CheckNoError(t, resp)
   647  
   648  	basicHooks, resp := th.Client.GetOutgoingWebhooks(0, 1000, "")
   649  	CheckNoError(t, resp)
   650  	assert.Equal(t, 1, len(basicHooks))
   651  	assert.Equal(t, basicHook.Id, basicHooks[0].Id)
   652  
   653  	// Admin User webhook
   654  	aHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   655  	_, resp = th.SystemAdminClient.CreateOutgoingWebhook(aHook)
   656  	CheckNoError(t, resp)
   657  
   658  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   659  		adminHooks, rresp := client.GetOutgoingWebhooks(0, 1000, "")
   660  		CheckNoError(t, rresp)
   661  		assert.Equal(t, 2, len(adminHooks))
   662  	})
   663  
   664  	//Re-check basic user that has no MANAGE_OTHERS permission
   665  	filteredHooks, resp := th.Client.GetOutgoingWebhooks(0, 1000, "")
   666  	CheckNoError(t, resp)
   667  	assert.Equal(t, 1, len(filteredHooks))
   668  	assert.Equal(t, basicHook.Id, filteredHooks[0].Id)
   669  }
   670  
   671  func TestGetOutgoingWebhook(t *testing.T) {
   672  	th := Setup(t).InitBasic()
   673  	defer th.TearDown()
   674  
   675  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   676  
   677  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   678  
   679  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   680  	CheckNoError(t, resp)
   681  
   682  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   683  		getHook, rresp := client.GetOutgoingWebhook(rhook.Id)
   684  		CheckNoError(t, rresp)
   685  
   686  		require.Equal(t, getHook.Id, rhook.Id, "failed to retrieve the correct outgoing hook")
   687  	})
   688  
   689  	_, resp = th.Client.GetOutgoingWebhook(rhook.Id)
   690  	CheckForbiddenStatus(t, resp)
   691  
   692  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   693  		nonExistentHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id}
   694  		_, resp = client.GetOutgoingWebhook(nonExistentHook.Id)
   695  		CheckNotFoundStatus(t, resp)
   696  
   697  		nonExistentHook.Id = model.NewId()
   698  		_, resp = client.GetOutgoingWebhook(nonExistentHook.Id)
   699  		CheckNotFoundStatus(t, resp)
   700  	})
   701  }
   702  
   703  func TestUpdateIncomingHook(t *testing.T) {
   704  	th := Setup(t).InitBasic()
   705  	defer th.TearDown()
   706  
   707  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   708  
   709  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   710  	defer func() {
   711  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   712  	}()
   713  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   714  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   715  
   716  	hook1 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   717  
   718  	var resp *model.Response
   719  	var createdHook *model.IncomingWebhook
   720  
   721  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = false })
   722  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = false })
   723  
   724  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   725  		// webhook creations are allways performed by a sysadmin
   726  		// because it's not currently possible to create a webhook via
   727  		// local mode
   728  		createdHook, resp = th.SystemAdminClient.CreateIncomingWebhook(hook1)
   729  		CheckNoError(t, resp)
   730  
   731  		createdHook.DisplayName = "hook2"
   732  		createdHook.Description = "description"
   733  		createdHook.ChannelId = th.BasicChannel2.Id
   734  		createdHook.Username = "username"
   735  		createdHook.IconURL = "icon"
   736  
   737  		updatedHook, rresp := client.UpdateIncomingWebhook(createdHook)
   738  		CheckNoError(t, rresp)
   739  
   740  		require.NotNil(t, updatedHook, "should not be nil")
   741  		require.Exactly(t, "hook2", updatedHook.DisplayName, "Hook name is not updated")
   742  		require.Exactly(t, "description", updatedHook.Description, "Hook description is not updated")
   743  		require.Equal(t, updatedHook.ChannelId, th.BasicChannel2.Id, "Hook channel is not updated")
   744  		require.Empty(t, updatedHook.Username, "Hook username was incorrectly updated")
   745  		require.Empty(t, updatedHook.IconURL, "Hook icon was incorrectly updated")
   746  
   747  		//updatedHook, _ = th.App.GetIncomingWebhook(createdHook.Id)
   748  		assert.Equal(t, updatedHook.ChannelId, createdHook.ChannelId)
   749  	}, "UpdateIncomingHook, overrides disabled")
   750  
   751  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   752  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   753  
   754  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   755  		createdHook, resp = th.SystemAdminClient.CreateIncomingWebhook(hook1)
   756  		CheckNoError(t, resp)
   757  
   758  		createdHook.DisplayName = "hook2"
   759  		createdHook.Description = "description"
   760  		createdHook.ChannelId = th.BasicChannel2.Id
   761  		createdHook.Username = "username"
   762  		createdHook.IconURL = "icon"
   763  
   764  		updatedHook, resp := client.UpdateIncomingWebhook(createdHook)
   765  		CheckNoError(t, resp)
   766  
   767  		require.NotNil(t, updatedHook, "should not be nil")
   768  		require.Exactly(t, "hook2", updatedHook.DisplayName, "Hook name is not updated")
   769  		require.Exactly(t, "description", updatedHook.Description, "Hook description is not updated")
   770  		require.Equal(t, updatedHook.ChannelId, th.BasicChannel2.Id, "Hook channel is not updated")
   771  		require.Exactly(t, "username", updatedHook.Username, "Hook username is not updated")
   772  		require.Exactly(t, "icon", updatedHook.IconURL, "Hook icon is not updated")
   773  
   774  		//updatedHook, _ = th.App.GetIncomingWebhook(createdHook.Id)
   775  		assert.Equal(t, updatedHook.ChannelId, createdHook.ChannelId)
   776  	}, "UpdateIncomingHook")
   777  
   778  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   779  		hook2 := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id, CreateAt: 100}
   780  
   781  		createdHook2, resp := th.SystemAdminClient.CreateIncomingWebhook(hook2)
   782  		CheckNoError(t, resp)
   783  
   784  		createdHook2.DisplayName = "Name2"
   785  
   786  		updatedHook, resp := client.UpdateIncomingWebhook(createdHook2)
   787  		CheckNoError(t, resp)
   788  		require.NotNil(t, updatedHook)
   789  		assert.Equal(t, createdHook2.CreateAt, updatedHook.CreateAt)
   790  	}, "RetainCreateAt")
   791  
   792  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   793  		createdHook.DisplayName = "Name3"
   794  
   795  		updatedHook, resp := client.UpdateIncomingWebhook(createdHook)
   796  		CheckNoError(t, resp)
   797  		require.NotNil(t, updatedHook, "should not be nil")
   798  		require.NotEqual(t, createdHook.UpdateAt, updatedHook.UpdateAt, "failed - hook updateAt is not updated")
   799  	}, "ModifyUpdateAt")
   800  
   801  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   802  		nonExistentHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   803  
   804  		_, resp := client.UpdateIncomingWebhook(nonExistentHook)
   805  		CheckNotFoundStatus(t, resp)
   806  
   807  		nonExistentHook.Id = model.NewId()
   808  		_, resp = client.UpdateIncomingWebhook(nonExistentHook)
   809  		CheckNotFoundStatus(t, resp)
   810  	}, "UpdateNonExistentHook")
   811  
   812  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
   813  		_, resp := th.Client.UpdateIncomingWebhook(createdHook)
   814  		CheckForbiddenStatus(t, resp)
   815  	})
   816  
   817  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   818  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   819  
   820  	t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
   821  		th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   822  
   823  		t.Run("UpdateHookOfSameUser", func(t *testing.T) {
   824  			sameUserHook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   825  
   826  			sameUserHook, resp := th.Client.CreateIncomingWebhook(sameUserHook)
   827  			CheckNoError(t, resp)
   828  
   829  			sameUserHook.UserId = th.BasicUser2.Id
   830  			_, resp = th.Client.UpdateIncomingWebhook(sameUserHook)
   831  			CheckNoError(t, resp)
   832  		})
   833  
   834  		t.Run("UpdateHookOfDifferentUser", func(t *testing.T) {
   835  			_, resp := th.Client.UpdateIncomingWebhook(createdHook)
   836  			CheckForbiddenStatus(t, resp)
   837  		})
   838  	})
   839  
   840  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   841  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   842  
   843  	th.Client.Logout()
   844  	th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
   845  	th.LoginBasic2()
   846  	t.Run("UpdateByDifferentUser", func(t *testing.T) {
   847  		updatedHook, resp := th.Client.UpdateIncomingWebhook(createdHook)
   848  		CheckNoError(t, resp)
   849  		require.NotEqual(t, th.BasicUser2.Id, updatedHook.UserId, "Hook's creator userId is not retained")
   850  	})
   851  
   852  	t.Run("IncomingHooksDisabled", func(t *testing.T) {
   853  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = false })
   854  		_, resp := th.Client.UpdateIncomingWebhook(createdHook)
   855  		CheckNotImplementedStatus(t, resp)
   856  		CheckErrorMessage(t, resp, "api.incoming_webhook.disabled.app_error")
   857  	})
   858  
   859  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   860  
   861  	t.Run("PrivateChannel", func(t *testing.T) {
   862  		privateChannel := th.CreatePrivateChannel()
   863  		th.Client.Logout()
   864  		th.LoginBasic()
   865  		createdHook.ChannelId = privateChannel.Id
   866  
   867  		_, resp := th.Client.UpdateIncomingWebhook(createdHook)
   868  		CheckForbiddenStatus(t, resp)
   869  	})
   870  
   871  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   872  		createdHook.ChannelId = "junk"
   873  		_, resp := client.UpdateIncomingWebhook(createdHook)
   874  		CheckNotFoundStatus(t, resp)
   875  	}, "UpdateToNonExistentChannel")
   876  
   877  	team := th.CreateTeamWithClient(th.Client)
   878  	user := th.CreateUserWithClient(th.Client)
   879  	th.LinkUserToTeam(user, team)
   880  	th.Client.Logout()
   881  	th.Client.Login(user.Id, user.Password)
   882  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
   883  		_, resp := th.Client.UpdateIncomingWebhook(createdHook)
   884  		CheckUnauthorizedStatus(t, resp)
   885  	})
   886  }
   887  
   888  func TestUpdateIncomingWebhook_BypassTeamPermissions(t *testing.T) {
   889  	th := Setup(t).InitBasic()
   890  	defer th.TearDown()
   891  
   892  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
   893  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostUsernameOverride = true })
   894  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnablePostIconOverride = true })
   895  
   896  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   897  	defer th.RestoreDefaultRolePermissions(defaultRolePermissions)
   898  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.SYSTEM_USER_ROLE_ID)
   899  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   900  	th.AddPermissionToRole(model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   901  
   902  	hook := &model.IncomingWebhook{ChannelId: th.BasicChannel.Id}
   903  
   904  	rhook, resp := th.Client.CreateIncomingWebhook(hook)
   905  	CheckNoError(t, resp)
   906  
   907  	require.Equal(t, rhook.ChannelId, hook.ChannelId)
   908  	require.Equal(t, rhook.UserId, th.BasicUser.Id)
   909  	require.Equal(t, rhook.TeamId, th.BasicTeam.Id)
   910  
   911  	team := th.CreateTeam()
   912  	team.AllowOpenInvite = false
   913  	th.Client.UpdateTeam(team)
   914  	th.SystemAdminClient.RemoveTeamMember(team.Id, th.BasicUser.Id)
   915  	channel := th.CreateChannelWithClientAndTeam(th.SystemAdminClient, model.CHANNEL_OPEN, team.Id)
   916  
   917  	hook2 := &model.IncomingWebhook{Id: rhook.Id, ChannelId: channel.Id}
   918  	rhook, resp = th.Client.UpdateIncomingWebhook(hook2)
   919  	CheckBadRequestStatus(t, resp)
   920  }
   921  
   922  func TestRegenOutgoingHookToken(t *testing.T) {
   923  	th := Setup(t).InitBasic()
   924  	defer th.TearDown()
   925  	Client := th.Client
   926  
   927  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   928  
   929  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId, CallbackURLs: []string{"http://nowhere.com"}}
   930  	rhook, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook)
   931  	CheckNoError(t, resp)
   932  
   933  	_, resp = th.SystemAdminClient.RegenOutgoingHookToken("junk")
   934  	CheckBadRequestStatus(t, resp)
   935  
   936  	//investigate why is act weird on jenkins
   937  	// _, resp = th.SystemAdminClient.RegenOutgoingHookToken("")
   938  	// CheckNotFoundStatus(t, resp)
   939  
   940  	regenHookToken, resp := th.SystemAdminClient.RegenOutgoingHookToken(rhook.Id)
   941  	CheckNoError(t, resp)
   942  	require.NotEqual(t, rhook.Token, regenHookToken.Token, "regen didn't work properly")
   943  
   944  	_, resp = Client.RegenOutgoingHookToken(rhook.Id)
   945  	CheckForbiddenStatus(t, resp)
   946  
   947  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   948  	_, resp = th.SystemAdminClient.RegenOutgoingHookToken(rhook.Id)
   949  	CheckNotImplementedStatus(t, resp)
   950  }
   951  
   952  func TestUpdateOutgoingHook(t *testing.T) {
   953  	th := Setup(t).InitBasic()
   954  	defer th.TearDown()
   955  
   956  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   957  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   958  	defer func() {
   959  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   960  	}()
   961  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
   962  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
   963  
   964  	createdHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
   965  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
   966  
   967  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   968  		rcreatedHook, webookResp := th.SystemAdminClient.CreateOutgoingWebhook(createdHook)
   969  		CheckNoError(t, webookResp)
   970  		defer func() {
   971  			_, resp := client.DeleteOutgoingWebhook(rcreatedHook.Id)
   972  			CheckNoError(t, resp)
   973  		}()
   974  
   975  		rcreatedHook.DisplayName = "Cats"
   976  		rcreatedHook.Description = "Get me some cats"
   977  
   978  		updatedHook, resp := client.UpdateOutgoingWebhook(rcreatedHook)
   979  		CheckNoError(t, resp)
   980  
   981  		require.Exactly(t, "Cats", updatedHook.DisplayName, "did not update")
   982  		require.Exactly(t, "Get me some cats", updatedHook.Description, "did not update")
   983  	}, "UpdateOutgoingWebhook")
   984  
   985  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
   986  		rcreatedHook, webookResp := th.SystemAdminClient.CreateOutgoingWebhook(createdHook)
   987  		CheckNoError(t, webookResp)
   988  		defer func() {
   989  			th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
   990  			_, resp := client.DeleteOutgoingWebhook(rcreatedHook.Id)
   991  			CheckNoError(t, resp)
   992  		}()
   993  
   994  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = false })
   995  		_, resp := client.UpdateOutgoingWebhook(rcreatedHook)
   996  		CheckNotImplementedStatus(t, resp)
   997  	}, "OutgoingHooksDisabled")
   998  
   999  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
  1000  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1001  		hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1002  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
  1003  
  1004  		createdHook2, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook2)
  1005  		CheckNoError(t, resp)
  1006  		defer func() {
  1007  			_, rresp := client.DeleteOutgoingWebhook(createdHook2.Id)
  1008  			CheckNoError(t, rresp)
  1009  		}()
  1010  		createdHook2.DisplayName = "Name2"
  1011  
  1012  		updatedHook2, resp := client.UpdateOutgoingWebhook(createdHook2)
  1013  		CheckNoError(t, resp)
  1014  
  1015  		require.Equal(t, createdHook2.CreateAt, updatedHook2.CreateAt, "failed - hook create at should not be changed")
  1016  	}, "RetainCreateAt")
  1017  
  1018  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1019  		rcreatedHook, resp := th.SystemAdminClient.CreateOutgoingWebhook(createdHook)
  1020  		CheckNoError(t, resp)
  1021  		defer func() {
  1022  			_, rresp := client.DeleteOutgoingWebhook(rcreatedHook.Id)
  1023  			CheckNoError(t, rresp)
  1024  		}()
  1025  		rcreatedHook.DisplayName = "Name3"
  1026  
  1027  		updatedHook2, resp := client.UpdateOutgoingWebhook(rcreatedHook)
  1028  		CheckNoError(t, resp)
  1029  
  1030  		require.NotEqual(t, createdHook.UpdateAt, updatedHook2.UpdateAt, "failed - hook updateAt is not updated")
  1031  	}, "ModifyUpdateAt")
  1032  
  1033  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1034  		nonExistentHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1035  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats"}}
  1036  
  1037  		_, resp := client.UpdateOutgoingWebhook(nonExistentHook)
  1038  		CheckNotFoundStatus(t, resp)
  1039  
  1040  		nonExistentHook.Id = model.NewId()
  1041  		_, resp = client.UpdateOutgoingWebhook(nonExistentHook)
  1042  		CheckNotFoundStatus(t, resp)
  1043  	}, "UpdateNonExistentHook")
  1044  
  1045  	createdHook, resp := th.SystemAdminClient.CreateOutgoingWebhook(createdHook)
  1046  	CheckNoError(t, resp)
  1047  
  1048  	t.Run("UserIsNotAdminOfTeam", func(t *testing.T) {
  1049  		_, rresp := th.Client.UpdateOutgoingWebhook(createdHook)
  1050  		CheckForbiddenStatus(t, rresp)
  1051  	})
  1052  
  1053  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
  1054  	hook2 := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1055  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats2"}}
  1056  
  1057  	createdHook2, resp := th.SystemAdminClient.CreateOutgoingWebhook(hook2)
  1058  	CheckNoError(t, resp)
  1059  
  1060  	_, resp = th.Client.UpdateOutgoingWebhook(createdHook2)
  1061  	CheckForbiddenStatus(t, resp)
  1062  
  1063  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
  1064  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
  1065  
  1066  	th.Client.Logout()
  1067  	th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
  1068  	th.LoginBasic2()
  1069  	t.Run("RetainHookCreator", func(t *testing.T) {
  1070  		createdHook.DisplayName = "Basic user 2"
  1071  		updatedHook, rresp := th.Client.UpdateOutgoingWebhook(createdHook)
  1072  		CheckNoError(t, rresp)
  1073  
  1074  		require.Exactly(t, "Basic user 2", updatedHook.DisplayName, "should apply the change")
  1075  		require.Equal(t, th.SystemAdminUser.Id, updatedHook.CreatorId, "hook creator should not be changed")
  1076  	})
  1077  
  1078  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1079  		firstHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1080  			CallbackURLs: []string{"http://someurl"}, TriggerWords: []string{"first"}}
  1081  		firstHook, resp = th.SystemAdminClient.CreateOutgoingWebhook(firstHook)
  1082  		CheckNoError(t, resp)
  1083  
  1084  		baseHook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1085  			CallbackURLs: []string{"http://someurl"}, TriggerWords: []string{"base"}}
  1086  		baseHook, resp = th.SystemAdminClient.CreateOutgoingWebhook(baseHook)
  1087  		CheckNoError(t, resp)
  1088  
  1089  		defer func() {
  1090  			_, resp := client.DeleteOutgoingWebhook(firstHook.Id)
  1091  			CheckNoError(t, resp)
  1092  			_, resp = client.DeleteOutgoingWebhook(baseHook.Id)
  1093  			CheckNoError(t, resp)
  1094  		}()
  1095  
  1096  		t.Run("OnSameChannel", func(t *testing.T) {
  1097  			baseHook.TriggerWords = []string{"first"}
  1098  
  1099  			_, resp := client.UpdateOutgoingWebhook(baseHook)
  1100  			CheckBadRequestStatus(t, resp)
  1101  		})
  1102  
  1103  		t.Run("OnDifferentChannel", func(t *testing.T) {
  1104  			baseHook.TriggerWords = []string{"first"}
  1105  			baseHook.ChannelId = th.BasicChannel2.Id
  1106  
  1107  			_, resp := client.UpdateOutgoingWebhook(baseHook)
  1108  			CheckNoError(t, resp)
  1109  		})
  1110  	}, "UpdateToExistingTriggerWordAndCallback")
  1111  
  1112  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1113  		createdHook.ChannelId = "junk"
  1114  
  1115  		_, resp := client.UpdateOutgoingWebhook(createdHook)
  1116  		CheckNotFoundStatus(t, resp)
  1117  	}, "UpdateToNonExistentChannel")
  1118  
  1119  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1120  		privateChannel := th.CreatePrivateChannel()
  1121  		createdHook.ChannelId = privateChannel.Id
  1122  
  1123  		_, resp := client.UpdateOutgoingWebhook(createdHook)
  1124  		CheckForbiddenStatus(t, resp)
  1125  	}, "UpdateToPrivateChannel")
  1126  
  1127  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1128  		createdHook.ChannelId = ""
  1129  		createdHook.TriggerWords = nil
  1130  
  1131  		_, resp := client.UpdateOutgoingWebhook(createdHook)
  1132  		CheckInternalErrorStatus(t, resp)
  1133  	}, "UpdateToBlankTriggerWordAndChannel")
  1134  
  1135  	team := th.CreateTeamWithClient(th.Client)
  1136  	user := th.CreateUserWithClient(th.Client)
  1137  	th.LinkUserToTeam(user, team)
  1138  	th.Client.Logout()
  1139  	th.Client.Login(user.Id, user.Password)
  1140  	t.Run("UpdateToADifferentTeam", func(t *testing.T) {
  1141  		_, resp := th.Client.UpdateOutgoingWebhook(createdHook)
  1142  		CheckUnauthorizedStatus(t, resp)
  1143  	})
  1144  }
  1145  
  1146  func TestUpdateOutgoingWebhook_BypassTeamPermissions(t *testing.T) {
  1147  	th := Setup(t).InitBasic()
  1148  	defer th.TearDown()
  1149  
  1150  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOutgoingWebhooks = true })
  1151  
  1152  	defaultRolePermissions := th.SaveDefaultRolePermissions()
  1153  	defer th.RestoreDefaultRolePermissions(defaultRolePermissions)
  1154  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.SYSTEM_USER_ROLE_ID)
  1155  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_ADMIN_ROLE_ID)
  1156  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id, model.TEAM_USER_ROLE_ID)
  1157  
  1158  	hook := &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1159  		CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"rats2"}}
  1160  
  1161  	rhook, resp := th.Client.CreateOutgoingWebhook(hook)
  1162  	CheckNoError(t, resp)
  1163  
  1164  	require.Equal(t, rhook.ChannelId, hook.ChannelId)
  1165  	require.Equal(t, rhook.TeamId, th.BasicTeam.Id)
  1166  
  1167  	team := th.CreateTeam()
  1168  	team.AllowOpenInvite = false
  1169  	th.Client.UpdateTeam(team)
  1170  	th.SystemAdminClient.RemoveTeamMember(team.Id, th.BasicUser.Id)
  1171  	channel := th.CreateChannelWithClientAndTeam(th.SystemAdminClient, model.CHANNEL_OPEN, team.Id)
  1172  
  1173  	hook2 := &model.OutgoingWebhook{Id: rhook.Id, ChannelId: channel.Id}
  1174  	rhook, resp = th.Client.UpdateOutgoingWebhook(hook2)
  1175  	CheckForbiddenStatus(t, resp)
  1176  }
  1177  
  1178  func TestDeleteOutgoingHook(t *testing.T) {
  1179  	th := Setup(t).InitBasic()
  1180  	defer th.TearDown()
  1181  
  1182  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableIncomingWebhooks = true })
  1183  
  1184  	var resp *model.Response
  1185  	var rhook *model.OutgoingWebhook
  1186  	var hook *model.OutgoingWebhook
  1187  	var status bool
  1188  
  1189  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1190  		status, resp = client.DeleteOutgoingWebhook("abc")
  1191  		CheckBadRequestStatus(t, resp)
  1192  	}, "WhenInvalidHookID")
  1193  
  1194  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1195  		status, resp = client.DeleteOutgoingWebhook(model.NewId())
  1196  		CheckNotFoundStatus(t, resp)
  1197  	}, "WhenHookDoesNotExist")
  1198  
  1199  	th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
  1200  		hook = &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1201  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"cats"}}
  1202  		rhook, resp = th.SystemAdminClient.CreateOutgoingWebhook(hook)
  1203  		CheckNoError(t, resp)
  1204  
  1205  		status, resp = client.DeleteOutgoingWebhook(rhook.Id)
  1206  
  1207  		require.True(t, status, "Delete should have succeeded")
  1208  		CheckOKStatus(t, resp)
  1209  
  1210  		// Get now should not return this deleted hook
  1211  		_, resp = client.GetIncomingWebhook(rhook.Id, "")
  1212  		CheckNotFoundStatus(t, resp)
  1213  	}, "WhenHookExists")
  1214  
  1215  	t.Run("WhenUserDoesNotHavePemissions", func(t *testing.T) {
  1216  		hook = &model.OutgoingWebhook{ChannelId: th.BasicChannel.Id, TeamId: th.BasicChannel.TeamId,
  1217  			CallbackURLs: []string{"http://nowhere.com"}, TriggerWords: []string{"dogs"}}
  1218  		rhook, resp = th.SystemAdminClient.CreateOutgoingWebhook(hook)
  1219  		CheckNoError(t, resp)
  1220  
  1221  		th.LoginBasic()
  1222  		_, resp = th.Client.DeleteOutgoingWebhook(rhook.Id)
  1223  		CheckForbiddenStatus(t, resp)
  1224  	})
  1225  }