github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/storetest/oauth_store.go (about)

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