auth
auth/http_test.go
Add tests for invalid clients when getting a grant. Test that an invalid or missing client_id parameter when trying to obtain a grant code returns the error we expect.
| paddy@52 | 1 package auth |
| paddy@52 | 2 |
| paddy@52 | 3 import ( |
| paddy@52 | 4 "html/template" |
| paddy@52 | 5 "net/http" |
| paddy@52 | 6 "net/http/httptest" |
| paddy@53 | 7 "net/url" |
| paddy@52 | 8 "testing" |
| paddy@56 | 9 "time" |
| paddy@56 | 10 |
| paddy@56 | 11 "code.secondbit.org/uuid" |
| paddy@52 | 12 ) |
| paddy@52 | 13 |
| paddy@53 | 14 const ( |
| paddy@53 | 15 scopeSet = 1 << iota |
| paddy@53 | 16 stateSet |
| paddy@53 | 17 uriSet |
| paddy@53 | 18 ) |
| paddy@53 | 19 |
| paddy@52 | 20 func TestGetGrantCodeSuccess(t *testing.T) { |
| paddy@52 | 21 t.Parallel() |
| paddy@52 | 22 store := NewMemstore() |
| paddy@52 | 23 testContext := Context{ |
| paddy@52 | 24 template: template.Must(template.New(getGrantTemplateName).Parse("Get auth grant")), |
| paddy@52 | 25 clients: store, |
| paddy@52 | 26 grants: store, |
| paddy@52 | 27 profiles: store, |
| paddy@52 | 28 tokens: store, |
| paddy@52 | 29 } |
| paddy@56 | 30 client := Client{ |
| paddy@56 | 31 ID: uuid.NewID(), |
| paddy@56 | 32 Secret: "super secret!", |
| paddy@56 | 33 OwnerID: uuid.NewID(), |
| paddy@56 | 34 Name: "My test client", |
| paddy@56 | 35 Logo: "https://secondbit.org/logo.png", |
| paddy@56 | 36 Website: "https://secondbit.org", |
| paddy@56 | 37 Type: "public", |
| paddy@56 | 38 } |
| paddy@56 | 39 uri, err := url.Parse("https://test.secondbit.org/redirect") |
| paddy@56 | 40 if err != nil { |
| paddy@56 | 41 t.Fatal("Can't parse URL:", err) |
| paddy@56 | 42 } |
| paddy@56 | 43 endpoint := Endpoint{ |
| paddy@56 | 44 ID: uuid.NewID(), |
| paddy@56 | 45 ClientID: client.ID, |
| paddy@56 | 46 URI: *uri, |
| paddy@56 | 47 Added: time.Now(), |
| paddy@56 | 48 } |
| paddy@56 | 49 err = testContext.SaveClient(client) |
| paddy@56 | 50 if err != nil { |
| paddy@56 | 51 t.Fatal("Can't store client:", err) |
| paddy@56 | 52 } |
| paddy@56 | 53 err = testContext.AddEndpoint(client.ID, endpoint) |
| paddy@56 | 54 if err != nil { |
| paddy@56 | 55 t.Fatal("Can't store endpoint:", err) |
| paddy@56 | 56 } |
| paddy@52 | 57 req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@52 | 58 if err != nil { |
| paddy@52 | 59 t.Fatal("Can't build request:", err) |
| paddy@52 | 60 } |
| paddy@58 | 61 for i := 0; i < 1<<3; i++ { |
| paddy@53 | 62 w := httptest.NewRecorder() |
| paddy@53 | 63 params := url.Values{} |
| paddy@53 | 64 // see OAuth 2.0 spec, section 4.1.1 |
| paddy@53 | 65 params.Set("response_type", "code") |
| paddy@56 | 66 params.Set("client_id", client.ID.String()) |
| paddy@53 | 67 if i&uriSet != 0 { |
| paddy@58 | 68 params.Set("redirect_uri", endpoint.URI.String()) |
| paddy@53 | 69 } |
| paddy@53 | 70 if i&scopeSet != 0 { |
| paddy@53 | 71 params.Set("scope", "testscope") |
| paddy@53 | 72 } |
| paddy@53 | 73 if i&stateSet != 0 { |
| paddy@53 | 74 params.Set("state", "my super secure state string") |
| paddy@53 | 75 } |
| paddy@53 | 76 req.URL.RawQuery = params.Encode() |
| paddy@53 | 77 GetGrantHandler(w, req, testContext) |
| paddy@53 | 78 if w.Code != http.StatusOK { |
| paddy@53 | 79 t.Errorf("Expected status code to be %d, got %d for %s", http.StatusOK, w.Code, req.URL.String()) |
| paddy@53 | 80 } |
| paddy@53 | 81 if w.Body.String() != "Get auth grant" { |
| paddy@53 | 82 t.Errorf("Expected body to be `%s`, got `%s` for %s", "Get auth grant", w.Body.String(), req.URL.String()) |
| paddy@53 | 83 } |
| paddy@52 | 84 } |
| paddy@52 | 85 } |
| paddy@56 | 86 |
| paddy@62 | 87 func TestGetGrantCodeInvalidClient(t *testing.T) { |
| paddy@62 | 88 t.Parallel() |
| paddy@62 | 89 store := NewMemstore() |
| paddy@62 | 90 testContext := Context{ |
| paddy@62 | 91 template: template.Must(template.New(getGrantTemplateName).Parse("{{ .error }}")), |
| paddy@62 | 92 clients: store, |
| paddy@62 | 93 grants: store, |
| paddy@62 | 94 profiles: store, |
| paddy@62 | 95 tokens: store, |
| paddy@62 | 96 } |
| paddy@62 | 97 client := Client{ |
| paddy@62 | 98 ID: uuid.NewID(), |
| paddy@62 | 99 Secret: "super secret!", |
| paddy@62 | 100 OwnerID: uuid.NewID(), |
| paddy@62 | 101 Name: "My test client", |
| paddy@62 | 102 Type: "public", |
| paddy@62 | 103 } |
| paddy@62 | 104 err := testContext.SaveClient(client) |
| paddy@62 | 105 if err != nil { |
| paddy@62 | 106 t.Fatal("Can't store client:", err) |
| paddy@62 | 107 } |
| paddy@62 | 108 req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@62 | 109 if err != nil { |
| paddy@62 | 110 t.Fatal("Can't build request:", err) |
| paddy@62 | 111 } |
| paddy@62 | 112 w := httptest.NewRecorder() |
| paddy@62 | 113 params := url.Values{} |
| paddy@62 | 114 params.Set("response_type", "code") |
| paddy@62 | 115 params.Set("redirect_uri", "https://test.secondbit.org/") |
| paddy@62 | 116 req.URL.RawQuery = params.Encode() |
| paddy@62 | 117 GetGrantHandler(w, req, testContext) |
| paddy@62 | 118 if w.Code != http.StatusBadRequest { |
| paddy@62 | 119 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@62 | 120 } |
| paddy@62 | 121 if w.Body.String() != "Client ID must be specified in the request." { |
| paddy@62 | 122 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "Client ID must be specified in the request.", w.Body.String()) |
| paddy@62 | 123 } |
| paddy@62 | 124 w = httptest.NewRecorder() |
| paddy@62 | 125 params.Set("client_id", "Not an ID") |
| paddy@62 | 126 req.URL.RawQuery = params.Encode() |
| paddy@62 | 127 GetGrantHandler(w, req, testContext) |
| paddy@62 | 128 if w.Code != http.StatusBadRequest { |
| paddy@62 | 129 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@62 | 130 } |
| paddy@62 | 131 if w.Body.String() != "client_id is not a valid Client ID." { |
| paddy@62 | 132 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "client_id is not a valid Client ID.", w.Body.String()) |
| paddy@62 | 133 } |
| paddy@62 | 134 w = httptest.NewRecorder() |
| paddy@62 | 135 params.Set("client_id", uuid.NewID().String()) |
| paddy@62 | 136 req.URL.RawQuery = params.Encode() |
| paddy@62 | 137 GetGrantHandler(w, req, testContext) |
| paddy@62 | 138 if w.Code != http.StatusBadRequest { |
| paddy@62 | 139 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@62 | 140 } |
| paddy@62 | 141 if w.Body.String() != "The specified Client couldn’t be found." { |
| paddy@62 | 142 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "The specified Client couldn’t be found.", w.Body.String()) |
| paddy@62 | 143 } |
| paddy@62 | 144 } |
| paddy@62 | 145 |
| paddy@56 | 146 func TestGetGrantCodeInvalidURI(t *testing.T) { |
| paddy@56 | 147 t.Parallel() |
| paddy@56 | 148 store := NewMemstore() |
| paddy@56 | 149 testContext := Context{ |
| paddy@56 | 150 template: template.Must(template.New(getGrantTemplateName).Parse("{{ .error }}")), |
| paddy@56 | 151 clients: store, |
| paddy@56 | 152 grants: store, |
| paddy@56 | 153 profiles: store, |
| paddy@56 | 154 tokens: store, |
| paddy@56 | 155 } |
| paddy@56 | 156 client := Client{ |
| paddy@56 | 157 ID: uuid.NewID(), |
| paddy@56 | 158 Secret: "super secret!", |
| paddy@56 | 159 OwnerID: uuid.NewID(), |
| paddy@56 | 160 Name: "My test client", |
| paddy@56 | 161 Type: "public", |
| paddy@56 | 162 } |
| paddy@56 | 163 uri, err := url.Parse("https://test.secondbit.org/redirect") |
| paddy@56 | 164 if err != nil { |
| paddy@56 | 165 t.Fatal("Can't parse URL:", err) |
| paddy@56 | 166 } |
| paddy@56 | 167 endpoint := Endpoint{ |
| paddy@56 | 168 ID: uuid.NewID(), |
| paddy@56 | 169 ClientID: client.ID, |
| paddy@56 | 170 URI: *uri, |
| paddy@56 | 171 Added: time.Now(), |
| paddy@56 | 172 } |
| paddy@56 | 173 err = testContext.SaveClient(client) |
| paddy@56 | 174 if err != nil { |
| paddy@56 | 175 t.Fatal("Can't store client:", err) |
| paddy@56 | 176 } |
| paddy@56 | 177 err = testContext.AddEndpoint(client.ID, endpoint) |
| paddy@56 | 178 if err != nil { |
| paddy@56 | 179 t.Fatal("Can't store endpoint:", err) |
| paddy@56 | 180 } |
| paddy@56 | 181 req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@56 | 182 if err != nil { |
| paddy@56 | 183 t.Fatal("Can't build request:", err) |
| paddy@56 | 184 } |
| paddy@56 | 185 w := httptest.NewRecorder() |
| paddy@56 | 186 params := url.Values{} |
| paddy@56 | 187 params.Set("response_type", "code") |
| paddy@56 | 188 params.Set("client_id", client.ID.String()) |
| paddy@56 | 189 params.Set("redirect_uri", "https://test.secondbit.org/wrong") |
| paddy@56 | 190 req.URL.RawQuery = params.Encode() |
| paddy@56 | 191 GetGrantHandler(w, req, testContext) |
| paddy@56 | 192 if w.Code != http.StatusBadRequest { |
| paddy@56 | 193 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@56 | 194 } |
| paddy@56 | 195 if w.Body.String() != "The redirect_uri specified is not valid." { |
| paddy@56 | 196 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "The redirect_uri specified is not valid.", w.Body.String()) |
| paddy@56 | 197 } |
| paddy@60 | 198 req, err = http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@60 | 199 if err != nil { |
| paddy@60 | 200 t.Fatal("Can't build request:", err) |
| paddy@60 | 201 } |
| paddy@60 | 202 w = httptest.NewRecorder() |
| paddy@60 | 203 params.Set("redirect_uri", "not a URL") |
| paddy@60 | 204 req.URL.RawQuery = params.Encode() |
| paddy@60 | 205 GetGrantHandler(w, req, testContext) |
| paddy@60 | 206 if w.Code != http.StatusBadRequest { |
| paddy@60 | 207 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@60 | 208 } |
| paddy@60 | 209 if w.Body.String() != "The redirect_uri specified is not valid." { |
| paddy@60 | 210 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "The redirect_uri specified is not valid.", w.Body.String()) |
| paddy@60 | 211 } |
| paddy@56 | 212 } |