github.com/resonatecoop/id@v1.1.0-43/oauth/access_token_test.go (about)

     1  package oauth_test
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/google/uuid"
     8  	"github.com/resonatecoop/id/util"
     9  
    10  	"github.com/resonatecoop/user-api/model"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func (suite *OauthTestSuite) TestGrantAccessToken() {
    15  	var (
    16  		ctx          context.Context
    17  		accessToken  *model.AccessToken
    18  		err          error
    19  		accessTokens []model.AccessToken
    20  	)
    21  
    22  	ctx = context.Background()
    23  
    24  	// Grant a client only access token
    25  	accessToken, err = suite.service.GrantAccessToken(
    26  		suite.clients[0],       // client
    27  		nil,                    // user
    28  		3600,                   // expires in
    29  		"scope doesn't matter", // scope
    30  	)
    31  
    32  	// Error should be Nil
    33  	assert.Nil(suite.T(), err)
    34  
    35  	// Correct access token object should be returned
    36  	if assert.NotNil(suite.T(), accessToken) {
    37  		// Fetch all access tokens
    38  		//	model.AccessTokenPreload(suite.db).Order("created_at").Find(&tokens)
    39  
    40  		err = suite.db.NewSelect().Model(&accessTokens).
    41  			Column("access_token.*").
    42  			Relation("Client").
    43  			OrderExpr("created_at").
    44  			Scan(ctx)
    45  
    46  		// There should be no error
    47  		assert.Nil(suite.T(), err)
    48  
    49  		// There should be just one right now
    50  		assert.Equal(suite.T(), 1, len(accessTokens))
    51  
    52  		// And the token should match the one returned by the grant method
    53  		assert.Equal(suite.T(), accessTokens[0].Token, accessToken.Token)
    54  
    55  		// Client id should be set
    56  		assert.True(suite.T(), util.IsValidUUID(accessTokens[0].ClientID.String()))
    57  		assert.Equal(suite.T(), suite.clients[0].ID.String(), accessTokens[0].ClientID.String())
    58  
    59  		// User id should be nil
    60  		assert.Equal(suite.T(), accessTokens[0].UserID, uuid.Nil)
    61  	}
    62  
    63  	// Grant a user specific access token
    64  	accessToken, err = suite.service.GrantAccessToken(
    65  		suite.clients[0],       // client
    66  		suite.users[0],         // user
    67  		3600,                   // expires in
    68  		"scope doesn't matter", // scope
    69  	)
    70  
    71  	// Error should be Nil
    72  	assert.Nil(suite.T(), err)
    73  
    74  	// Correct access token object should be returned
    75  	if assert.NotNil(suite.T(), accessToken) {
    76  		// Fetch all access tokens
    77  
    78  		rows, err := suite.db.QueryContext(ctx, "SELECT * FROM access_tokens ORDER BY created_at")
    79  		if err != nil {
    80  			panic(err)
    81  		}
    82  		err = suite.db.ScanRows(ctx, rows, &accessTokens)
    83  
    84  		// There should be no error
    85  		assert.Nil(suite.T(), err)
    86  
    87  		// There should be 2 tokens now
    88  		assert.Equal(suite.T(), 2, len(accessTokens))
    89  
    90  		// And the second token should match the one returned by the grant method
    91  		assert.Equal(suite.T(), accessTokens[1].Token, accessToken.Token)
    92  
    93  		// Client id should be set
    94  		assert.True(suite.T(), util.IsValidUUID(accessTokens[1].ClientID.String()))
    95  		assert.Equal(suite.T(), suite.clients[0].ID.String(), accessTokens[1].ClientID.String())
    96  
    97  		// User id should be set
    98  		assert.True(suite.T(), util.IsValidUUID(accessTokens[1].UserID.String()))
    99  		assert.Equal(suite.T(), suite.users[0].ID.String(), accessTokens[1].UserID.String())
   100  	}
   101  }
   102  
   103  func (suite *OauthTestSuite) TestGrantAccessTokenDeletesExpiredTokens() {
   104  	var (
   105  		ctx              context.Context
   106  		accessToken      *model.AccessToken
   107  		testAccessTokens = []*model.AccessToken{
   108  			// Expired access token with a user
   109  			{
   110  				Token:     "test_token_1",
   111  				ExpiresAt: time.Now().UTC().Add(-10 * time.Second),
   112  				ClientID:  suite.clients[0].ID,
   113  				UserID:    suite.users[0].ID,
   114  			},
   115  			// Expired access token without a user
   116  			{
   117  				Token:     "test_token_2",
   118  				ExpiresAt: time.Now().UTC().Add(-10 * time.Second),
   119  				ClientID:  suite.clients[0].ID,
   120  			},
   121  			// Access token with a user
   122  			{
   123  				Token:     "test_token_3",
   124  				ExpiresAt: time.Now().UTC().Add(+10 * time.Second),
   125  				ClientID:  suite.clients[0].ID,
   126  				UserID:    suite.users[0].ID,
   127  			},
   128  			// Access token without a user
   129  			{
   130  				Token:     "test_token_4",
   131  				ExpiresAt: time.Now().UTC().Add(+10 * time.Second),
   132  				ClientID:  suite.clients[0].ID,
   133  			},
   134  		}
   135  		err            error
   136  		existingTokens []string
   137  	)
   138  	ctx = context.Background()
   139  	// Insert test access tokens
   140  	for _, testAccessToken := range testAccessTokens {
   141  		_, err = suite.db.NewInsert().
   142  			Model(testAccessToken).
   143  			Exec(ctx)
   144  		assert.NoError(suite.T(), err, "Inserting test data failed")
   145  	}
   146  
   147  	// This should only delete test_token_1
   148  	_, err = suite.service.GrantAccessToken(
   149  		suite.clients[0],       // client
   150  		suite.users[0],         // user
   151  		3600,                   // expires in
   152  		"scope doesn't matter", // scope
   153  	)
   154  	assert.NoError(suite.T(), err)
   155  
   156  	accessToken = new(model.AccessToken)
   157  	// Check the test_token_1 was deleted
   158  	err = suite.db.NewSelect().
   159  		Model(accessToken).
   160  		Where("token = ?", "test_token_1").
   161  		Limit(1).
   162  		Scan(ctx)
   163  
   164  	assert.NotNil(suite.T(), err)
   165  
   166  	// Check the other two tokens are still around
   167  	existingTokens = []string{
   168  		"test_token_2",
   169  		//"test_token_3",
   170  		"test_token_4",
   171  	}
   172  
   173  	for _, token := range existingTokens {
   174  
   175  		err = suite.db.NewSelect().
   176  			Model(accessToken).
   177  			Where("token = ?", token).
   178  			Limit(1).
   179  			Scan(ctx)
   180  
   181  		assert.Nil(suite.T(), err)
   182  	}
   183  
   184  	// This should only delete test_token_2
   185  	_, err = suite.service.GrantAccessToken(
   186  		suite.clients[0],       // client
   187  		nil,                    // user
   188  		3600,                   // expires in
   189  		"scope doesn't matter", // scope
   190  	)
   191  	assert.NoError(suite.T(), err)
   192  
   193  	// Check the test_token_2 was deleted
   194  	err = suite.db.NewSelect().
   195  		Model(accessToken).
   196  		Where("token = ?", "test_token_2").
   197  		Limit(1).
   198  		Scan(ctx)
   199  
   200  	assert.NotNil(suite.T(), err)
   201  
   202  	// Check that last two tokens are still around
   203  	existingTokens = []string{
   204  		"test_token_3",
   205  		"test_token_4",
   206  	}
   207  	for _, token := range existingTokens {
   208  		err = suite.db.NewSelect().
   209  			Model(accessToken).
   210  			Where("token = ?", token).
   211  			Limit(1).
   212  			Scan(ctx)
   213  
   214  		assert.Nil(suite.T(), err)
   215  	}
   216  }