github.com/demisto/mattermost-server@v4.9.0-rc3+incompatible/store/storetest/oauth_store.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/mattermost/mattermost-server/model"
    10  	"github.com/mattermost/mattermost-server/store"
    11  )
    12  
    13  func TestOAuthStore(t *testing.T, ss store.Store) {
    14  	t.Run("SaveApp", func(t *testing.T) { testOAuthStoreSaveApp(t, ss) })
    15  	t.Run("GetApp", func(t *testing.T) { testOAuthStoreGetApp(t, ss) })
    16  	t.Run("UpdateApp", func(t *testing.T) { testOAuthStoreUpdateApp(t, ss) })
    17  	t.Run("SaveAccessData", func(t *testing.T) { testOAuthStoreSaveAccessData(t, ss) })
    18  	t.Run("OAuthUpdateAccessData", func(t *testing.T) { testOAuthUpdateAccessData(t, ss) })
    19  	t.Run("GetAccessData", func(t *testing.T) { testOAuthStoreGetAccessData(t, ss) })
    20  	t.Run("RemoveAccessData", func(t *testing.T) { testOAuthStoreRemoveAccessData(t, ss) })
    21  	t.Run("SaveAuthData", func(t *testing.T) { testOAuthStoreSaveAuthData(t, ss) })
    22  	t.Run("GetAuthData", func(t *testing.T) { testOAuthStoreGetAuthData(t, ss) })
    23  	t.Run("RemoveAuthData", func(t *testing.T) { testOAuthStoreRemoveAuthData(t, ss) })
    24  	t.Run("RemoveAuthDataByUser", func(t *testing.T) { testOAuthStoreRemoveAuthDataByUser(t, ss) })
    25  	t.Run("OAuthGetAuthorizedApps", func(t *testing.T) { testOAuthGetAuthorizedApps(t, ss) })
    26  	t.Run("OAuthGetAccessDataByUserForApp", func(t *testing.T) { testOAuthGetAccessDataByUserForApp(t, ss) })
    27  	t.Run("DeleteApp", func(t *testing.T) { testOAuthStoreDeleteApp(t, ss) })
    28  }
    29  
    30  func testOAuthStoreSaveApp(t *testing.T, ss store.Store) {
    31  	a1 := model.OAuthApp{}
    32  	a1.CreatorId = model.NewId()
    33  	a1.CallbackUrls = []string{"https://nowhere.com"}
    34  	a1.Homepage = "https://nowhere.com"
    35  
    36  	// Try to save an app that already has an Id
    37  	a1.Id = model.NewId()
    38  	if err := (<-ss.OAuth().SaveApp(&a1)).Err; err == nil {
    39  		t.Fatal("Should have failed, cannot add an OAuth app cannot be save with an Id, it has to be updated")
    40  	}
    41  
    42  	// Try to save an Invalid App
    43  	a1.Id = ""
    44  	if err := (<-ss.OAuth().SaveApp(&a1)).Err; err == nil {
    45  		t.Fatal("Should have failed, app should be invalid cause it doesn' have a name set")
    46  	}
    47  
    48  	// Save the app
    49  	a1.Id = ""
    50  	a1.Name = "TestApp" + model.NewId()
    51  	if err := (<-ss.OAuth().SaveApp(&a1)).Err; err != nil {
    52  		t.Fatal(err)
    53  	}
    54  }
    55  
    56  func testOAuthStoreGetApp(t *testing.T, ss store.Store) {
    57  	a1 := model.OAuthApp{}
    58  	a1.CreatorId = model.NewId()
    59  	a1.Name = "TestApp" + model.NewId()
    60  	a1.CallbackUrls = []string{"https://nowhere.com"}
    61  	a1.Homepage = "https://nowhere.com"
    62  	store.Must(ss.OAuth().SaveApp(&a1))
    63  
    64  	// Lets try to get and app that does not exists
    65  	if err := (<-ss.OAuth().GetApp("fake0123456789abcderfgret1")).Err; err == nil {
    66  		t.Fatal("Should have failed. App does not exists")
    67  	}
    68  
    69  	if err := (<-ss.OAuth().GetApp(a1.Id)).Err; err != nil {
    70  		t.Fatal(err)
    71  	}
    72  
    73  	// Lets try and get the app from a user that hasn't created any apps
    74  	if result := (<-ss.OAuth().GetAppByUser("fake0123456789abcderfgret1", 0, 1000)); result.Err == nil {
    75  		if len(result.Data.([]*model.OAuthApp)) > 0 {
    76  			t.Fatal("Should have failed. Fake user hasn't created any apps")
    77  		}
    78  	} else {
    79  		t.Fatal(result.Err)
    80  	}
    81  
    82  	if err := (<-ss.OAuth().GetAppByUser(a1.CreatorId, 0, 1000)).Err; err != nil {
    83  		t.Fatal(err)
    84  	}
    85  
    86  	if err := (<-ss.OAuth().GetApps(0, 1000)).Err; err != nil {
    87  		t.Fatal(err)
    88  	}
    89  }
    90  
    91  func testOAuthStoreUpdateApp(t *testing.T, ss store.Store) {
    92  	a1 := model.OAuthApp{}
    93  	a1.CreatorId = model.NewId()
    94  	a1.Name = "TestApp" + model.NewId()
    95  	a1.CallbackUrls = []string{"https://nowhere.com"}
    96  	a1.Homepage = "https://nowhere.com"
    97  	store.Must(ss.OAuth().SaveApp(&a1))
    98  
    99  	// temporarily save the created app id
   100  	id := a1.Id
   101  
   102  	a1.CreateAt = 1
   103  	a1.ClientSecret = "pwd"
   104  	a1.CreatorId = "12345678901234567890123456"
   105  
   106  	// Lets update the app by removing the name
   107  	a1.Name = ""
   108  	if result := <-ss.OAuth().UpdateApp(&a1); result.Err == nil {
   109  		t.Fatal("Should have failed. App name is not set")
   110  	}
   111  
   112  	// Lets not find the app that we are trying to update
   113  	a1.Id = "fake0123456789abcderfgret1"
   114  	a1.Name = "NewName"
   115  	if result := <-ss.OAuth().UpdateApp(&a1); result.Err == nil {
   116  		t.Fatal("Should have failed. Not able to find the app")
   117  	}
   118  
   119  	a1.Id = id
   120  	if result := <-ss.OAuth().UpdateApp(&a1); result.Err != nil {
   121  		t.Fatal(result.Err)
   122  	} else {
   123  		ua1 := (result.Data.([2]*model.OAuthApp)[0])
   124  		if ua1.Name != "NewName" {
   125  			t.Fatal("name did not update")
   126  		}
   127  		if ua1.CreateAt == 1 {
   128  			t.Fatal("create at should not have updated")
   129  		}
   130  		if ua1.CreatorId == "12345678901234567890123456" {
   131  			t.Fatal("creator id should not have updated")
   132  		}
   133  	}
   134  }
   135  
   136  func testOAuthStoreSaveAccessData(t *testing.T, ss store.Store) {
   137  	a1 := model.AccessData{}
   138  	a1.ClientId = model.NewId()
   139  	a1.UserId = model.NewId()
   140  
   141  	// Lets try and save an incomplete access data
   142  	if err := (<-ss.OAuth().SaveAccessData(&a1)).Err; err == nil {
   143  		t.Fatal("Should have failed. Access data needs the token")
   144  	}
   145  
   146  	a1.Token = model.NewId()
   147  	a1.RefreshToken = model.NewId()
   148  	a1.RedirectUri = "http://example.com"
   149  
   150  	if err := (<-ss.OAuth().SaveAccessData(&a1)).Err; err != nil {
   151  		t.Fatal(err)
   152  	}
   153  }
   154  
   155  func testOAuthUpdateAccessData(t *testing.T, ss store.Store) {
   156  	a1 := model.AccessData{}
   157  	a1.ClientId = model.NewId()
   158  	a1.UserId = model.NewId()
   159  	a1.Token = model.NewId()
   160  	a1.RefreshToken = model.NewId()
   161  	a1.ExpiresAt = model.GetMillis()
   162  	a1.RedirectUri = "http://example.com"
   163  	store.Must(ss.OAuth().SaveAccessData(&a1))
   164  
   165  	//Try to update to invalid Refresh Token
   166  	refreshToken := a1.RefreshToken
   167  	a1.RefreshToken = model.NewId() + "123"
   168  	if err := (<-ss.OAuth().UpdateAccessData(&a1)).Err; err == nil {
   169  		t.Fatal("Should have failed with invalid token")
   170  	}
   171  
   172  	//Try to update to invalid RedirectUri
   173  	a1.RefreshToken = model.NewId()
   174  	a1.RedirectUri = ""
   175  	if err := (<-ss.OAuth().UpdateAccessData(&a1)).Err; err == nil {
   176  		t.Fatal("Should have failed with invalid Redirect URI")
   177  	}
   178  
   179  	// Should update fine
   180  	a1.RedirectUri = "http://example.com"
   181  	if result := <-ss.OAuth().UpdateAccessData(&a1); result.Err != nil {
   182  		t.Fatal(result.Err)
   183  	} else {
   184  		ra1 := result.Data.(*model.AccessData)
   185  		if ra1.RefreshToken == refreshToken {
   186  			t.Fatal("refresh tokens didn't match")
   187  		}
   188  	}
   189  }
   190  
   191  func testOAuthStoreGetAccessData(t *testing.T, ss store.Store) {
   192  	a1 := model.AccessData{}
   193  	a1.ClientId = model.NewId()
   194  	a1.UserId = model.NewId()
   195  	a1.Token = model.NewId()
   196  	a1.RefreshToken = model.NewId()
   197  	a1.ExpiresAt = model.GetMillis()
   198  	a1.RedirectUri = "http://example.com"
   199  	store.Must(ss.OAuth().SaveAccessData(&a1))
   200  
   201  	if err := (<-ss.OAuth().GetAccessData("invalidToken")).Err; err == nil {
   202  		t.Fatal("Should have failed. There is no data with an invalid token")
   203  	}
   204  
   205  	if result := <-ss.OAuth().GetAccessData(a1.Token); result.Err != nil {
   206  		t.Fatal(result.Err)
   207  	} else {
   208  		ra1 := result.Data.(*model.AccessData)
   209  		if a1.Token != ra1.Token {
   210  			t.Fatal("tokens didn't match")
   211  		}
   212  	}
   213  
   214  	if err := (<-ss.OAuth().GetPreviousAccessData(a1.UserId, a1.ClientId)).Err; err != nil {
   215  		t.Fatal(err)
   216  	}
   217  
   218  	if err := (<-ss.OAuth().GetPreviousAccessData("user", "junk")).Err; err != nil {
   219  		t.Fatal(err)
   220  	}
   221  
   222  	// Try to get the Access data using an invalid refresh token
   223  	if err := (<-ss.OAuth().GetAccessDataByRefreshToken(a1.Token)).Err; err == nil {
   224  		t.Fatal("Should have failed. There is no data with an invalid token")
   225  	}
   226  
   227  	// Get the Access Data using the refresh token
   228  	if result := <-ss.OAuth().GetAccessDataByRefreshToken(a1.RefreshToken); result.Err != nil {
   229  		t.Fatal(result.Err)
   230  	} else {
   231  		ra1 := result.Data.(*model.AccessData)
   232  		if a1.RefreshToken != ra1.RefreshToken {
   233  			t.Fatal("tokens didn't match")
   234  		}
   235  	}
   236  }
   237  
   238  func testOAuthStoreRemoveAccessData(t *testing.T, ss store.Store) {
   239  	a1 := model.AccessData{}
   240  	a1.ClientId = model.NewId()
   241  	a1.UserId = model.NewId()
   242  	a1.Token = model.NewId()
   243  	a1.RefreshToken = model.NewId()
   244  	a1.RedirectUri = "http://example.com"
   245  	store.Must(ss.OAuth().SaveAccessData(&a1))
   246  
   247  	if err := (<-ss.OAuth().RemoveAccessData(a1.Token)).Err; err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	if result := (<-ss.OAuth().GetPreviousAccessData(a1.UserId, a1.ClientId)); result.Err != nil {
   252  	} else {
   253  		if result.Data != nil {
   254  			t.Fatal("did not delete access token")
   255  		}
   256  	}
   257  }
   258  
   259  func testOAuthStoreSaveAuthData(t *testing.T, ss store.Store) {
   260  	a1 := model.AuthData{}
   261  	a1.ClientId = model.NewId()
   262  	a1.UserId = model.NewId()
   263  	a1.Code = model.NewId()
   264  	a1.RedirectUri = "http://example.com"
   265  	if err := (<-ss.OAuth().SaveAuthData(&a1)).Err; err != nil {
   266  		t.Fatal(err)
   267  	}
   268  }
   269  
   270  func testOAuthStoreGetAuthData(t *testing.T, ss store.Store) {
   271  	a1 := model.AuthData{}
   272  	a1.ClientId = model.NewId()
   273  	a1.UserId = model.NewId()
   274  	a1.Code = model.NewId()
   275  	a1.RedirectUri = "http://example.com"
   276  	store.Must(ss.OAuth().SaveAuthData(&a1))
   277  
   278  	if err := (<-ss.OAuth().GetAuthData(a1.Code)).Err; err != nil {
   279  		t.Fatal(err)
   280  	}
   281  }
   282  
   283  func testOAuthStoreRemoveAuthData(t *testing.T, ss store.Store) {
   284  	a1 := model.AuthData{}
   285  	a1.ClientId = model.NewId()
   286  	a1.UserId = model.NewId()
   287  	a1.Code = model.NewId()
   288  	a1.RedirectUri = "http://example.com"
   289  	store.Must(ss.OAuth().SaveAuthData(&a1))
   290  
   291  	if err := (<-ss.OAuth().RemoveAuthData(a1.Code)).Err; err != nil {
   292  		t.Fatal(err)
   293  	}
   294  
   295  	if err := (<-ss.OAuth().GetAuthData(a1.Code)).Err; err == nil {
   296  		t.Fatal("should have errored - auth code removed")
   297  	}
   298  }
   299  
   300  func testOAuthStoreRemoveAuthDataByUser(t *testing.T, ss store.Store) {
   301  	a1 := model.AuthData{}
   302  	a1.ClientId = model.NewId()
   303  	a1.UserId = model.NewId()
   304  	a1.Code = model.NewId()
   305  	a1.RedirectUri = "http://example.com"
   306  	store.Must(ss.OAuth().SaveAuthData(&a1))
   307  
   308  	if err := (<-ss.OAuth().PermanentDeleteAuthDataByUser(a1.UserId)).Err; err != nil {
   309  		t.Fatal(err)
   310  	}
   311  }
   312  
   313  func testOAuthGetAuthorizedApps(t *testing.T, ss store.Store) {
   314  	a1 := model.OAuthApp{}
   315  	a1.CreatorId = model.NewId()
   316  	a1.Name = "TestApp" + model.NewId()
   317  	a1.CallbackUrls = []string{"https://nowhere.com"}
   318  	a1.Homepage = "https://nowhere.com"
   319  	store.Must(ss.OAuth().SaveApp(&a1))
   320  
   321  	// Lets try and get an Authorized app for a user who hasn't authorized it
   322  	if result := <-ss.OAuth().GetAuthorizedApps("fake0123456789abcderfgret1", 0, 1000); result.Err == nil {
   323  		if len(result.Data.([]*model.OAuthApp)) > 0 {
   324  			t.Fatal("Should have failed. Fake user hasn't authorized the app")
   325  		}
   326  	} else {
   327  		t.Fatal(result.Err)
   328  	}
   329  
   330  	// allow the app
   331  	p := model.Preference{}
   332  	p.UserId = a1.CreatorId
   333  	p.Category = model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP
   334  	p.Name = a1.Id
   335  	p.Value = "true"
   336  	store.Must(ss.Preference().Save(&model.Preferences{p}))
   337  
   338  	if result := <-ss.OAuth().GetAuthorizedApps(a1.CreatorId, 0, 1000); result.Err != nil {
   339  		t.Fatal(result.Err)
   340  	} else {
   341  		apps := result.Data.([]*model.OAuthApp)
   342  		if len(apps) == 0 {
   343  			t.Fatal("It should have return apps")
   344  		}
   345  	}
   346  }
   347  
   348  func testOAuthGetAccessDataByUserForApp(t *testing.T, ss store.Store) {
   349  	a1 := model.OAuthApp{}
   350  	a1.CreatorId = model.NewId()
   351  	a1.Name = "TestApp" + model.NewId()
   352  	a1.CallbackUrls = []string{"https://nowhere.com"}
   353  	a1.Homepage = "https://nowhere.com"
   354  	store.Must(ss.OAuth().SaveApp(&a1))
   355  
   356  	// allow the app
   357  	p := model.Preference{}
   358  	p.UserId = a1.CreatorId
   359  	p.Category = model.PREFERENCE_CATEGORY_AUTHORIZED_OAUTH_APP
   360  	p.Name = a1.Id
   361  	p.Value = "true"
   362  	store.Must(ss.Preference().Save(&model.Preferences{p}))
   363  
   364  	if result := <-ss.OAuth().GetAuthorizedApps(a1.CreatorId, 0, 1000); result.Err != nil {
   365  		t.Fatal(result.Err)
   366  	} else {
   367  		apps := result.Data.([]*model.OAuthApp)
   368  		if len(apps) == 0 {
   369  			t.Fatal("It should have return apps")
   370  		}
   371  	}
   372  
   373  	// save the token
   374  	ad1 := model.AccessData{}
   375  	ad1.ClientId = a1.Id
   376  	ad1.UserId = a1.CreatorId
   377  	ad1.Token = model.NewId()
   378  	ad1.RefreshToken = model.NewId()
   379  	ad1.RedirectUri = "http://example.com"
   380  
   381  	if err := (<-ss.OAuth().SaveAccessData(&ad1)).Err; err != nil {
   382  		t.Fatal(err)
   383  	}
   384  
   385  	if result := <-ss.OAuth().GetAccessDataByUserForApp(a1.CreatorId, a1.Id); result.Err != nil {
   386  		t.Fatal(result.Err)
   387  	} else {
   388  		accessData := result.Data.([]*model.AccessData)
   389  		if len(accessData) == 0 {
   390  			t.Fatal("It should have return access data")
   391  		}
   392  	}
   393  }
   394  
   395  func testOAuthStoreDeleteApp(t *testing.T, ss store.Store) {
   396  	a1 := model.OAuthApp{}
   397  	a1.CreatorId = model.NewId()
   398  	a1.Name = "TestApp" + model.NewId()
   399  	a1.CallbackUrls = []string{"https://nowhere.com"}
   400  	a1.Homepage = "https://nowhere.com"
   401  	store.Must(ss.OAuth().SaveApp(&a1))
   402  
   403  	// delete a non-existent app
   404  	if err := (<-ss.OAuth().DeleteApp("fakeclientId")).Err; err != nil {
   405  		t.Fatal(err)
   406  	}
   407  
   408  	s1 := model.Session{}
   409  	s1.UserId = model.NewId()
   410  	s1.Token = model.NewId()
   411  	s1.IsOAuth = true
   412  
   413  	store.Must(ss.Session().Save(&s1))
   414  
   415  	ad1 := model.AccessData{}
   416  	ad1.ClientId = a1.Id
   417  	ad1.UserId = a1.CreatorId
   418  	ad1.Token = s1.Token
   419  	ad1.RefreshToken = model.NewId()
   420  	ad1.RedirectUri = "http://example.com"
   421  
   422  	store.Must(ss.OAuth().SaveAccessData(&ad1))
   423  
   424  	if err := (<-ss.OAuth().DeleteApp(a1.Id)).Err; err != nil {
   425  		t.Fatal(err)
   426  	}
   427  
   428  	if err := (<-ss.Session().Get(s1.Token)).Err; err == nil {
   429  		t.Fatal("should error - session should be deleted")
   430  	}
   431  
   432  	if err := (<-ss.OAuth().GetAccessData(s1.Token)).Err; err == nil {
   433  		t.Fatal("should error - access data should be deleted")
   434  	}
   435  }