github.com/RichardKnop/Go-oauth2-server@v1.0.1/oauth/refresh_token_test.go (about) 1 package oauth_test 2 3 import ( 4 "time" 5 6 "github.com/RichardKnop/go-oauth2-server/models" 7 "github.com/RichardKnop/go-oauth2-server/oauth" 8 "github.com/RichardKnop/uuid" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func (suite *OauthTestSuite) TestGetOrCreateRefreshTokenCreatesNew() { 13 var ( 14 refreshToken *models.OauthRefreshToken 15 err error 16 tokens []*models.OauthRefreshToken 17 ) 18 19 // Since there is no user specific token, 20 // a new one should be created and returned 21 refreshToken, err = suite.service.GetOrCreateRefreshToken( 22 suite.clients[0], // client 23 suite.users[0], // user 24 3600, // expires in 25 "read_write", // scope 26 ) 27 28 // Error should be nil 29 if assert.Nil(suite.T(), err) { 30 // Fetch all refresh tokens 31 models.OauthRefreshTokenPreload(suite.db).Order("created_at").Find(&tokens) 32 33 // There should be just one token now 34 assert.Equal(suite.T(), 1, len(tokens)) 35 36 // Correct refresh token object should be returned 37 assert.NotNil(suite.T(), refreshToken) 38 assert.Equal(suite.T(), tokens[0].Token, refreshToken.Token) 39 40 // Client ID should be set 41 assert.True(suite.T(), tokens[0].ClientID.Valid) 42 assert.Equal(suite.T(), suite.clients[0].ID, tokens[0].Client.ID) 43 44 // User ID should be set 45 assert.True(suite.T(), tokens[0].UserID.Valid) 46 assert.Equal(suite.T(), suite.users[0].ID, tokens[0].User.ID) 47 } 48 49 // Valid user specific token exists, new one should NOT be created 50 refreshToken, err = suite.service.GetOrCreateRefreshToken( 51 suite.clients[0], // client 52 suite.users[0], // user 53 3600, // expires in 54 "read_write", // scope 55 ) 56 57 // Error should be nil 58 if assert.Nil(suite.T(), err) { 59 // Fetch all refresh tokens 60 models.OauthRefreshTokenPreload(suite.db).Order("created_at").Find(&tokens) 61 62 // There should be just one token now 63 assert.Equal(suite.T(), 1, len(tokens)) 64 65 // Correct refresh token object should be returned 66 assert.NotNil(suite.T(), refreshToken) 67 assert.Equal(suite.T(), tokens[0].Token, refreshToken.Token) 68 69 // Client ID should be set 70 assert.True(suite.T(), tokens[0].ClientID.Valid) 71 assert.Equal(suite.T(), suite.clients[0].ID, tokens[0].Client.ID) 72 73 // User ID should be set 74 assert.True(suite.T(), tokens[0].UserID.Valid) 75 assert.Equal(suite.T(), suite.users[0].ID, tokens[0].User.ID) 76 } 77 78 // Since there is no client only token, 79 // a new one should be created and returned 80 refreshToken, err = suite.service.GetOrCreateRefreshToken( 81 suite.clients[0], // client 82 nil, // user 83 3600, // expires in 84 "read_write", // scope 85 ) 86 87 // Error should be nil 88 if assert.Nil(suite.T(), err) { 89 // Fetch all refresh tokens 90 models.OauthRefreshTokenPreload(suite.db).Order("created_at").Find(&tokens) 91 92 // There should be 2 tokens 93 assert.Equal(suite.T(), 2, len(tokens)) 94 95 // Correct refresh token object should be returned 96 assert.NotNil(suite.T(), refreshToken) 97 assert.Equal(suite.T(), tokens[1].Token, refreshToken.Token) 98 99 // Client ID should be set 100 assert.True(suite.T(), tokens[1].ClientID.Valid) 101 assert.Equal(suite.T(), suite.clients[0].ID, tokens[1].Client.ID) 102 103 // User ID should be nil 104 assert.False(suite.T(), tokens[1].UserID.Valid) 105 } 106 107 // Valid client only token exists, new one should NOT be created 108 refreshToken, err = suite.service.GetOrCreateRefreshToken( 109 suite.clients[0], // client 110 nil, // user 111 3600, // expires in 112 "read_write", // scope 113 ) 114 115 // Error should be nil 116 if assert.Nil(suite.T(), err) { 117 // Fetch all refresh tokens 118 models.OauthRefreshTokenPreload(suite.db).Order("created_at").Find(&tokens) 119 120 // There should be 2 tokens 121 assert.Equal(suite.T(), 2, len(tokens)) 122 123 // Correct refresh token object should be returned 124 assert.NotNil(suite.T(), refreshToken) 125 assert.Equal(suite.T(), tokens[1].Token, refreshToken.Token) 126 127 // Client ID should be set 128 assert.True(suite.T(), tokens[1].ClientID.Valid) 129 assert.Equal(suite.T(), suite.clients[0].ID, tokens[1].Client.ID) 130 131 // User ID should be nil 132 assert.False(suite.T(), tokens[1].UserID.Valid) 133 } 134 } 135 136 func (suite *OauthTestSuite) TestGetOrCreateRefreshTokenReturnsExisting() { 137 var ( 138 refreshToken *models.OauthRefreshToken 139 err error 140 tokens []*models.OauthRefreshToken 141 ) 142 143 // Insert an access token without a user 144 err = suite.db.Create(&models.OauthRefreshToken{ 145 MyGormModel: models.MyGormModel{ 146 ID: uuid.New(), 147 CreatedAt: time.Now().UTC(), 148 }, 149 Token: "test_token", 150 ExpiresAt: time.Now().UTC().Add(+10 * time.Second), 151 Client: suite.clients[0], 152 }).Error 153 assert.NoError(suite.T(), err, "Inserting test data failed") 154 155 // Since the current client only token is valid, this should just return it 156 refreshToken, err = suite.service.GetOrCreateRefreshToken( 157 suite.clients[0], // client 158 nil, // user 159 3600, // expires in 160 "read_write", // scope 161 ) 162 163 // Error should be Nil 164 assert.Nil(suite.T(), err) 165 166 // Correct refresh token should be returned 167 if assert.NotNil(suite.T(), refreshToken) { 168 // Fetch all refresh tokens 169 models.OauthRefreshTokenPreload(suite.db).Order("created_at").Find(&tokens) 170 171 // There should be just one token right now 172 assert.Equal(suite.T(), 1, len(tokens)) 173 174 // Correct refresh token object should be returned 175 assert.NotNil(suite.T(), refreshToken) 176 assert.Equal(suite.T(), tokens[0].Token, refreshToken.Token) 177 assert.Equal(suite.T(), "test_token", refreshToken.Token) 178 assert.Equal(suite.T(), "test_token", tokens[0].Token) 179 180 // Client ID should be set 181 assert.True(suite.T(), tokens[0].ClientID.Valid) 182 assert.Equal(suite.T(), string(suite.clients[0].ID), tokens[0].ClientID.String) 183 184 // User ID should be nil 185 assert.False(suite.T(), tokens[0].UserID.Valid) 186 } 187 188 // Insert an access token with a user 189 err = suite.db.Create(&models.OauthRefreshToken{ 190 MyGormModel: models.MyGormModel{ 191 ID: uuid.New(), 192 CreatedAt: time.Now().UTC(), 193 }, 194 Token: "test_token2", 195 ExpiresAt: time.Now().UTC().Add(+10 * time.Second), 196 Client: suite.clients[0], 197 User: suite.users[0], 198 }).Error 199 assert.NoError(suite.T(), err, "Inserting test data failed") 200 201 // Since the current user specific only token is valid, 202 // this should just return it 203 refreshToken, err = suite.service.GetOrCreateRefreshToken( 204 suite.clients[0], // client 205 suite.users[0], // user 206 3600, // expires in 207 "read_write", // scope 208 ) 209 210 // Error should be Nil 211 assert.Nil(suite.T(), err) 212 213 // Correct refresh token should be returned 214 if assert.NotNil(suite.T(), refreshToken) { 215 // Fetch all refresh tokens 216 models.OauthRefreshTokenPreload(suite.db).Order("created_at").Find(&tokens) 217 218 // There should be 2 tokens now 219 assert.Equal(suite.T(), 2, len(tokens)) 220 221 // Correct refresh token object should be returned 222 assert.NotNil(suite.T(), refreshToken) 223 assert.Equal(suite.T(), tokens[1].Token, refreshToken.Token) 224 assert.Equal(suite.T(), "test_token2", refreshToken.Token) 225 assert.Equal(suite.T(), "test_token2", tokens[1].Token) 226 227 // Client ID should be set 228 assert.True(suite.T(), tokens[1].ClientID.Valid) 229 assert.Equal(suite.T(), string(suite.clients[0].ID), tokens[1].ClientID.String) 230 231 // User ID should be set 232 assert.True(suite.T(), tokens[1].UserID.Valid) 233 assert.Equal(suite.T(), string(suite.users[0].ID), tokens[1].UserID.String) 234 } 235 } 236 237 func (suite *OauthTestSuite) TestGetOrCreateRefreshTokenDeletesExpired() { 238 var ( 239 refreshToken *models.OauthRefreshToken 240 err error 241 tokens []*models.OauthRefreshToken 242 ) 243 244 // Insert an expired client only test refresh token 245 err = suite.db.Create(&models.OauthRefreshToken{ 246 MyGormModel: models.MyGormModel{ 247 ID: uuid.New(), 248 CreatedAt: time.Now().UTC(), 249 }, 250 Token: "test_token", 251 ExpiresAt: time.Now().UTC().Add(-10 * time.Second), 252 Client: suite.clients[0], 253 }).Error 254 assert.NoError(suite.T(), err, "Inserting test data failed") 255 256 // Since the current client only token is expired, 257 // this should delete it and create and return a new one 258 refreshToken, err = suite.service.GetOrCreateRefreshToken( 259 suite.clients[0], // client 260 nil, // user 261 3600, // expires in 262 "read_write", // scope 263 ) 264 265 // Error should be nil 266 if assert.Nil(suite.T(), err) { 267 // Fetch all refresh tokens 268 models.OauthRefreshTokenPreload(suite.db.Unscoped()).Order("created_at").Find(&tokens) 269 270 // There should be just one token right now 271 assert.Equal(suite.T(), 1, len(tokens)) 272 273 // Correct refresh token object should be returned 274 assert.NotNil(suite.T(), refreshToken) 275 assert.Equal(suite.T(), tokens[0].Token, refreshToken.Token) 276 assert.NotEqual(suite.T(), "test_token", refreshToken.Token) 277 assert.NotEqual(suite.T(), "test_token", tokens[0].Token) 278 279 // Client ID should be set 280 assert.True(suite.T(), tokens[0].ClientID.Valid) 281 assert.Equal(suite.T(), string(suite.clients[0].ID), tokens[0].ClientID.String) 282 283 // User ID should be nil 284 assert.False(suite.T(), tokens[0].UserID.Valid) 285 } 286 287 // Insert an expired user specific test refresh token 288 err = suite.db.Create(&models.OauthRefreshToken{ 289 MyGormModel: models.MyGormModel{ 290 ID: uuid.New(), 291 CreatedAt: time.Now().UTC(), 292 }, 293 Token: "test_token", 294 ExpiresAt: time.Now().UTC().Add(-10 * time.Second), 295 Client: suite.clients[0], 296 User: suite.users[0], 297 }).Error 298 assert.NoError(suite.T(), err, "Inserting test data failed") 299 300 // Since the current user specific token is expired, 301 // this should delete it and create and return a new one 302 refreshToken, err = suite.service.GetOrCreateRefreshToken( 303 suite.clients[0], // client 304 suite.users[0], // user 305 3600, // expires in 306 "read_write", // scope 307 ) 308 309 // Error should be nil 310 if assert.Nil(suite.T(), err) { 311 // Fetch all refresh tokens 312 models.OauthRefreshTokenPreload(suite.db.Unscoped()).Order("created_at").Find(&tokens) 313 314 // There should be 2 tokens now 315 assert.Equal(suite.T(), 2, len(tokens)) 316 317 // Correct refresh token object should be returned 318 assert.NotNil(suite.T(), refreshToken) 319 assert.Equal(suite.T(), tokens[1].Token, refreshToken.Token) 320 assert.NotEqual(suite.T(), "test_token", refreshToken.Token) 321 assert.NotEqual(suite.T(), "test_token", tokens[1].Token) 322 323 // Client ID should be set 324 assert.True(suite.T(), tokens[1].ClientID.Valid) 325 assert.Equal(suite.T(), string(suite.clients[0].ID), tokens[1].ClientID.String) 326 327 // User ID should be set 328 assert.True(suite.T(), tokens[1].UserID.Valid) 329 assert.Equal(suite.T(), string(suite.users[0].ID), tokens[1].UserID.String) 330 } 331 } 332 333 func (suite *OauthTestSuite) TestGetValidRefreshToken() { 334 var ( 335 refreshToken *models.OauthRefreshToken 336 err error 337 ) 338 339 // Insert some test refresh tokens 340 testRefreshTokens := []*models.OauthRefreshToken{ 341 // Expired test refresh token 342 { 343 MyGormModel: models.MyGormModel{ 344 ID: uuid.New(), 345 CreatedAt: time.Now().UTC(), 346 }, 347 Token: "test_expired_token", 348 ExpiresAt: time.Now().UTC().Add(-10 * time.Second), 349 Client: suite.clients[0], 350 User: suite.users[0], 351 }, 352 // Refresh token 353 { 354 MyGormModel: models.MyGormModel{ 355 ID: uuid.New(), 356 CreatedAt: time.Now().UTC(), 357 }, 358 Token: "test_token", 359 ExpiresAt: time.Now().UTC().Add(+10 * time.Second), 360 Client: suite.clients[0], 361 User: suite.users[0], 362 }, 363 } 364 for _, testRefreshToken := range testRefreshTokens { 365 err := suite.db.Create(testRefreshToken).Error 366 assert.NoError(suite.T(), err, "Inserting test data failed") 367 } 368 369 // Test passing an empty token 370 refreshToken, err = suite.service.GetValidRefreshToken( 371 "", // refresh token 372 suite.clients[0], // client 373 ) 374 375 // Refresh token should be nil 376 assert.Nil(suite.T(), refreshToken) 377 378 // Correct error should be returned 379 if assert.NotNil(suite.T(), err) { 380 assert.Equal(suite.T(), oauth.ErrRefreshTokenNotFound, err) 381 } 382 383 // Test passing a bogus token 384 refreshToken, err = suite.service.GetValidRefreshToken( 385 "bogus", // refresh token 386 suite.clients[0], // client 387 ) 388 389 // Refresh token should be nil 390 assert.Nil(suite.T(), refreshToken) 391 392 // Correct error should be returned 393 if assert.NotNil(suite.T(), err) { 394 assert.Equal(suite.T(), oauth.ErrRefreshTokenNotFound, err) 395 } 396 397 // Test passing an expired token 398 refreshToken, err = suite.service.GetValidRefreshToken( 399 "test_expired_token", // refresh token 400 suite.clients[0], // client 401 ) 402 403 // Refresh token should be nil 404 assert.Nil(suite.T(), refreshToken) 405 406 // Correct error should be returned 407 if assert.NotNil(suite.T(), err) { 408 assert.Equal(suite.T(), oauth.ErrRefreshTokenExpired, err) 409 } 410 411 // Test passing a valid token 412 refreshToken, err = suite.service.GetValidRefreshToken( 413 "test_token", // refresh token 414 suite.clients[0], // client 415 ) 416 417 // Error should be nil 418 assert.Nil(suite.T(), err) 419 420 // Correct refresh token object should be returned 421 assert.NotNil(suite.T(), refreshToken) 422 assert.Equal(suite.T(), "test_token", refreshToken.Token) 423 }