github.com/jxgolibs/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  }