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