github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+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 }