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