auth

Paddy 2015-05-12 Parent:c45b946abe78 Child:581c60f8dd23

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 +}