github.com/wanliu/go-oauth2-server@v0.0.0-20180817021415-f928fa1580df/oauth/introspect.go (about) 1 package oauth 2 3 import ( 4 "errors" 5 "net/http" 6 7 "github.com/wanliu/go-oauth2-server/models" 8 "github.com/wanliu/go-oauth2-server/oauth/tokentypes" 9 ) 10 11 const ( 12 // AccessTokenHint ... 13 AccessTokenHint = "access_token" 14 // RefreshTokenHint ... 15 RefreshTokenHint = "refresh_token" 16 ) 17 18 var ( 19 // ErrTokenMissing ... 20 ErrTokenMissing = errors.New("Token missing") 21 // ErrTokenHintInvalid ... 22 ErrTokenHintInvalid = errors.New("Invalid token hint") 23 ) 24 25 func (s *Service) introspectToken(r *http.Request, client *models.OauthClient) (*IntrospectResponse, error) { 26 // Parse the form so r.Form becomes available 27 if err := r.ParseForm(); err != nil { 28 return nil, err 29 } 30 31 // Get token from the query 32 token := r.Form.Get("token") 33 if token == "" { 34 return nil, ErrTokenMissing 35 } 36 37 // Get token type hint from the query 38 tokenTypeHint := r.Form.Get("token_type_hint") 39 40 // Default to access token hint 41 if tokenTypeHint == "" { 42 tokenTypeHint = AccessTokenHint 43 } 44 45 switch tokenTypeHint { 46 case AccessTokenHint: 47 accessToken, err := s.Authenticate(token) 48 if err != nil { 49 return nil, err 50 } 51 return s.NewIntrospectResponseFromAccessToken(accessToken) 52 case RefreshTokenHint: 53 refreshToken, err := s.GetValidRefreshToken(token, client) 54 if err != nil { 55 return nil, err 56 } 57 return s.NewIntrospectResponseFromRefreshToken(refreshToken) 58 default: 59 return nil, ErrTokenHintInvalid 60 } 61 } 62 63 // NewIntrospectResponseFromAccessToken ... 64 func (s *Service) NewIntrospectResponseFromAccessToken(accessToken *models.OauthAccessToken) (*IntrospectResponse, error) { 65 var introspectResponse = &IntrospectResponse{ 66 Active: true, 67 Scope: accessToken.Scope, 68 TokenType: tokentypes.Bearer, 69 ExpiresAt: int(accessToken.ExpiresAt.Unix()), 70 } 71 72 if accessToken.ClientID.Valid { 73 client := new(models.OauthClient) 74 notFound := s.db.Select("key").First(client, accessToken.ClientID.String). 75 RecordNotFound() 76 if notFound { 77 return nil, ErrClientNotFound 78 } 79 introspectResponse.ClientID = client.Key 80 } 81 82 if accessToken.UserID.Valid { 83 user := new(models.OauthUser) 84 notFound := s.db.First(user, "id = ?", accessToken.UserID.String). 85 RecordNotFound() 86 if notFound { 87 return nil, ErrUserNotFound 88 } 89 introspectResponse.Username = user.Username 90 userResp := UserResponse{ 91 ID: user.ID, 92 NickName: user.NickName.String, 93 Avatar: user.Avatar(), 94 } 95 96 introspectResponse.User = &userResp 97 } 98 99 if accessToken.ClientID.Valid && accessToken.UserID.Valid { 100 refreshToken := new(models.OauthRefreshToken) 101 notFound := s.db.First(refreshToken, "user_id = ? and client_id = ?", accessToken.UserID.String, accessToken.ClientID.String). 102 RecordNotFound() 103 if notFound { 104 return nil, ErrRefreshTokenNotFound 105 } 106 107 introspectResponse.RefreshToken = refreshToken.Token 108 } 109 110 return introspectResponse, nil 111 } 112 113 // NewIntrospectResponseFromRefreshToken ... 114 func (s *Service) NewIntrospectResponseFromRefreshToken(refreshToken *models.OauthRefreshToken) (*IntrospectResponse, error) { 115 var introspectResponse = &IntrospectResponse{ 116 Active: true, 117 Scope: refreshToken.Scope, 118 TokenType: tokentypes.Bearer, 119 ExpiresAt: int(refreshToken.ExpiresAt.Unix()), 120 } 121 122 if refreshToken.ClientID.Valid { 123 client := new(models.OauthClient) 124 notFound := s.db.Select("key").First(client, refreshToken.ClientID.String). 125 RecordNotFound() 126 if notFound { 127 return nil, ErrClientNotFound 128 } 129 introspectResponse.ClientID = client.Key 130 } 131 132 if refreshToken.UserID.Valid { 133 user := new(models.OauthUser) 134 notFound := s.db.Select("username").First(user, refreshToken.UserID.String). 135 RecordNotFound() 136 if notFound { 137 return nil, ErrUserNotFound 138 } 139 introspectResponse.Username = user.Username 140 } 141 142 return introspectResponse, nil 143 }