auth

Paddy 2014-11-02 Parent:03c9890f99c5 Child:cef5111af5c7

60:0cc717e02c9b Go to Latest

auth/http.go

Fill out redirects. Actually redirect the user when obtaining a grant. Check if the redirect_uri being passed when obtaining a grant is _actually a URL_. If it's not, return the right error. Add a test for a redirect_uri that isn't a valid URL.

History
     1.1 --- a/http.go	Sun Oct 26 03:31:24 2014 -0400
     1.2 +++ b/http.go	Sun Nov 02 20:45:51 2014 -0500
     1.3 @@ -2,11 +2,16 @@
     1.4  
     1.5  import (
     1.6  	"net/http"
     1.7 +	"net/url"
     1.8 +	"time"
     1.9  
    1.10  	"code.secondbit.org/uuid"
    1.11  )
    1.12  
    1.13 -const getGrantTemplateName = "get_grant"
    1.14 +const (
    1.15 +	getGrantTemplateName   = "get_grant"
    1.16 +	defaultGrantExpiration = 600 // default to ten minute grant expirations
    1.17 +)
    1.18  
    1.19  // GetGrantHandler presents and processes the page for asking a user to grant access
    1.20  // to their data. See RFC 6749, Section 4.1.
    1.21 @@ -90,18 +95,51 @@
    1.22  		})
    1.23  		return
    1.24  	}
    1.25 +	scope := r.URL.Query().Get("scope")
    1.26 +	state := r.URL.Query().Get("state")
    1.27 +	redirectURL, err := url.Parse(redirectURI)
    1.28 +	if err != nil {
    1.29 +		w.WriteHeader(http.StatusBadRequest)
    1.30 +		context.Render(w, getGrantTemplateName, map[string]interface{}{
    1.31 +			"error": "The redirect_uri specified is not valid.",
    1.32 +		})
    1.33 +		return
    1.34 +	}
    1.35  	if r.URL.Query().Get("response_type") != "code" {
    1.36 -		// TODO: redirect error
    1.37 +		redirectURL.Query().Add("error", "invalid_request")
    1.38 +		redirectURL.Query().Add("state", state)
    1.39 +		http.Redirect(w, r, redirectURL.String(), http.StatusFound)
    1.40 +		return
    1.41  	}
    1.42 -	//scope := r.URL.Query().Get("scope")
    1.43 -	//state := r.URL.Query().Get("state")
    1.44  	if r.Method == "POST" {
    1.45  		// TODO: CSRF protection
    1.46  		if r.PostFormValue("grant") == "approved" {
    1.47 -			// TODO: redirect
    1.48 -		} else {
    1.49 -			// TODO: redirect error
    1.50 +			code := uuid.NewID().String()
    1.51 +			grant := Grant{
    1.52 +				Code:        code,
    1.53 +				Created:     time.Now(),
    1.54 +				ExpiresIn:   defaultGrantExpiration,
    1.55 +				ClientID:    clientID,
    1.56 +				Scope:       scope,
    1.57 +				RedirectURI: redirectURI,
    1.58 +				State:       state,
    1.59 +			}
    1.60 +			err := context.SaveGrant(grant)
    1.61 +			if err != nil {
    1.62 +				redirectURL.Query().Add("error", "server_error")
    1.63 +				redirectURL.Query().Add("state", state)
    1.64 +				http.Redirect(w, r, redirectURL.String(), http.StatusFound)
    1.65 +				return
    1.66 +			}
    1.67 +			redirectURL.Query().Add("code", code)
    1.68 +			redirectURL.Query().Add("state", state)
    1.69 +			http.Redirect(w, r, redirectURL.String(), http.StatusFound)
    1.70 +			return
    1.71  		}
    1.72 +		redirectURL.Query().Add("error", "access_denied")
    1.73 +		redirectURL.Query().Add("state", state)
    1.74 +		http.Redirect(w, r, redirectURL.String(), http.StatusFound)
    1.75 +		return
    1.76  	}
    1.77  	w.WriteHeader(http.StatusOK)
    1.78  	context.Render(w, getGrantTemplateName, map[string]interface{}{