github.com/turgay/mattermost-server@v5.3.2-0.20181002173352-2945e8a2b0ce+incompatible/api4/oauth_test.go (about)

     1  // Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api4
     5  
     6  import (
     7  	"encoding/base64"
     8  	"io"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"net/url"
    13  	"strconv"
    14  	"testing"
    15  
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  
    19  	"github.com/mattermost/mattermost-server/einterfaces"
    20  	"github.com/mattermost/mattermost-server/model"
    21  	"github.com/mattermost/mattermost-server/utils"
    22  	"github.com/mattermost/mattermost-server/web"
    23  )
    24  
    25  func TestCreateOAuthApp(t *testing.T) {
    26  	th := Setup().InitBasic().InitSystemAdmin()
    27  	defer th.TearDown()
    28  	Client := th.Client
    29  	AdminClient := th.SystemAdminClient
    30  
    31  	defaultRolePermissions := th.SaveDefaultRolePermissions()
    32  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
    33  	defer func() {
    34  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
    35  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
    36  	}()
    37  
    38  	// Grant permission to regular users.
    39  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
    40  
    41  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
    42  
    43  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}, IsTrusted: true}
    44  
    45  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
    46  	CheckNoError(t, resp)
    47  	CheckCreatedStatus(t, resp)
    48  
    49  	if rapp.Name != oapp.Name {
    50  		t.Fatal("names did not match")
    51  	}
    52  
    53  	if rapp.IsTrusted != oapp.IsTrusted {
    54  		t.Fatal("trusted did no match")
    55  	}
    56  
    57  	// Revoke permission from regular users.
    58  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
    59  
    60  	_, resp = Client.CreateOAuthApp(oapp)
    61  	CheckForbiddenStatus(t, resp)
    62  
    63  	// Grant permission to regular users.
    64  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
    65  
    66  	rapp, resp = Client.CreateOAuthApp(oapp)
    67  	CheckNoError(t, resp)
    68  	CheckCreatedStatus(t, resp)
    69  
    70  	if rapp.IsTrusted {
    71  		t.Fatal("trusted should be false - created by non admin")
    72  	}
    73  
    74  	oapp.Name = ""
    75  	_, resp = AdminClient.CreateOAuthApp(oapp)
    76  	CheckBadRequestStatus(t, resp)
    77  
    78  	if r, err := Client.DoApiPost("/oauth/apps", "garbage"); err == nil {
    79  		t.Fatal("should have failed")
    80  	} else {
    81  		if r.StatusCode != http.StatusBadRequest {
    82  			t.Log("actual: " + strconv.Itoa(r.StatusCode))
    83  			t.Log("expected: " + strconv.Itoa(http.StatusBadRequest))
    84  			t.Fatal("wrong status code")
    85  		}
    86  	}
    87  
    88  	Client.Logout()
    89  	_, resp = Client.CreateOAuthApp(oapp)
    90  	CheckUnauthorizedStatus(t, resp)
    91  
    92  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
    93  	oapp.Name = GenerateTestAppName()
    94  	_, resp = AdminClient.CreateOAuthApp(oapp)
    95  	CheckNotImplementedStatus(t, resp)
    96  }
    97  
    98  func TestUpdateOAuthApp(t *testing.T) {
    99  	th := Setup().InitBasic().InitSystemAdmin()
   100  	defer th.TearDown()
   101  	Client := th.Client
   102  	AdminClient := th.SystemAdminClient
   103  
   104  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   105  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   106  	defer func() {
   107  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   108  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
   109  	}()
   110  
   111  	// Grant permission to regular users.
   112  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   113  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   114  
   115  	oapp := &model.OAuthApp{
   116  		Name:         "oapp",
   117  		IsTrusted:    false,
   118  		IconURL:      "https://nowhere.com/img",
   119  		Homepage:     "https://nowhere.com",
   120  		Description:  "test",
   121  		CallbackUrls: []string{"https://callback.com"},
   122  	}
   123  
   124  	oapp, _ = AdminClient.CreateOAuthApp(oapp)
   125  
   126  	oapp.Name = "oapp_update"
   127  	oapp.IsTrusted = true
   128  	oapp.IconURL = "https://nowhere.com/img_update"
   129  	oapp.Homepage = "https://nowhere_update.com"
   130  	oapp.Description = "test_update"
   131  	oapp.CallbackUrls = []string{"https://callback_update.com", "https://another_callback.com"}
   132  
   133  	updatedApp, resp := AdminClient.UpdateOAuthApp(oapp)
   134  	CheckNoError(t, resp)
   135  
   136  	if updatedApp.Id != oapp.Id {
   137  		t.Fatal("Id should have not updated")
   138  	}
   139  
   140  	if updatedApp.CreatorId != oapp.CreatorId {
   141  		t.Fatal("CreatorId should have not updated")
   142  	}
   143  
   144  	if updatedApp.CreateAt != oapp.CreateAt {
   145  		t.Fatal("CreateAt should have not updated")
   146  	}
   147  
   148  	if updatedApp.UpdateAt == oapp.UpdateAt {
   149  		t.Fatal("UpdateAt should have updated")
   150  	}
   151  
   152  	if updatedApp.ClientSecret != oapp.ClientSecret {
   153  		t.Fatal("ClientSecret should have not updated")
   154  	}
   155  
   156  	if updatedApp.Name != oapp.Name {
   157  		t.Fatal("Name should have updated")
   158  	}
   159  
   160  	if updatedApp.Description != oapp.Description {
   161  		t.Fatal("Description should have updated")
   162  	}
   163  
   164  	if updatedApp.IconURL != oapp.IconURL {
   165  		t.Fatal("IconURL should have updated")
   166  	}
   167  
   168  	if len(updatedApp.CallbackUrls) == len(oapp.CallbackUrls) {
   169  		for i, callbackUrl := range updatedApp.CallbackUrls {
   170  			if callbackUrl != oapp.CallbackUrls[i] {
   171  				t.Fatal("Description should have updated")
   172  			}
   173  		}
   174  	}
   175  
   176  	if updatedApp.Homepage != oapp.Homepage {
   177  		t.Fatal("Homepage should have updated")
   178  	}
   179  
   180  	if updatedApp.IsTrusted != oapp.IsTrusted {
   181  		t.Fatal("IsTrusted should have updated")
   182  	}
   183  
   184  	th.LoginBasic2()
   185  	updatedApp.CreatorId = th.BasicUser2.Id
   186  	_, resp = Client.UpdateOAuthApp(oapp)
   187  	CheckForbiddenStatus(t, resp)
   188  
   189  	th.LoginBasic()
   190  
   191  	// Revoke permission from regular users.
   192  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   193  
   194  	_, resp = Client.UpdateOAuthApp(oapp)
   195  	CheckForbiddenStatus(t, resp)
   196  
   197  	oapp.Id = "zhk9d1ggatrqz236c7h87im7bc"
   198  	_, resp = AdminClient.UpdateOAuthApp(oapp)
   199  	CheckNotFoundStatus(t, resp)
   200  
   201  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   202  
   203  	_, resp = AdminClient.UpdateOAuthApp(oapp)
   204  	CheckNotImplementedStatus(t, resp)
   205  
   206  	Client.Logout()
   207  	_, resp = Client.UpdateOAuthApp(oapp)
   208  	CheckUnauthorizedStatus(t, resp)
   209  
   210  	oapp.Id = "junk"
   211  	_, resp = AdminClient.UpdateOAuthApp(oapp)
   212  	CheckBadRequestStatus(t, resp)
   213  }
   214  
   215  func TestGetOAuthApps(t *testing.T) {
   216  	th := Setup().InitBasic().InitSystemAdmin()
   217  	defer th.TearDown()
   218  	Client := th.Client
   219  	AdminClient := th.SystemAdminClient
   220  
   221  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   222  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   223  	defer func() {
   224  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   225  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
   226  	}()
   227  
   228  	// Grant permission to regular users.
   229  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   230  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   231  
   232  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   233  
   234  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   235  	CheckNoError(t, resp)
   236  
   237  	oapp.Name = GenerateTestAppName()
   238  	rapp2, resp := Client.CreateOAuthApp(oapp)
   239  	CheckNoError(t, resp)
   240  
   241  	apps, resp := AdminClient.GetOAuthApps(0, 1000)
   242  	CheckNoError(t, resp)
   243  
   244  	found1 := false
   245  	found2 := false
   246  	for _, a := range apps {
   247  		if a.Id == rapp.Id {
   248  			found1 = true
   249  		}
   250  		if a.Id == rapp2.Id {
   251  			found2 = true
   252  		}
   253  	}
   254  
   255  	if !found1 || !found2 {
   256  		t.Fatal("missing oauth app")
   257  	}
   258  
   259  	apps, resp = AdminClient.GetOAuthApps(1, 1)
   260  	CheckNoError(t, resp)
   261  
   262  	if len(apps) != 1 {
   263  		t.Fatal("paging failed")
   264  	}
   265  
   266  	apps, resp = Client.GetOAuthApps(0, 1000)
   267  	CheckNoError(t, resp)
   268  
   269  	if len(apps) != 1 && apps[0].Id != rapp2.Id {
   270  		t.Fatal("wrong apps returned")
   271  	}
   272  
   273  	// Revoke permission from regular users.
   274  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   275  
   276  	_, resp = Client.GetOAuthApps(0, 1000)
   277  	CheckForbiddenStatus(t, resp)
   278  
   279  	Client.Logout()
   280  
   281  	_, resp = Client.GetOAuthApps(0, 1000)
   282  	CheckUnauthorizedStatus(t, resp)
   283  
   284  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   285  	_, resp = AdminClient.GetOAuthApps(0, 1000)
   286  	CheckNotImplementedStatus(t, resp)
   287  }
   288  
   289  func TestGetOAuthApp(t *testing.T) {
   290  	th := Setup().InitBasic().InitSystemAdmin()
   291  	defer th.TearDown()
   292  	Client := th.Client
   293  	AdminClient := th.SystemAdminClient
   294  
   295  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   296  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   297  	defer func() {
   298  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   299  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
   300  	}()
   301  
   302  	// Grant permission to regular users.
   303  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   304  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   305  
   306  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   307  
   308  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   309  	CheckNoError(t, resp)
   310  
   311  	oapp.Name = GenerateTestAppName()
   312  	rapp2, resp := Client.CreateOAuthApp(oapp)
   313  	CheckNoError(t, resp)
   314  
   315  	rrapp, resp := AdminClient.GetOAuthApp(rapp.Id)
   316  	CheckNoError(t, resp)
   317  
   318  	if rapp.Id != rrapp.Id {
   319  		t.Fatal("wrong app")
   320  	}
   321  
   322  	if rrapp.ClientSecret == "" {
   323  		t.Fatal("should not be sanitized")
   324  	}
   325  
   326  	rrapp2, resp := AdminClient.GetOAuthApp(rapp2.Id)
   327  	CheckNoError(t, resp)
   328  
   329  	if rapp2.Id != rrapp2.Id {
   330  		t.Fatal("wrong app")
   331  	}
   332  
   333  	if rrapp2.ClientSecret == "" {
   334  		t.Fatal("should not be sanitized")
   335  	}
   336  
   337  	_, resp = Client.GetOAuthApp(rapp2.Id)
   338  	CheckNoError(t, resp)
   339  
   340  	_, resp = Client.GetOAuthApp(rapp.Id)
   341  	CheckForbiddenStatus(t, resp)
   342  
   343  	// Revoke permission from regular users.
   344  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   345  
   346  	_, resp = Client.GetOAuthApp(rapp2.Id)
   347  	CheckForbiddenStatus(t, resp)
   348  
   349  	Client.Logout()
   350  
   351  	_, resp = Client.GetOAuthApp(rapp2.Id)
   352  	CheckUnauthorizedStatus(t, resp)
   353  
   354  	_, resp = AdminClient.GetOAuthApp("junk")
   355  	CheckBadRequestStatus(t, resp)
   356  
   357  	_, resp = AdminClient.GetOAuthApp(model.NewId())
   358  	CheckNotFoundStatus(t, resp)
   359  
   360  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   361  	_, resp = AdminClient.GetOAuthApp(rapp.Id)
   362  	CheckNotImplementedStatus(t, resp)
   363  }
   364  
   365  func TestGetOAuthAppInfo(t *testing.T) {
   366  	th := Setup().InitBasic().InitSystemAdmin()
   367  	defer th.TearDown()
   368  	Client := th.Client
   369  	AdminClient := th.SystemAdminClient
   370  
   371  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   372  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   373  	defer func() {
   374  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   375  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
   376  	}()
   377  
   378  	// Grant permission to regular users.
   379  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   380  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   381  
   382  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   383  
   384  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   385  	CheckNoError(t, resp)
   386  
   387  	oapp.Name = GenerateTestAppName()
   388  	rapp2, resp := Client.CreateOAuthApp(oapp)
   389  	CheckNoError(t, resp)
   390  
   391  	rrapp, resp := AdminClient.GetOAuthAppInfo(rapp.Id)
   392  	CheckNoError(t, resp)
   393  
   394  	if rapp.Id != rrapp.Id {
   395  		t.Fatal("wrong app")
   396  	}
   397  
   398  	if rrapp.ClientSecret != "" {
   399  		t.Fatal("should be sanitized")
   400  	}
   401  
   402  	rrapp2, resp := AdminClient.GetOAuthAppInfo(rapp2.Id)
   403  	CheckNoError(t, resp)
   404  
   405  	if rapp2.Id != rrapp2.Id {
   406  		t.Fatal("wrong app")
   407  	}
   408  
   409  	if rrapp2.ClientSecret != "" {
   410  		t.Fatal("should be sanitized")
   411  	}
   412  
   413  	_, resp = Client.GetOAuthAppInfo(rapp2.Id)
   414  	CheckNoError(t, resp)
   415  
   416  	_, resp = Client.GetOAuthAppInfo(rapp.Id)
   417  	CheckNoError(t, resp)
   418  
   419  	// Revoke permission from regular users.
   420  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   421  
   422  	_, resp = Client.GetOAuthAppInfo(rapp2.Id)
   423  	CheckNoError(t, resp)
   424  
   425  	Client.Logout()
   426  
   427  	_, resp = Client.GetOAuthAppInfo(rapp2.Id)
   428  	CheckUnauthorizedStatus(t, resp)
   429  
   430  	_, resp = AdminClient.GetOAuthAppInfo("junk")
   431  	CheckBadRequestStatus(t, resp)
   432  
   433  	_, resp = AdminClient.GetOAuthAppInfo(model.NewId())
   434  	CheckNotFoundStatus(t, resp)
   435  
   436  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   437  	_, resp = AdminClient.GetOAuthAppInfo(rapp.Id)
   438  	CheckNotImplementedStatus(t, resp)
   439  }
   440  
   441  func TestDeleteOAuthApp(t *testing.T) {
   442  	th := Setup().InitBasic().InitSystemAdmin()
   443  	defer th.TearDown()
   444  	Client := th.Client
   445  	AdminClient := th.SystemAdminClient
   446  
   447  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   448  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   449  	defer func() {
   450  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   451  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
   452  	}()
   453  
   454  	// Grant permission to regular users.
   455  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   456  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   457  
   458  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   459  
   460  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   461  	CheckNoError(t, resp)
   462  
   463  	oapp.Name = GenerateTestAppName()
   464  	rapp2, resp := Client.CreateOAuthApp(oapp)
   465  	CheckNoError(t, resp)
   466  
   467  	pass, resp := AdminClient.DeleteOAuthApp(rapp.Id)
   468  	CheckNoError(t, resp)
   469  
   470  	if !pass {
   471  		t.Fatal("should have passed")
   472  	}
   473  
   474  	_, resp = AdminClient.DeleteOAuthApp(rapp2.Id)
   475  	CheckNoError(t, resp)
   476  
   477  	rapp, resp = AdminClient.CreateOAuthApp(oapp)
   478  	CheckNoError(t, resp)
   479  
   480  	oapp.Name = GenerateTestAppName()
   481  	rapp2, resp = Client.CreateOAuthApp(oapp)
   482  	CheckNoError(t, resp)
   483  
   484  	_, resp = Client.DeleteOAuthApp(rapp.Id)
   485  	CheckForbiddenStatus(t, resp)
   486  
   487  	_, resp = Client.DeleteOAuthApp(rapp2.Id)
   488  	CheckNoError(t, resp)
   489  
   490  	// Revoke permission from regular users.
   491  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   492  
   493  	_, resp = Client.DeleteOAuthApp(rapp.Id)
   494  	CheckForbiddenStatus(t, resp)
   495  
   496  	Client.Logout()
   497  	_, resp = Client.DeleteOAuthApp(rapp.Id)
   498  	CheckUnauthorizedStatus(t, resp)
   499  
   500  	_, resp = AdminClient.DeleteOAuthApp("junk")
   501  	CheckBadRequestStatus(t, resp)
   502  
   503  	_, resp = AdminClient.DeleteOAuthApp(model.NewId())
   504  	CheckNotFoundStatus(t, resp)
   505  
   506  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   507  	_, resp = AdminClient.DeleteOAuthApp(rapp.Id)
   508  	CheckNotImplementedStatus(t, resp)
   509  }
   510  
   511  func TestRegenerateOAuthAppSecret(t *testing.T) {
   512  	th := Setup().InitBasic().InitSystemAdmin()
   513  	defer th.TearDown()
   514  	Client := th.Client
   515  	AdminClient := th.SystemAdminClient
   516  
   517  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   518  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   519  	defer func() {
   520  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   521  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
   522  	}()
   523  
   524  	// Grant permission to regular users.
   525  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   526  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   527  
   528  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   529  
   530  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   531  	CheckNoError(t, resp)
   532  
   533  	oapp.Name = GenerateTestAppName()
   534  	rapp2, resp := Client.CreateOAuthApp(oapp)
   535  	CheckNoError(t, resp)
   536  
   537  	rrapp, resp := AdminClient.RegenerateOAuthAppSecret(rapp.Id)
   538  	CheckNoError(t, resp)
   539  
   540  	if rrapp.Id != rapp.Id {
   541  		t.Fatal("wrong app")
   542  	}
   543  
   544  	if rrapp.ClientSecret == rapp.ClientSecret {
   545  		t.Fatal("secret didn't change")
   546  	}
   547  
   548  	_, resp = AdminClient.RegenerateOAuthAppSecret(rapp2.Id)
   549  	CheckNoError(t, resp)
   550  
   551  	rapp, resp = AdminClient.CreateOAuthApp(oapp)
   552  	CheckNoError(t, resp)
   553  
   554  	oapp.Name = GenerateTestAppName()
   555  	rapp2, resp = Client.CreateOAuthApp(oapp)
   556  	CheckNoError(t, resp)
   557  
   558  	_, resp = Client.RegenerateOAuthAppSecret(rapp.Id)
   559  	CheckForbiddenStatus(t, resp)
   560  
   561  	_, resp = Client.RegenerateOAuthAppSecret(rapp2.Id)
   562  	CheckNoError(t, resp)
   563  
   564  	// Revoke permission from regular users.
   565  	th.RemovePermissionFromRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   566  
   567  	_, resp = Client.RegenerateOAuthAppSecret(rapp.Id)
   568  	CheckForbiddenStatus(t, resp)
   569  
   570  	Client.Logout()
   571  	_, resp = Client.RegenerateOAuthAppSecret(rapp.Id)
   572  	CheckUnauthorizedStatus(t, resp)
   573  
   574  	_, resp = AdminClient.RegenerateOAuthAppSecret("junk")
   575  	CheckBadRequestStatus(t, resp)
   576  
   577  	_, resp = AdminClient.RegenerateOAuthAppSecret(model.NewId())
   578  	CheckNotFoundStatus(t, resp)
   579  
   580  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   581  	_, resp = AdminClient.RegenerateOAuthAppSecret(rapp.Id)
   582  	CheckNotImplementedStatus(t, resp)
   583  }
   584  
   585  func TestGetAuthorizedOAuthAppsForUser(t *testing.T) {
   586  	th := Setup().InitBasic().InitSystemAdmin()
   587  	defer th.TearDown()
   588  	Client := th.Client
   589  	AdminClient := th.SystemAdminClient
   590  
   591  	enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   592  	defer func() {
   593  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
   594  	}()
   595  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   596  
   597  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   598  
   599  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   600  	CheckNoError(t, resp)
   601  
   602  	authRequest := &model.AuthorizeRequest{
   603  		ResponseType: model.AUTHCODE_RESPONSE_TYPE,
   604  		ClientId:     rapp.Id,
   605  		RedirectUri:  rapp.CallbackUrls[0],
   606  		Scope:        "",
   607  		State:        "123",
   608  	}
   609  
   610  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   611  	CheckNoError(t, resp)
   612  
   613  	apps, resp := Client.GetAuthorizedOAuthAppsForUser(th.BasicUser.Id, 0, 1000)
   614  	CheckNoError(t, resp)
   615  
   616  	found := false
   617  	for _, a := range apps {
   618  		if a.Id == rapp.Id {
   619  			found = true
   620  		}
   621  
   622  		if a.ClientSecret != "" {
   623  			t.Fatal("not sanitized")
   624  		}
   625  	}
   626  
   627  	if !found {
   628  		t.Fatal("missing app")
   629  	}
   630  
   631  	_, resp = Client.GetAuthorizedOAuthAppsForUser(th.BasicUser2.Id, 0, 1000)
   632  	CheckForbiddenStatus(t, resp)
   633  
   634  	_, resp = Client.GetAuthorizedOAuthAppsForUser("junk", 0, 1000)
   635  	CheckBadRequestStatus(t, resp)
   636  
   637  	Client.Logout()
   638  	_, resp = Client.GetAuthorizedOAuthAppsForUser(th.BasicUser.Id, 0, 1000)
   639  	CheckUnauthorizedStatus(t, resp)
   640  
   641  	_, resp = AdminClient.GetAuthorizedOAuthAppsForUser(th.BasicUser.Id, 0, 1000)
   642  	CheckNoError(t, resp)
   643  }
   644  
   645  func TestAuthorizeOAuthApp(t *testing.T) {
   646  	th := Setup().InitBasic().InitSystemAdmin()
   647  	defer th.TearDown()
   648  	Client := th.Client
   649  	AdminClient := th.SystemAdminClient
   650  
   651  	enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   652  	defer func() {
   653  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
   654  	}()
   655  
   656  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   657  
   658  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   659  
   660  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   661  	CheckNoError(t, resp)
   662  
   663  	authRequest := &model.AuthorizeRequest{
   664  		ResponseType: model.AUTHCODE_RESPONSE_TYPE,
   665  		ClientId:     rapp.Id,
   666  		RedirectUri:  rapp.CallbackUrls[0],
   667  		Scope:        "",
   668  		State:        "123",
   669  	}
   670  
   671  	// Test auth code flow
   672  	ruri, resp := Client.AuthorizeOAuthApp(authRequest)
   673  	CheckNoError(t, resp)
   674  
   675  	if len(ruri) == 0 {
   676  		t.Fatal("redirect url should be set")
   677  	}
   678  
   679  	ru, _ := url.Parse(ruri)
   680  	if ru == nil {
   681  		t.Fatal("redirect url unparseable")
   682  	} else {
   683  		if len(ru.Query().Get("code")) == 0 {
   684  			t.Fatal("authorization code not returned")
   685  		}
   686  		if ru.Query().Get("state") != authRequest.State {
   687  			t.Fatal("returned state doesn't match")
   688  		}
   689  	}
   690  
   691  	// Test implicit flow
   692  	authRequest.ResponseType = model.IMPLICIT_RESPONSE_TYPE
   693  	ruri, resp = Client.AuthorizeOAuthApp(authRequest)
   694  	CheckNoError(t, resp)
   695  	require.False(t, len(ruri) == 0, "redirect url should be set")
   696  
   697  	ru, _ = url.Parse(ruri)
   698  	require.NotNil(t, ru, "redirect url unparseable")
   699  	values, err := url.ParseQuery(ru.Fragment)
   700  	require.Nil(t, err)
   701  	assert.False(t, len(values.Get("access_token")) == 0, "access_token not returned")
   702  	assert.Equal(t, authRequest.State, values.Get("state"), "returned state doesn't match")
   703  
   704  	oldToken := Client.AuthToken
   705  	Client.AuthToken = values.Get("access_token")
   706  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   707  	CheckForbiddenStatus(t, resp)
   708  
   709  	Client.AuthToken = oldToken
   710  
   711  	authRequest.RedirectUri = ""
   712  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   713  	CheckBadRequestStatus(t, resp)
   714  
   715  	authRequest.RedirectUri = "http://somewhereelse.com"
   716  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   717  	CheckBadRequestStatus(t, resp)
   718  
   719  	authRequest.RedirectUri = rapp.CallbackUrls[0]
   720  	authRequest.ResponseType = ""
   721  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   722  	CheckBadRequestStatus(t, resp)
   723  
   724  	authRequest.ResponseType = model.AUTHCODE_RESPONSE_TYPE
   725  	authRequest.ClientId = ""
   726  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   727  	CheckBadRequestStatus(t, resp)
   728  
   729  	authRequest.ClientId = model.NewId()
   730  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   731  	CheckNotFoundStatus(t, resp)
   732  }
   733  
   734  func TestDeauthorizeOAuthApp(t *testing.T) {
   735  	th := Setup().InitBasic().InitSystemAdmin()
   736  	defer th.TearDown()
   737  	Client := th.Client
   738  	AdminClient := th.SystemAdminClient
   739  
   740  	enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   741  	defer func() {
   742  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
   743  	}()
   744  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   745  
   746  	oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   747  
   748  	rapp, resp := AdminClient.CreateOAuthApp(oapp)
   749  	CheckNoError(t, resp)
   750  
   751  	authRequest := &model.AuthorizeRequest{
   752  		ResponseType: model.AUTHCODE_RESPONSE_TYPE,
   753  		ClientId:     rapp.Id,
   754  		RedirectUri:  rapp.CallbackUrls[0],
   755  		Scope:        "",
   756  		State:        "123",
   757  	}
   758  
   759  	_, resp = Client.AuthorizeOAuthApp(authRequest)
   760  	CheckNoError(t, resp)
   761  
   762  	pass, resp := Client.DeauthorizeOAuthApp(rapp.Id)
   763  	CheckNoError(t, resp)
   764  
   765  	if !pass {
   766  		t.Fatal("should have passed")
   767  	}
   768  
   769  	_, resp = Client.DeauthorizeOAuthApp("junk")
   770  	CheckBadRequestStatus(t, resp)
   771  
   772  	_, resp = Client.DeauthorizeOAuthApp(model.NewId())
   773  	CheckNoError(t, resp)
   774  
   775  	Client.Logout()
   776  	_, resp = Client.DeauthorizeOAuthApp(rapp.Id)
   777  	CheckUnauthorizedStatus(t, resp)
   778  }
   779  
   780  func TestOAuthAccessToken(t *testing.T) {
   781  	if testing.Short() {
   782  		t.SkipNow()
   783  	}
   784  
   785  	th := Setup().InitBasic()
   786  	defer th.TearDown()
   787  
   788  	Client := th.Client
   789  
   790  	enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
   791  	defer func() {
   792  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
   793  	}()
   794  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   795  
   796  	defaultRolePermissions := th.SaveDefaultRolePermissions()
   797  	defer func() {
   798  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
   799  	}()
   800  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
   801  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
   802  
   803  	oauthApp := &model.OAuthApp{Name: "TestApp5" + model.NewId(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
   804  	oauthApp = Client.Must(Client.CreateOAuthApp(oauthApp)).(*model.OAuthApp)
   805  
   806  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = false })
   807  	data := url.Values{"grant_type": []string{"junk"}, "client_id": []string{"12345678901234567890123456"}, "client_secret": []string{"12345678901234567890123456"}, "code": []string{"junk"}, "redirect_uri": []string{oauthApp.CallbackUrls[0]}}
   808  
   809  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   810  		t.Log(resp.StatusCode)
   811  		t.Fatal("should have failed - oauth providing turned off")
   812  	}
   813  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
   814  
   815  	authRequest := &model.AuthorizeRequest{
   816  		ResponseType: model.AUTHCODE_RESPONSE_TYPE,
   817  		ClientId:     oauthApp.Id,
   818  		RedirectUri:  oauthApp.CallbackUrls[0],
   819  		Scope:        "all",
   820  		State:        "123",
   821  	}
   822  
   823  	redirect, resp := Client.AuthorizeOAuthApp(authRequest)
   824  	CheckNoError(t, resp)
   825  	rurl, _ := url.Parse(redirect)
   826  
   827  	Client.Logout()
   828  
   829  	data = url.Values{"grant_type": []string{"junk"}, "client_id": []string{oauthApp.Id}, "client_secret": []string{oauthApp.ClientSecret}, "code": []string{rurl.Query().Get("code")}, "redirect_uri": []string{oauthApp.CallbackUrls[0]}}
   830  
   831  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   832  		t.Fatal("should have failed - bad grant type")
   833  	}
   834  
   835  	data.Set("grant_type", model.ACCESS_TOKEN_GRANT_TYPE)
   836  	data.Set("client_id", "")
   837  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   838  		t.Fatal("should have failed - missing client id")
   839  	}
   840  	data.Set("client_id", "junk")
   841  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   842  		t.Fatal("should have failed - bad client id")
   843  	}
   844  
   845  	data.Set("client_id", oauthApp.Id)
   846  	data.Set("client_secret", "")
   847  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   848  		t.Fatal("should have failed - missing client secret")
   849  	}
   850  
   851  	data.Set("client_secret", "junk")
   852  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   853  		t.Fatal("should have failed - bad client secret")
   854  	}
   855  
   856  	data.Set("client_secret", oauthApp.ClientSecret)
   857  	data.Set("code", "")
   858  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   859  		t.Fatal("should have failed - missing code")
   860  	}
   861  
   862  	data.Set("code", "junk")
   863  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   864  		t.Fatal("should have failed - bad code")
   865  	}
   866  
   867  	data.Set("code", rurl.Query().Get("code"))
   868  	data.Set("redirect_uri", "junk")
   869  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   870  		t.Fatal("should have failed - non-matching redirect uri")
   871  	}
   872  
   873  	// reset data for successful request
   874  	data.Set("grant_type", model.ACCESS_TOKEN_GRANT_TYPE)
   875  	data.Set("client_id", oauthApp.Id)
   876  	data.Set("client_secret", oauthApp.ClientSecret)
   877  	data.Set("code", rurl.Query().Get("code"))
   878  	data.Set("redirect_uri", oauthApp.CallbackUrls[0])
   879  
   880  	token := ""
   881  	refreshToken := ""
   882  	if rsp, resp := Client.GetOAuthAccessToken(data); resp.Error != nil {
   883  		t.Fatal(resp.Error)
   884  	} else {
   885  		if len(rsp.AccessToken) == 0 {
   886  			t.Fatal("access token not returned")
   887  		} else if len(rsp.RefreshToken) == 0 {
   888  			t.Fatal("refresh token not returned")
   889  		} else {
   890  			token = rsp.AccessToken
   891  			refreshToken = rsp.RefreshToken
   892  		}
   893  		if rsp.TokenType != model.ACCESS_TOKEN_TYPE {
   894  			t.Fatal("access token type incorrect")
   895  		}
   896  	}
   897  
   898  	if _, err := Client.DoApiGet("/users?page=0&per_page=100&access_token="+token, ""); err != nil {
   899  		t.Fatal(err)
   900  	}
   901  
   902  	if _, resp := Client.GetUsers(0, 100, ""); resp.Error == nil {
   903  		t.Fatal("should have failed - no access token provided")
   904  	}
   905  
   906  	if _, resp := Client.GetUsers(0, 100, ""); resp.Error == nil {
   907  		t.Fatal("should have failed - bad access token provided")
   908  	}
   909  
   910  	Client.SetOAuthToken(token)
   911  	if users, resp := Client.GetUsers(0, 100, ""); resp.Error != nil {
   912  		t.Fatal(resp.Error)
   913  	} else {
   914  		if len(users) == 0 {
   915  			t.Fatal("users empty - did not get results correctly")
   916  		}
   917  	}
   918  
   919  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   920  		t.Fatal("should have failed - tried to reuse auth code")
   921  	}
   922  
   923  	data.Set("grant_type", model.REFRESH_TOKEN_GRANT_TYPE)
   924  	data.Set("client_id", oauthApp.Id)
   925  	data.Set("client_secret", oauthApp.ClientSecret)
   926  	data.Set("refresh_token", "")
   927  	data.Set("redirect_uri", oauthApp.CallbackUrls[0])
   928  	data.Del("code")
   929  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   930  		t.Fatal("Should have failed - refresh token empty")
   931  	}
   932  
   933  	data.Set("refresh_token", refreshToken)
   934  	if rsp, resp := Client.GetOAuthAccessToken(data); resp.Error != nil {
   935  		t.Fatal(resp.Error)
   936  	} else {
   937  		if len(rsp.AccessToken) == 0 {
   938  			t.Fatal("access token not returned")
   939  		} else if len(rsp.RefreshToken) == 0 {
   940  			t.Fatal("refresh token not returned")
   941  		} else if rsp.RefreshToken == refreshToken {
   942  			t.Fatal("refresh token did not update")
   943  		}
   944  
   945  		if rsp.TokenType != model.ACCESS_TOKEN_TYPE {
   946  			t.Fatal("access token type incorrect")
   947  		}
   948  		Client.SetOAuthToken(rsp.AccessToken)
   949  		_, resp = Client.GetMe("")
   950  		if resp.Error != nil {
   951  			t.Fatal(resp.Error)
   952  		}
   953  
   954  		data.Set("refresh_token", rsp.RefreshToken)
   955  	}
   956  
   957  	if rsp, resp := Client.GetOAuthAccessToken(data); resp.Error != nil {
   958  		t.Fatal(resp.Error)
   959  	} else {
   960  		if len(rsp.AccessToken) == 0 {
   961  			t.Fatal("access token not returned")
   962  		} else if len(rsp.RefreshToken) == 0 {
   963  			t.Fatal("refresh token not returned")
   964  		} else if rsp.RefreshToken == refreshToken {
   965  			t.Fatal("refresh token did not update")
   966  		}
   967  
   968  		if rsp.TokenType != model.ACCESS_TOKEN_TYPE {
   969  			t.Fatal("access token type incorrect")
   970  		}
   971  		Client.SetOAuthToken(rsp.AccessToken)
   972  		_, resp = Client.GetMe("")
   973  		if resp.Error != nil {
   974  			t.Fatal(resp.Error)
   975  		}
   976  	}
   977  
   978  	authData := &model.AuthData{ClientId: oauthApp.Id, RedirectUri: oauthApp.CallbackUrls[0], UserId: th.BasicUser.Id, Code: model.NewId(), ExpiresIn: -1}
   979  	<-th.App.Srv.Store.OAuth().SaveAuthData(authData)
   980  
   981  	data.Set("grant_type", model.ACCESS_TOKEN_GRANT_TYPE)
   982  	data.Set("client_id", oauthApp.Id)
   983  	data.Set("client_secret", oauthApp.ClientSecret)
   984  	data.Set("redirect_uri", oauthApp.CallbackUrls[0])
   985  	data.Set("code", authData.Code)
   986  	data.Del("refresh_token")
   987  	if _, resp := Client.GetOAuthAccessToken(data); resp.Error == nil {
   988  		t.Fatal("Should have failed - code is expired")
   989  	}
   990  
   991  	Client.ClearOAuthToken()
   992  }
   993  
   994  func TestOAuthComplete(t *testing.T) {
   995  	if testing.Short() {
   996  		t.SkipNow()
   997  	}
   998  
   999  	th := Setup().InitBasic()
  1000  	defer th.TearDown()
  1001  
  1002  	Client := th.Client
  1003  
  1004  	gitLabSettingsEnable := th.App.Config().GitLabSettings.Enable
  1005  	gitLabSettingsAuthEndpoint := th.App.Config().GitLabSettings.AuthEndpoint
  1006  	gitLabSettingsId := th.App.Config().GitLabSettings.Id
  1007  	gitLabSettingsSecret := th.App.Config().GitLabSettings.Secret
  1008  	gitLabSettingsTokenEndpoint := th.App.Config().GitLabSettings.TokenEndpoint
  1009  	gitLabSettingsUserApiEndpoint := th.App.Config().GitLabSettings.UserApiEndpoint
  1010  	enableOAuthServiceProvider := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
  1011  	defer func() {
  1012  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Enable = gitLabSettingsEnable })
  1013  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.AuthEndpoint = gitLabSettingsAuthEndpoint })
  1014  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Id = gitLabSettingsId })
  1015  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Secret = gitLabSettingsSecret })
  1016  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.TokenEndpoint = gitLabSettingsTokenEndpoint })
  1017  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.UserApiEndpoint = gitLabSettingsUserApiEndpoint })
  1018  		th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuthServiceProvider })
  1019  	}()
  1020  
  1021  	r, err := HttpGet(Client.Url+"/login/gitlab/complete?code=123", Client.HttpClient, "", true)
  1022  	assert.NotNil(t, err)
  1023  	closeBody(r)
  1024  
  1025  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Enable = true })
  1026  	r, err = HttpGet(Client.Url+"/login/gitlab/complete?code=123&state=!#$#F@#Yˆ&~ñ", Client.HttpClient, "", true)
  1027  	assert.NotNil(t, err)
  1028  	closeBody(r)
  1029  
  1030  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.AuthEndpoint = Client.Url + "/oauth/authorize" })
  1031  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Id = model.NewId() })
  1032  
  1033  	stateProps := map[string]string{}
  1034  	stateProps["action"] = model.OAUTH_ACTION_LOGIN
  1035  	stateProps["team_id"] = th.BasicTeam.Id
  1036  	stateProps["redirect_to"] = th.App.Config().GitLabSettings.AuthEndpoint
  1037  
  1038  	state := base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
  1039  	r, err = HttpGet(Client.Url+"/login/gitlab/complete?code=123&state="+url.QueryEscape(state), Client.HttpClient, "", true)
  1040  	assert.NotNil(t, err)
  1041  	closeBody(r)
  1042  
  1043  	stateProps["hash"] = utils.HashSha256(th.App.Config().GitLabSettings.Id)
  1044  	state = base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
  1045  	r, err = HttpGet(Client.Url+"/login/gitlab/complete?code=123&state="+url.QueryEscape(state), Client.HttpClient, "", true)
  1046  	assert.NotNil(t, err)
  1047  	closeBody(r)
  1048  
  1049  	// We are going to use mattermost as the provider emulating gitlab
  1050  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
  1051  
  1052  	defaultRolePermissions := th.SaveDefaultRolePermissions()
  1053  	defer func() {
  1054  		th.RestoreDefaultRolePermissions(defaultRolePermissions)
  1055  	}()
  1056  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.TEAM_USER_ROLE_ID)
  1057  	th.AddPermissionToRole(model.PERMISSION_MANAGE_OAUTH.Id, model.SYSTEM_USER_ROLE_ID)
  1058  
  1059  	oauthApp := &model.OAuthApp{
  1060  		Name:        "TestApp5" + model.NewId(),
  1061  		Homepage:    "https://nowhere.com",
  1062  		Description: "test",
  1063  		CallbackUrls: []string{
  1064  			Client.Url + "/signup/" + model.SERVICE_GITLAB + "/complete",
  1065  			Client.Url + "/login/" + model.SERVICE_GITLAB + "/complete",
  1066  		},
  1067  		IsTrusted: true,
  1068  	}
  1069  	oauthApp = Client.Must(Client.CreateOAuthApp(oauthApp)).(*model.OAuthApp)
  1070  
  1071  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Id = oauthApp.Id })
  1072  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.Secret = oauthApp.ClientSecret })
  1073  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.AuthEndpoint = Client.Url + "/oauth/authorize" })
  1074  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.TokenEndpoint = Client.Url + "/oauth/access_token" })
  1075  	th.App.UpdateConfig(func(cfg *model.Config) { cfg.GitLabSettings.UserApiEndpoint = Client.ApiUrl + "/users/me" })
  1076  
  1077  	provider := &MattermostTestProvider{}
  1078  
  1079  	authRequest := &model.AuthorizeRequest{
  1080  		ResponseType: model.AUTHCODE_RESPONSE_TYPE,
  1081  		ClientId:     oauthApp.Id,
  1082  		RedirectUri:  oauthApp.CallbackUrls[0],
  1083  		Scope:        "all",
  1084  		State:        "123",
  1085  	}
  1086  
  1087  	redirect, resp := Client.AuthorizeOAuthApp(authRequest)
  1088  	CheckNoError(t, resp)
  1089  	rurl, _ := url.Parse(redirect)
  1090  
  1091  	code := rurl.Query().Get("code")
  1092  	stateProps["action"] = model.OAUTH_ACTION_EMAIL_TO_SSO
  1093  	delete(stateProps, "team_id")
  1094  	stateProps["redirect_to"] = th.App.Config().GitLabSettings.AuthEndpoint
  1095  	stateProps["hash"] = utils.HashSha256(th.App.Config().GitLabSettings.Id)
  1096  	stateProps["redirect_to"] = "/oauth/authorize"
  1097  	state = base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
  1098  	if r, err := HttpGet(Client.Url+"/login/"+model.SERVICE_GITLAB+"/complete?code="+url.QueryEscape(code)+"&state="+url.QueryEscape(state), Client.HttpClient, "", false); err == nil {
  1099  		closeBody(r)
  1100  	}
  1101  
  1102  	einterfaces.RegisterOauthProvider(model.SERVICE_GITLAB, provider)
  1103  
  1104  	redirect, resp = Client.AuthorizeOAuthApp(authRequest)
  1105  	CheckNoError(t, resp)
  1106  	rurl, _ = url.Parse(redirect)
  1107  
  1108  	code = rurl.Query().Get("code")
  1109  	if r, err := HttpGet(Client.Url+"/login/"+model.SERVICE_GITLAB+"/complete?code="+url.QueryEscape(code)+"&state="+url.QueryEscape(state), Client.HttpClient, "", false); err == nil {
  1110  		closeBody(r)
  1111  	}
  1112  
  1113  	if result := <-th.App.Srv.Store.User().UpdateAuthData(
  1114  		th.BasicUser.Id, model.SERVICE_GITLAB, &th.BasicUser.Email, th.BasicUser.Email, true); result.Err != nil {
  1115  		t.Fatal(result.Err)
  1116  	}
  1117  
  1118  	redirect, resp = Client.AuthorizeOAuthApp(authRequest)
  1119  	CheckNoError(t, resp)
  1120  	rurl, _ = url.Parse(redirect)
  1121  
  1122  	code = rurl.Query().Get("code")
  1123  	stateProps["action"] = model.OAUTH_ACTION_LOGIN
  1124  	state = base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
  1125  	if r, err := HttpGet(Client.Url+"/login/"+model.SERVICE_GITLAB+"/complete?code="+url.QueryEscape(code)+"&state="+url.QueryEscape(state), Client.HttpClient, "", false); err == nil {
  1126  		closeBody(r)
  1127  	}
  1128  
  1129  	redirect, resp = Client.AuthorizeOAuthApp(authRequest)
  1130  	CheckNoError(t, resp)
  1131  	rurl, _ = url.Parse(redirect)
  1132  
  1133  	code = rurl.Query().Get("code")
  1134  	delete(stateProps, "action")
  1135  	state = base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
  1136  	if r, err := HttpGet(Client.Url+"/login/"+model.SERVICE_GITLAB+"/complete?code="+url.QueryEscape(code)+"&state="+url.QueryEscape(state), Client.HttpClient, "", false); err == nil {
  1137  		closeBody(r)
  1138  	}
  1139  
  1140  	redirect, resp = Client.AuthorizeOAuthApp(authRequest)
  1141  	CheckNoError(t, resp)
  1142  	rurl, _ = url.Parse(redirect)
  1143  
  1144  	code = rurl.Query().Get("code")
  1145  	stateProps["action"] = model.OAUTH_ACTION_SIGNUP
  1146  	state = base64.StdEncoding.EncodeToString([]byte(model.MapToJson(stateProps)))
  1147  	if r, err := HttpGet(Client.Url+"/login/"+model.SERVICE_GITLAB+"/complete?code="+url.QueryEscape(code)+"&state="+url.QueryEscape(state), Client.HttpClient, "", false); err == nil {
  1148  		closeBody(r)
  1149  	}
  1150  }
  1151  
  1152  func TestOAuthComplete_AccessDenied(t *testing.T) {
  1153  	th := Setup().InitBasic()
  1154  	defer th.TearDown()
  1155  
  1156  	c := &Context{
  1157  		App: th.App,
  1158  		Params: &web.Params{
  1159  			Service: "TestService",
  1160  		},
  1161  	}
  1162  	responseWriter := httptest.NewRecorder()
  1163  	request, _ := http.NewRequest(http.MethodGet, th.App.GetSiteURL()+"/signup/TestService/complete?error=access_denied", nil)
  1164  
  1165  	completeOAuth(c, responseWriter, request)
  1166  
  1167  	response := responseWriter.Result()
  1168  
  1169  	assert.Equal(t, http.StatusTemporaryRedirect, response.StatusCode)
  1170  
  1171  	location, _ := url.Parse(response.Header.Get("Location"))
  1172  	assert.Equal(t, "oauth_access_denied", location.Query().Get("type"))
  1173  	assert.Equal(t, "TestService", location.Query().Get("service"))
  1174  }
  1175  
  1176  func HttpGet(url string, httpClient *http.Client, authToken string, followRedirect bool) (*http.Response, *model.AppError) {
  1177  	rq, _ := http.NewRequest("GET", url, nil)
  1178  	rq.Close = true
  1179  
  1180  	if len(authToken) > 0 {
  1181  		rq.Header.Set(model.HEADER_AUTH, authToken)
  1182  	}
  1183  
  1184  	if !followRedirect {
  1185  		httpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
  1186  			return http.ErrUseLastResponse
  1187  		}
  1188  	}
  1189  
  1190  	if rp, err := httpClient.Do(rq); err != nil {
  1191  		return nil, model.NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), 0)
  1192  	} else if rp.StatusCode == 304 {
  1193  		return rp, nil
  1194  	} else if rp.StatusCode == 307 {
  1195  		return rp, nil
  1196  	} else if rp.StatusCode >= 300 {
  1197  		defer closeBody(rp)
  1198  		return rp, model.AppErrorFromJson(rp.Body)
  1199  	} else {
  1200  		return rp, nil
  1201  	}
  1202  }
  1203  
  1204  func closeBody(r *http.Response) {
  1205  	if r != nil && r.Body != nil {
  1206  		ioutil.ReadAll(r.Body)
  1207  		r.Body.Close()
  1208  	}
  1209  }
  1210  
  1211  type MattermostTestProvider struct {
  1212  }
  1213  
  1214  func (m *MattermostTestProvider) GetUserFromJson(data io.Reader) *model.User {
  1215  	user := model.UserFromJson(data)
  1216  	user.AuthData = &user.Email
  1217  	return user
  1218  }