auth

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

167:0ff23f3a4ede Go to Latest

auth/token.go

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.

History
     1.1 --- a/token.go	Mon May 11 21:25:18 2015 -0400
     1.2 +++ b/token.go	Tue May 12 21:14:21 2015 -0400
     1.3 @@ -3,6 +3,7 @@
     1.4  import (
     1.5  	"encoding/json"
     1.6  	"errors"
     1.7 +	"github.com/gorilla/mux"
     1.8  	"log"
     1.9  	"net/http"
    1.10  	"time"
    1.11 @@ -37,17 +38,17 @@
    1.12  // Token represents an access and/or refresh token that the Client can use to access user data
    1.13  // or obtain a new access token.
    1.14  type Token struct {
    1.15 -	AccessToken    string
    1.16 -	RefreshToken   string
    1.17 -	Created        time.Time
    1.18 -	CreatedFrom    string
    1.19 -	ExpiresIn      int32
    1.20 -	TokenType      string
    1.21 -	Scopes         Scopes
    1.22 -	ProfileID      uuid.ID
    1.23 -	ClientID       uuid.ID
    1.24 -	Revoked        bool
    1.25 -	RefreshRevoked bool
    1.26 +	AccessToken    string    `json:"access_token"`
    1.27 +	RefreshToken   string    `json:"refresh_token,omitempty"`
    1.28 +	Created        time.Time `json:"-"`
    1.29 +	CreatedFrom    string    `json:"created_from"`
    1.30 +	ExpiresIn      int32     `json:"expires_in"`
    1.31 +	TokenType      string    `json:"token_type"`
    1.32 +	Scopes         Scopes    `json:"-"`
    1.33 +	ProfileID      uuid.ID   `json:"profile_id"`
    1.34 +	ClientID       uuid.ID   `json:"client_id"`
    1.35 +	Revoked        bool      `json:"revoked,omitempty"`
    1.36 +	RefreshRevoked bool      `json:"refresh_revoked,omitempty"`
    1.37  }
    1.38  
    1.39  type tokenStore interface {
    1.40 @@ -223,5 +224,44 @@
    1.41  	return "refresh_token:" + r.PostFormValue("refresh_token")
    1.42  }
    1.43  
    1.44 -// BUG(paddy): We need to implement a handler for revoking a token.
    1.45 -// BUG(paddy): We need to implement a handler for listing active tokens.
    1.46 +func RegisterTokenHandlers(r *mux.Router, context Context) {
    1.47 +	r.Handle("/tokens/{id}", wrap(context, GetTokenInfoHandler)).Methods("GET", "OPTIONS")
    1.48 +	r.Handle("/tokens/{id}", wrap(context, RevokeTokenHandler)).Methods("DELETE", "OPTIONS")
    1.49 +}
    1.50 +
    1.51 +// GetTokenInfoHandler is an HTTP handler for retrieving information about a token.
    1.52 +func GetTokenInfoHandler(w http.ResponseWriter, r *http.Request, context Context) {
    1.53 +	errors := []requestError{}
    1.54 +	vars := mux.Vars(r)
    1.55 +	tokenID := vars["id"]
    1.56 +	if tokenID == "" {
    1.57 +		errors = append(errors, requestError{Slug: requestErrMissing, Param: "id"})
    1.58 +		encode(w, r, http.StatusBadRequest, response{Errors: errors})
    1.59 +		return
    1.60 +	}
    1.61 +	token, err := context.GetToken(tokenID, false)
    1.62 +	if err != nil {
    1.63 +		if err == ErrTokenNotFound {
    1.64 +			errors = append(errors, requestError{Slug: requestErrNotFound, Param: "id"})
    1.65 +			encode(w, r, http.StatusNotFound, response{Errors: errors})
    1.66 +			return
    1.67 +		}
    1.68 +		encode(w, r, http.StatusInternalServerError, actOfGodResponse)
    1.69 +		return
    1.70 +	}
    1.71 +	token.RefreshToken = ""
    1.72 +	expired := int64(time.Now().Sub(token.Created) / time.Second)
    1.73 +	if expired > int64(token.ExpiresIn) {
    1.74 +		token.ExpiresIn = 0
    1.75 +	} else {
    1.76 +		token.ExpiresIn = token.ExpiresIn - int32(expired)
    1.77 +	}
    1.78 +	encode(w, r, http.StatusOK, response{Tokens: []Token{token}})
    1.79 +	return
    1.80 +}
    1.81 +
    1.82 +// RevokeTokenHandler is an HTTP handler for revoking a Token prematurely.
    1.83 +func RevokeTokenHandler(w http.ResponseWriter, r *http.Request, context Context) {
    1.84 +	//errors := []requestError{}
    1.85 +	// TODO
    1.86 +}