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