auth

Paddy 2014-11-02 Parent:c29c7df35905 Child:55d5107e8805

65:f97ca45d5657 Browse Files

Fix bug with response_type redirect, add tests. Test that we redirect with an error when an invalid response_type is supplied. Fix a bug that would not add any of our parameters to the redirect URL.

http.go http_test.go

     1.1 --- a/http.go	Sun Nov 02 22:28:49 2014 -0500
     1.2 +++ b/http.go	Sun Nov 02 23:01:02 2014 -0500
     1.3 @@ -107,8 +107,10 @@
     1.4  	scope := r.URL.Query().Get("scope")
     1.5  	state := r.URL.Query().Get("state")
     1.6  	if r.URL.Query().Get("response_type") != "code" {
     1.7 -		redirectURL.Query().Add("error", "invalid_request")
     1.8 -		redirectURL.Query().Add("state", state)
     1.9 +		q := redirectURL.Query()
    1.10 +		q.Add("error", "invalid_request")
    1.11 +		q.Add("state", state)
    1.12 +		redirectURL.RawQuery = q.Encode()
    1.13  		http.Redirect(w, r, redirectURL.String(), http.StatusFound)
    1.14  		return
    1.15  	}
     2.1 --- a/http_test.go	Sun Nov 02 22:28:49 2014 -0500
     2.2 +++ b/http_test.go	Sun Nov 02 23:01:02 2014 -0500
     2.3 @@ -17,6 +17,12 @@
     2.4  	uriSet
     2.5  )
     2.6  
     2.7 +func stripParam(param string, u *url.URL) {
     2.8 +	q := u.Query()
     2.9 +	q.Del(param)
    2.10 +	u.RawQuery = q.Encode()
    2.11 +}
    2.12 +
    2.13  func TestGetGrantCodeSuccess(t *testing.T) {
    2.14  	t.Parallel()
    2.15  	store := NewMemstore()
    2.16 @@ -235,3 +241,96 @@
    2.17  		t.Errorf(`Expected output to be "%s", got "%s" instead.`, "The redirect_uri specified is not valid.", w.Body.String())
    2.18  	}
    2.19  }
    2.20 +
    2.21 +func TestGetGrantCodeInvalidResponseType(t *testing.T) {
    2.22 +	t.Parallel()
    2.23 +	store := NewMemstore()
    2.24 +	testContext := Context{
    2.25 +		template: template.Must(template.New(getGrantTemplateName).Parse("{{ .error }}")),
    2.26 +		clients:  store,
    2.27 +		grants:   store,
    2.28 +		profiles: store,
    2.29 +		tokens:   store,
    2.30 +	}
    2.31 +	client := Client{
    2.32 +		ID:      uuid.NewID(),
    2.33 +		Secret:  "super secret!",
    2.34 +		OwnerID: uuid.NewID(),
    2.35 +		Name:    "My test client",
    2.36 +		Logo:    "https://secondbit.org/logo.png",
    2.37 +		Website: "https://secondbit.org",
    2.38 +		Type:    "public",
    2.39 +	}
    2.40 +	uri, err := url.Parse("https://test.secondbit.org/redirect")
    2.41 +	if err != nil {
    2.42 +		t.Fatal("Can't parse URL:", err)
    2.43 +	}
    2.44 +	endpoint := Endpoint{
    2.45 +		ID:       uuid.NewID(),
    2.46 +		ClientID: client.ID,
    2.47 +		URI:      *uri,
    2.48 +		Added:    time.Now(),
    2.49 +	}
    2.50 +	err = testContext.SaveClient(client)
    2.51 +	if err != nil {
    2.52 +		t.Fatal("Can't store client:", err)
    2.53 +	}
    2.54 +	err = testContext.AddEndpoint(client.ID, endpoint)
    2.55 +	if err != nil {
    2.56 +		t.Fatal("Can't store endpoint:", err)
    2.57 +	}
    2.58 +	req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil)
    2.59 +	if err != nil {
    2.60 +		t.Fatal("Can't build request:", err)
    2.61 +	}
    2.62 +	params := url.Values{}
    2.63 +	params.Set("response_type", "totally not code")
    2.64 +	params.Set("client_id", client.ID.String())
    2.65 +	params.Set("redirect_uri", endpoint.URI.String())
    2.66 +	params.Set("scope", "testscope")
    2.67 +	params.Set("state", "my super secure state string")
    2.68 +	req.URL.RawQuery = params.Encode()
    2.69 +	w := httptest.NewRecorder()
    2.70 +	GetGrantHandler(w, req, testContext)
    2.71 +	if w.Code != http.StatusFound {
    2.72 +		t.Errorf("Expected status code to be %d, got %d", http.StatusFound, w.Code)
    2.73 +	}
    2.74 +	redirectedTo := w.Header().Get("Location")
    2.75 +	red, err := url.Parse(redirectedTo)
    2.76 +	if err != nil {
    2.77 +		t.Fatalf("Being redirected to a non-URL (%s) threw error: %s\n", redirectedTo, err)
    2.78 +	}
    2.79 +	if red.Query().Get("error") != "invalid_request" {
    2.80 +		t.Errorf(`Expected error param in redirect URL to be "%s", got "%s"`, "invalid_request", red.Query().Get("error"))
    2.81 +	}
    2.82 +	stripParam("error", red)
    2.83 +	if red.Query().Get("state") != params.Get("state") {
    2.84 +		t.Errorf(`Expected state param in redirect URL to be "%s", got "%s"`, params.Get("state"), red.Query().Get("state"))
    2.85 +	}
    2.86 +	stripParam("state", red)
    2.87 +	if red.String() != endpoint.URI.String() {
    2.88 +		t.Errorf(`Expected redirect URL to be "%s", got "%s"`, endpoint.URI.String(), red.String())
    2.89 +	}
    2.90 +	stripParam("response_type", req.URL)
    2.91 +	w = httptest.NewRecorder()
    2.92 +	GetGrantHandler(w, req, testContext)
    2.93 +	if w.Code != http.StatusFound {
    2.94 +		t.Errorf("Expected status code to be %d, got %d", http.StatusFound, w.Code)
    2.95 +	}
    2.96 +	redirectedTo = w.Header().Get("Location")
    2.97 +	red, err = url.Parse(redirectedTo)
    2.98 +	if err != nil {
    2.99 +		t.Fatalf("Being redirected to a non-URL (%s) threw error: %s\n", redirectedTo, err)
   2.100 +	}
   2.101 +	if red.Query().Get("error") != "invalid_request" {
   2.102 +		t.Errorf(`Expected error param in redirect URL to be "%s", got "%s"`, "invalid_request", red.Query().Get("error"))
   2.103 +	}
   2.104 +	stripParam("error", red)
   2.105 +	if red.Query().Get("state") != params.Get("state") {
   2.106 +		t.Errorf(`Expected state param in redirect URL to be "%s", got "%s"`, params.Get("state"), red.Query().Get("state"))
   2.107 +	}
   2.108 +	stripParam("state", red)
   2.109 +	if red.String() != endpoint.URI.String() {
   2.110 +		t.Errorf(`Expected redirect URL to be "%s", got "%s"`, endpoint.URI.String(), red.String())
   2.111 +	}
   2.112 +}