github.com/wanliu/go-oauth2-server@v0.0.0-20180817021415-f928fa1580df/oauth/refresh_token.go (about) 1 package oauth 2 3 import ( 4 "errors" 5 "time" 6 7 "github.com/wanliu/go-oauth2-server/models" 8 "github.com/wanliu/go-oauth2-server/util" 9 ) 10 11 var ( 12 // ErrRefreshTokenNotFound ... 13 ErrRefreshTokenNotFound = errors.New("Refresh token not found") 14 // ErrRefreshTokenExpired ... 15 ErrRefreshTokenExpired = errors.New("Refresh token expired") 16 // ErrRequestedScopeCannotBeGreater ... 17 ErrRequestedScopeCannotBeGreater = errors.New("Requested scope cannot be greater") 18 ) 19 20 // GetOrCreateRefreshToken retrieves an existing refresh token, if expired, 21 // the token gets deleted and new refresh token is created 22 func (s *Service) GetOrCreateRefreshToken(client *models.OauthClient, user *models.OauthUser, expiresIn int, scope string) (*models.OauthRefreshToken, error) { 23 // Try to fetch an existing refresh token first 24 refreshToken := new(models.OauthRefreshToken) 25 query := models.OauthRefreshTokenPreload(s.db).Where("client_id = ?", client.ID) 26 if user != nil && len([]rune(user.ID)) > 0 { 27 query = query.Where("user_id = ?", user.ID) 28 } else { 29 query = query.Where("user_id IS NULL") 30 } 31 found := !query.First(refreshToken).RecordNotFound() 32 33 // Check if the token is expired, if found 34 var expired bool 35 if found { 36 expired = time.Now().UTC().After(refreshToken.ExpiresAt) 37 } 38 39 // If the refresh token has expired, delete it 40 if expired { 41 s.db.Unscoped().Delete(refreshToken) 42 } 43 44 // Create a new refresh token if it expired or was not found 45 if expired || !found { 46 refreshToken = models.NewOauthRefreshToken(client, user, expiresIn, scope) 47 if err := s.db.Create(refreshToken).Error; err != nil { 48 return nil, err 49 } 50 refreshToken.Client = client 51 refreshToken.User = user 52 } 53 54 return refreshToken, nil 55 } 56 57 // GetValidRefreshToken returns a valid non expired refresh token 58 func (s *Service) GetValidRefreshToken(token string, client *models.OauthClient) (*models.OauthRefreshToken, error) { 59 // Fetch the refresh token from the database 60 refreshToken := new(models.OauthRefreshToken) 61 notFound := models.OauthRefreshTokenPreload(s.db).Where("client_id = ?", client.ID). 62 Where("token = ?", token).First(refreshToken).RecordNotFound() 63 64 // Not found 65 if notFound { 66 return nil, ErrRefreshTokenNotFound 67 } 68 69 // Check the refresh token hasn't expired 70 if time.Now().UTC().After(refreshToken.ExpiresAt) { 71 return nil, ErrRefreshTokenExpired 72 } 73 74 return refreshToken, nil 75 } 76 77 // getRefreshTokenScope returns scope for a new refresh token 78 func (s *Service) getRefreshTokenScope(refreshToken *models.OauthRefreshToken, requestedScope string) (string, error) { 79 var ( 80 scope = refreshToken.Scope // default to the scope originally granted by the resource owner 81 err error 82 ) 83 84 // If the scope is specified in the request, get the scope string 85 if requestedScope != "" { 86 scope, err = s.GetScope(requestedScope) 87 if err != nil { 88 return "", err 89 } 90 } 91 92 // Requested scope CANNOT include any scope not originally granted 93 if !util.SpaceDelimitedStringNotGreater(scope, refreshToken.Scope) { 94 return "", ErrRequestedScopeCannotBeGreater 95 } 96 97 return scope, nil 98 }