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

     1  package oauth
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  
     8  	"github.com/google/uuid"
     9  	"github.com/resonatecoop/id/session"
    10  	"github.com/resonatecoop/id/util"
    11  	"github.com/resonatecoop/user-api/model"
    12  )
    13  
    14  var (
    15  	// ErrAccessTokenNotFound ...
    16  	ErrAccessTokenNotFound = errors.New("Access token not found")
    17  	// ErrAccessTokenExpired ...
    18  	ErrAccessTokenExpired = errors.New("Access token expired")
    19  )
    20  
    21  // Authenticate checks the access token is valid
    22  func (s *Service) Authenticate(token string) (*model.AccessToken, error) {
    23  	// Fetch the access token from the database
    24  	ctx := context.Background()
    25  	accessToken := new(model.AccessToken)
    26  
    27  	err := s.db.NewSelect().
    28  		Model(accessToken).
    29  		Where("token = ?", token).
    30  		Limit(1).
    31  		Scan(ctx)
    32  
    33  	// Not found
    34  	if err != nil {
    35  		return nil, ErrAccessTokenNotFound
    36  	}
    37  
    38  	// Check the access token hasn't expired
    39  	if time.Now().UTC().After(accessToken.ExpiresAt) {
    40  		return nil, ErrAccessTokenExpired
    41  	}
    42  
    43  	// Extend refresh token expiration database
    44  
    45  	increasedExpiresAt := time.Now().Add(
    46  		time.Duration(s.cnf.Oauth.RefreshTokenLifetime) * time.Second,
    47  	)
    48  
    49  	//var res sql.Result
    50  
    51  	//	err = GetOrCreateRefreshToken
    52  
    53  	if util.IsValidUUID(accessToken.UserID.String()) && accessToken.UserID != uuid.Nil {
    54  		_, err = s.db.NewUpdate().
    55  			Model(new(model.RefreshToken)).
    56  			Set("expires_at = ?", increasedExpiresAt).
    57  			Set("updated_at = ?", time.Now().UTC()).
    58  			Where("client_id = ?", accessToken.ClientID.String()).
    59  			Where("user_id = ?", accessToken.UserID.String()).
    60  			Exec(ctx)
    61  	} else {
    62  		_, err = s.db.NewUpdate().
    63  			Model(new(model.RefreshToken)).
    64  			Set("expires_at = ?", increasedExpiresAt).
    65  			Set("updated_at = ?", time.Now().UTC()).
    66  			Where("client_id = ?", accessToken.ClientID.String()).
    67  			Where("user_id = uuid_nil()").
    68  			Exec(ctx)
    69  	}
    70  
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  
    75  	return accessToken, nil
    76  }
    77  
    78  // ClearUserTokens deletes the user's access and refresh tokens associated with this client id
    79  func (s *Service) ClearUserTokens(userSession *session.UserSession) {
    80  	// Clear all refresh tokens with user_id and client_id
    81  	ctx := context.Background()
    82  	refreshToken := new(model.RefreshToken)
    83  
    84  	err := s.db.NewSelect().
    85  		Model(refreshToken).
    86  		Where("token = ?", userSession.RefreshToken).
    87  		Limit(1).
    88  		Scan(ctx)
    89  
    90  	// Found
    91  	if err == nil {
    92  		_, err = s.db.NewDelete().
    93  			Model(refreshToken).
    94  			Where("client_id = ? AND user_id = ?", refreshToken.ClientID, refreshToken.UserID).
    95  			Exec(ctx)
    96  	}
    97  
    98  	// Clear all access tokens with user_id and client_id
    99  	accessToken := new(model.AccessToken)
   100  
   101  	err = s.db.NewSelect().
   102  		Model(accessToken).
   103  		Where("token = ?", userSession.AccessToken).
   104  		Limit(1).
   105  		Scan(ctx)
   106  
   107  	// Found
   108  	if err == nil {
   109  		_, err = s.db.NewDelete().
   110  			Model(accessToken).
   111  			Where("client_id = ? AND user_id = ?", accessToken.ClientID, accessToken.UserID).
   112  			Exec(ctx)
   113  	}
   114  }