auth
167:0ff23f3a4ede Browse Files
Implement an endpoint for token information. Implement an endpoint that allows us to look up information on a token. We strip the refresh token before the response is sent to avoid leaking the response token.
authd/server.go profile.go request.go token.go
1.1 --- a/authd/server.go Mon May 11 21:25:18 2015 -0400 1.2 +++ b/authd/server.go Tue May 12 21:14:21 2015 -0400 1.3 @@ -55,6 +55,7 @@ 1.4 auth.RegisterSessionHandlers(router, context) 1.5 auth.RegisterProfileHandlers(router, context) 1.6 auth.RegisterClientHandlers(router, context) 1.7 + auth.RegisterTokenHandlers(router, context) 1.8 http.Handle("/", router) 1.9 log.Fatal(http.ListenAndServe(":8080", nil)) 1.10 }
2.1 --- a/profile.go Mon May 11 21:25:18 2015 -0400 2.2 +++ b/profile.go Tue May 12 21:14:21 2015 -0400 2.3 @@ -463,6 +463,7 @@ 2.4 r.Handle("/profiles/{id}", wrap(context, GetProfileHandler)).Methods("GET", "OPTIONS") 2.5 r.Handle("/profiles/{id}", wrap(context, UpdateProfileHandler)).Methods("PATCH", "OPTIONS") 2.6 r.Handle("/profiles/{id}", wrap(context, DeleteProfileHandler)).Methods("DELETE", "OPTIONS") 2.7 + // TODO: r.Handle("/profiles/{id}/tokens", wrap(context, ListTokensHandler)).Methods("GET", "OPTIONS") 2.8 // BUG(paddy): We need to implement a handler that will add a login to a profile. 2.9 // BUG(paddy): We need to implement a handler that will remove a login from a profile. What happens to sessions created with that login? 2.10 // BUG(paddy): We need to implement a handler that will list the logins attached to a profile.
3.1 --- a/request.go Mon May 11 21:25:18 2015 -0400 3.2 +++ b/request.go Tue May 12 21:14:21 2015 -0400 3.3 @@ -34,6 +34,7 @@ 3.4 Clients []Client `json:"clients,omitempty"` 3.5 Endpoints []Endpoint `json:"endpoints,omitempty"` 3.6 Sessions []Session `json:"sessions,omitempty"` 3.7 + Tokens []Token `json:"tokens,omitempty"` 3.8 } 3.9 3.10 type requestError struct {
4.1 --- a/token.go Mon May 11 21:25:18 2015 -0400 4.2 +++ b/token.go Tue May 12 21:14:21 2015 -0400 4.3 @@ -3,6 +3,7 @@ 4.4 import ( 4.5 "encoding/json" 4.6 "errors" 4.7 + "github.com/gorilla/mux" 4.8 "log" 4.9 "net/http" 4.10 "time" 4.11 @@ -37,17 +38,17 @@ 4.12 // Token represents an access and/or refresh token that the Client can use to access user data 4.13 // or obtain a new access token. 4.14 type Token struct { 4.15 - AccessToken string 4.16 - RefreshToken string 4.17 - Created time.Time 4.18 - CreatedFrom string 4.19 - ExpiresIn int32 4.20 - TokenType string 4.21 - Scopes Scopes 4.22 - ProfileID uuid.ID 4.23 - ClientID uuid.ID 4.24 - Revoked bool 4.25 - RefreshRevoked bool 4.26 + AccessToken string `json:"access_token"` 4.27 + RefreshToken string `json:"refresh_token,omitempty"` 4.28 + Created time.Time `json:"-"` 4.29 + CreatedFrom string `json:"created_from"` 4.30 + ExpiresIn int32 `json:"expires_in"` 4.31 + TokenType string `json:"token_type"` 4.32 + Scopes Scopes `json:"-"` 4.33 + ProfileID uuid.ID `json:"profile_id"` 4.34 + ClientID uuid.ID `json:"client_id"` 4.35 + Revoked bool `json:"revoked,omitempty"` 4.36 + RefreshRevoked bool `json:"refresh_revoked,omitempty"` 4.37 } 4.38 4.39 type tokenStore interface { 4.40 @@ -223,5 +224,44 @@ 4.41 return "refresh_token:" + r.PostFormValue("refresh_token") 4.42 } 4.43 4.44 -// BUG(paddy): We need to implement a handler for revoking a token. 4.45 -// BUG(paddy): We need to implement a handler for listing active tokens. 4.46 +func RegisterTokenHandlers(r *mux.Router, context Context) { 4.47 + r.Handle("/tokens/{id}", wrap(context, GetTokenInfoHandler)).Methods("GET", "OPTIONS") 4.48 + r.Handle("/tokens/{id}", wrap(context, RevokeTokenHandler)).Methods("DELETE", "OPTIONS") 4.49 +} 4.50 + 4.51 +// GetTokenInfoHandler is an HTTP handler for retrieving information about a token. 4.52 +func GetTokenInfoHandler(w http.ResponseWriter, r *http.Request, context Context) { 4.53 + errors := []requestError{} 4.54 + vars := mux.Vars(r) 4.55 + tokenID := vars["id"] 4.56 + if tokenID == "" { 4.57 + errors = append(errors, requestError{Slug: requestErrMissing, Param: "id"}) 4.58 + encode(w, r, http.StatusBadRequest, response{Errors: errors}) 4.59 + return 4.60 + } 4.61 + token, err := context.GetToken(tokenID, false) 4.62 + if err != nil { 4.63 + if err == ErrTokenNotFound { 4.64 + errors = append(errors, requestError{Slug: requestErrNotFound, Param: "id"}) 4.65 + encode(w, r, http.StatusNotFound, response{Errors: errors}) 4.66 + return 4.67 + } 4.68 + encode(w, r, http.StatusInternalServerError, actOfGodResponse) 4.69 + return 4.70 + } 4.71 + token.RefreshToken = "" 4.72 + expired := int64(time.Now().Sub(token.Created) / time.Second) 4.73 + if expired > int64(token.ExpiresIn) { 4.74 + token.ExpiresIn = 0 4.75 + } else { 4.76 + token.ExpiresIn = token.ExpiresIn - int32(expired) 4.77 + } 4.78 + encode(w, r, http.StatusOK, response{Tokens: []Token{token}}) 4.79 + return 4.80 +} 4.81 + 4.82 +// RevokeTokenHandler is an HTTP handler for revoking a Token prematurely. 4.83 +func RevokeTokenHandler(w http.ResponseWriter, r *http.Request, context Context) { 4.84 + //errors := []requestError{} 4.85 + // TODO 4.86 +}