// GetOrCreateRefreshToken retrieves an existing refresh token, if expired, // the token gets deleted and new refresh token is created func (s *Service) GetOrCreateRefreshToken(client *Client, user *User, scope string) (*RefreshToken, error) { // Try to fetch an existing refresh token first refreshToken := new(RefreshToken) found := !s.db.Where(RefreshToken{ ClientID: util.IntOrNull(int64(client.ID)), UserID: util.IntOrNull(int64(user.ID)), }).Preload("Client").Preload("User").First(refreshToken).RecordNotFound() // Check if the token is expired, if found var expired bool if found { expired = time.Now().After(refreshToken.ExpiresAt) } // If the refresh token has expired, delete it if expired { s.db.Unscoped().Delete(refreshToken) } // Create a new refresh token if it expired or was not found if expired || !found { refreshToken = newRefreshToken( s.cnf.Oauth.RefreshTokenLifetime, // expires in client, // client user, // user scope, // scope ) if err := s.db.Create(refreshToken).Error; err != nil { return nil, err } } return refreshToken, nil }
// newRefreshToken creates new RefreshToken instance func newRefreshToken(expiresIn int, client *Client, user *User, scope string) *RefreshToken { clientID := util.IntOrNull(int64(client.ID)) userID := util.IntOrNull(int64(user.ID)) refreshToken := &RefreshToken{ Token: uuid.New(), ExpiresAt: time.Now().Add(time.Duration(expiresIn) * time.Second), Scope: scope, ClientID: clientID, UserID: userID, } if clientID.Valid { refreshToken.Client = client } if userID.Valid { refreshToken.User = user } return refreshToken }
// newAuthorizationCode creates new AuthorizationCode instance func newAuthorizationCode(expiresIn int, client *Client, user *User, redirectURI, scope string) *AuthorizationCode { clientID := util.IntOrNull(int64(client.ID)) userID := util.IntOrNull(int64(user.ID)) authorizationCode := &AuthorizationCode{ Code: uuid.New(), ExpiresAt: time.Now().Add(time.Duration(expiresIn) * time.Second), RedirectURI: util.StringOrNull(redirectURI), Scope: scope, ClientID: clientID, UserID: userID, } if clientID.Valid { authorizationCode.Client = client } if userID.Valid { authorizationCode.User = user } return authorizationCode }
// getValidAuthorizationCode returns a valid non expired authorization code func (s *Service) getValidAuthorizationCode(code string, client *Client) (*AuthorizationCode, error) { // Fetch the auth code from the database authorizationCode := new(AuthorizationCode) if s.db.Where(AuthorizationCode{ Code: code, ClientID: util.IntOrNull(client.ID), }).Preload("Client").Preload("User").First(authorizationCode).RecordNotFound() { return nil, errors.New("Authorization code not found") } // Check the authorization code hasn't expired if time.Now().After(authorizationCode.ExpiresAt) { return nil, errors.New("Authorization code expired") } return authorizationCode, nil }
// GetValidRefreshToken returns a valid non expired refresh token func (s *Service) GetValidRefreshToken(token string, client *Client) (*RefreshToken, error) { // Fetch the refresh token from the database refreshToken := new(RefreshToken) notFound := s.db.Where(RefreshToken{ ClientID: util.IntOrNull(int64(client.ID)), }).Where("token = ?", token).Preload("Client").Preload("User"). First(refreshToken).RecordNotFound() // Not found if notFound { return nil, errRefreshTokenNotFound } // Check the refresh token hasn't expired if time.Now().After(refreshToken.ExpiresAt) { return nil, errRefreshTokenExpired } return refreshToken, nil }
// getValidAuthorizationCode returns a valid non expired authorization code func (s *Service) getValidAuthorizationCode(code string, client *Client) (*AuthorizationCode, error) { // Fetch the auth code from the database authorizationCode := new(AuthorizationCode) notFound := s.db.Where(AuthorizationCode{ ClientID: util.IntOrNull(int64(client.ID)), }).Where("code = ?", code).Preload("Client").Preload("User"). First(authorizationCode).RecordNotFound() // Not found if notFound { return nil, errAuthorizationCodeNotFound } // Check the authorization code hasn't expired if time.Now().After(authorizationCode.ExpiresAt) { return nil, errAuthorizationCodeExpired } return authorizationCode, nil }
// deleteExpiredAccessTokens deletes expired access tokens func (s *Service) deleteExpiredAccessTokens(client *Client, user *User) { s.db.Where(AccessToken{ ClientID: util.IntOrNull(client.ID), UserID: util.IntOrNull(user.ID), }).Where("expires_at <= ?", time.Now()).Delete(new(AccessToken)) }