auth
2015-12-14
Parent:b7e685839a1b
auth/authcode_test.go
Update nsq import path. go-nsq has moved to nsqio/go-nsq, so we need to update the import path appropriately.
| paddy@29 | 1 package auth |
| paddy@29 | 2 |
| paddy@29 | 3 import ( |
| paddy@111 | 4 "bytes" |
| paddy@111 | 5 "io/ioutil" |
| paddy@111 | 6 "net/http" |
| paddy@111 | 7 "net/http/httptest" |
| paddy@111 | 8 "net/url" |
| paddy@156 | 9 "os" |
| paddy@111 | 10 "strings" |
| paddy@29 | 11 "testing" |
| paddy@29 | 12 "time" |
| paddy@29 | 13 |
| paddy@181 | 14 "code.secondbit.org/scopes.hg/types" |
| paddy@107 | 15 "code.secondbit.org/uuid.hg" |
| paddy@29 | 16 ) |
| paddy@29 | 17 |
| paddy@156 | 18 func init() { |
| paddy@156 | 19 if os.Getenv("PG_TEST_DB") != "" { |
| paddy@156 | 20 p, err := NewPostgres(os.Getenv("PG_TEST_DB")) |
| paddy@156 | 21 if err != nil { |
| paddy@156 | 22 panic(err) |
| paddy@156 | 23 } |
| paddy@156 | 24 authCodeStores = append(authCodeStores, &p) |
| paddy@156 | 25 } |
| paddy@156 | 26 } |
| paddy@156 | 27 |
| paddy@87 | 28 var authCodeStores = []authorizationCodeStore{NewMemstore()} |
| paddy@29 | 29 |
| paddy@87 | 30 func compareAuthorizationCodes(authCode1, authCode2 AuthorizationCode) (success bool, field string, authCode1val, authCode2val interface{}) { |
| paddy@87 | 31 if authCode1.Code != authCode2.Code { |
| paddy@87 | 32 return false, "code", authCode1.Code, authCode2.Code |
| paddy@34 | 33 } |
| paddy@87 | 34 if !authCode1.Created.Equal(authCode2.Created) { |
| paddy@87 | 35 return false, "created", authCode1.Created, authCode2.Created |
| paddy@34 | 36 } |
| paddy@87 | 37 if authCode1.ExpiresIn != authCode2.ExpiresIn { |
| paddy@87 | 38 return false, "expires in", authCode1.ExpiresIn, authCode2.ExpiresIn |
| paddy@34 | 39 } |
| paddy@87 | 40 if !authCode1.ClientID.Equal(authCode2.ClientID) { |
| paddy@87 | 41 return false, "client ID", authCode1.ClientID, authCode2.ClientID |
| paddy@34 | 42 } |
| paddy@135 | 43 if len(authCode1.Scopes) != len(authCode2.Scopes) { |
| paddy@135 | 44 return false, "scopes", authCode1.Scopes, authCode2.Scopes |
| paddy@135 | 45 } |
| paddy@135 | 46 for pos, scope := range authCode1.Scopes { |
| paddy@135 | 47 if scope != authCode2.Scopes[pos] { |
| paddy@135 | 48 return false, "scopes", authCode1.Scopes, authCode2.Scopes |
| paddy@135 | 49 } |
| paddy@34 | 50 } |
| paddy@87 | 51 if authCode1.RedirectURI != authCode2.RedirectURI { |
| paddy@87 | 52 return false, "redirect URI", authCode1.RedirectURI, authCode2.RedirectURI |
| paddy@34 | 53 } |
| paddy@87 | 54 if authCode1.State != authCode2.State { |
| paddy@87 | 55 return false, "state", authCode1.State, authCode2.State |
| paddy@34 | 56 } |
| paddy@111 | 57 if !authCode1.ProfileID.Equal(authCode2.ProfileID) { |
| paddy@111 | 58 return false, "profile ID", authCode1.ProfileID, authCode2.ProfileID |
| paddy@111 | 59 } |
| paddy@111 | 60 if authCode1.Used != authCode2.Used { |
| paddy@111 | 61 return false, "used", authCode1.Used, authCode2.Used |
| paddy@111 | 62 } |
| paddy@34 | 63 return true, "", nil, nil |
| paddy@34 | 64 } |
| paddy@34 | 65 |
| paddy@111 | 66 func TestAuthorizationCodeStore(t *testing.T) { |
| paddy@36 | 67 t.Parallel() |
| paddy@87 | 68 authCode := AuthorizationCode{ |
| paddy@29 | 69 Code: "code", |
| paddy@149 | 70 Created: time.Now().Round(time.Millisecond), |
| paddy@29 | 71 ExpiresIn: 180, |
| paddy@29 | 72 ClientID: uuid.NewID(), |
| paddy@181 | 73 Scopes: scopeTypes.StringsToScopes([]string{"scope"}), |
| paddy@29 | 74 RedirectURI: "redirectURI", |
| paddy@29 | 75 State: "state", |
| paddy@29 | 76 } |
| paddy@87 | 77 for _, store := range authCodeStores { |
| paddy@116 | 78 context := Context{authCodes: store} |
| paddy@116 | 79 err := context.SaveAuthorizationCode(authCode) |
| paddy@29 | 80 if err != nil { |
| paddy@87 | 81 t.Errorf("Error saving auth code to %T: %s", store, err) |
| paddy@34 | 82 } |
| paddy@116 | 83 err = context.SaveAuthorizationCode(authCode) |
| paddy@87 | 84 if err != ErrAuthorizationCodeAlreadyExists { |
| paddy@87 | 85 t.Errorf("Expected ErrAuthorizationCodeAlreadyExists from %T, got %+v", store, err) |
| paddy@29 | 86 } |
| paddy@116 | 87 retrieved, err := context.GetAuthorizationCode(authCode.Code) |
| paddy@29 | 88 if err != nil { |
| paddy@87 | 89 t.Errorf("Error retrieving auth code from %T: %s", store, err) |
| paddy@29 | 90 } |
| paddy@87 | 91 match, field, expectation, result := compareAuthorizationCodes(authCode, retrieved) |
| paddy@34 | 92 if !match { |
| paddy@87 | 93 t.Errorf("Expected `%v` in the `%s` field of auth code retrieved from %T, got `%v`", expectation, field, store, result) |
| paddy@34 | 94 } |
| paddy@116 | 95 err = context.UseAuthorizationCode(authCode.Code) |
| paddy@111 | 96 if err != nil { |
| paddy@111 | 97 t.Errorf("Error retrieving auth code from %T: %s", store, err) |
| paddy@111 | 98 } |
| paddy@116 | 99 retrieved, err = context.GetAuthorizationCode(authCode.Code) |
| paddy@111 | 100 if err != nil { |
| paddy@111 | 101 t.Errorf("Error retrieving auth code from %T: %s", store, err) |
| paddy@111 | 102 } |
| paddy@111 | 103 authCode.Used = true |
| paddy@111 | 104 match, field, expectation, result = compareAuthorizationCodes(authCode, retrieved) |
| paddy@111 | 105 if !match { |
| paddy@111 | 106 t.Errorf("Expected `%v` in the `%s` field of auth code retrieved from %T, got `%v`", expectation, field, store, result) |
| paddy@111 | 107 } |
| paddy@116 | 108 err = context.DeleteAuthorizationCode(authCode.Code) |
| paddy@29 | 109 if err != nil { |
| paddy@87 | 110 t.Errorf("Error removing auth code from %T: %s", store, err) |
| paddy@29 | 111 } |
| paddy@116 | 112 retrieved, err = context.GetAuthorizationCode(authCode.Code) |
| paddy@87 | 113 if err != ErrAuthorizationCodeNotFound { |
| paddy@87 | 114 t.Errorf("Expected ErrAuthorizationCodeNotFound from %T, got %+v and %+v", store, retrieved, err) |
| paddy@34 | 115 } |
| paddy@116 | 116 err = context.DeleteAuthorizationCode(authCode.Code) |
| paddy@87 | 117 if err != ErrAuthorizationCodeNotFound { |
| paddy@87 | 118 t.Errorf("Expected ErrAuthorizationCodeNotFound from %T, got %+v", store, err) |
| paddy@29 | 119 } |
| paddy@116 | 120 err = context.UseAuthorizationCode(authCode.Code) |
| paddy@111 | 121 if err != ErrAuthorizationCodeNotFound { |
| paddy@111 | 122 t.Errorf("Expected ErrAuthorizationCodeNotFound from %T, got %+v", store, err) |
| paddy@111 | 123 } |
| paddy@29 | 124 } |
| paddy@29 | 125 } |
| paddy@111 | 126 |
| paddy@111 | 127 func TestAuthCodeGrantValidate(t *testing.T) { |
| paddy@111 | 128 t.Parallel() |
| paddy@111 | 129 store := NewMemstore() |
| paddy@111 | 130 testContext := Context{ |
| paddy@111 | 131 clients: store, |
| paddy@111 | 132 authCodes: store, |
| paddy@111 | 133 profiles: store, |
| paddy@111 | 134 tokens: store, |
| paddy@111 | 135 sessions: store, |
| paddy@111 | 136 } |
| paddy@111 | 137 client := Client{ |
| paddy@111 | 138 ID: uuid.NewID(), |
| paddy@111 | 139 Secret: "super secret!", |
| paddy@111 | 140 OwnerID: uuid.NewID(), |
| paddy@111 | 141 Name: "My test client", |
| paddy@111 | 142 Logo: "https://secondbit.org/logo.png", |
| paddy@111 | 143 Website: "https://secondbit.org/", |
| paddy@111 | 144 Type: "public", |
| paddy@111 | 145 } |
| paddy@111 | 146 endpoint := Endpoint{ |
| paddy@111 | 147 ID: uuid.NewID(), |
| paddy@111 | 148 ClientID: client.ID, |
| paddy@116 | 149 URI: "https://test.secondbit.org/redirect", |
| paddy@149 | 150 Added: time.Now().Round(time.Millisecond), |
| paddy@111 | 151 } |
| paddy@116 | 152 err := testContext.SaveClient(client) |
| paddy@111 | 153 if err != nil { |
| paddy@111 | 154 t.Fatal("Can't store client:", err) |
| paddy@111 | 155 } |
| paddy@151 | 156 err = testContext.AddEndpoints([]Endpoint{endpoint}) |
| paddy@111 | 157 if err != nil { |
| paddy@111 | 158 t.Fatal("Can't store endpoint:", err) |
| paddy@111 | 159 } |
| paddy@111 | 160 code := AuthorizationCode{ |
| paddy@111 | 161 Code: "myauthcode", |
| paddy@149 | 162 Created: time.Now().Round(time.Millisecond), |
| paddy@111 | 163 ExpiresIn: 180, |
| paddy@111 | 164 ClientID: uuid.NewID(), |
| paddy@181 | 165 Scopes: scopeTypes.StringsToScopes([]string{"scope"}), |
| paddy@111 | 166 RedirectURI: "redirectURI", |
| paddy@111 | 167 State: "state", |
| paddy@111 | 168 } |
| paddy@111 | 169 err = testContext.SaveAuthorizationCode(code) |
| paddy@111 | 170 if err != nil { |
| paddy@111 | 171 t.Fatal("Can't add auth code:", err) |
| paddy@111 | 172 } |
| paddy@112 | 173 code2 := code |
| paddy@112 | 174 code2.Code = "otherauthcode" |
| paddy@112 | 175 code2.ClientID = client.ID |
| paddy@112 | 176 err = testContext.SaveAuthorizationCode(code2) |
| paddy@112 | 177 if err != nil { |
| paddy@112 | 178 t.Fatal("Can't add second auth code:", err) |
| paddy@112 | 179 } |
| paddy@111 | 180 req, err := http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@111 | 181 if err != nil { |
| paddy@111 | 182 t.Fatal("Can't build request:", err) |
| paddy@111 | 183 } |
| paddy@112 | 184 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@111 | 185 w := httptest.NewRecorder() |
| paddy@111 | 186 params := url.Values{} |
| paddy@111 | 187 body := bytes.NewBufferString(params.Encode()) |
| paddy@111 | 188 req.Body = ioutil.NopCloser(body) |
| paddy@111 | 189 scope, profileID, valid := authCodeGrantValidate(w, req, testContext) |
| paddy@111 | 190 if valid { |
| paddy@112 | 191 t.Fatalf("Expected invalid auth code, got scope `%s` and profileID `%s`.", scope, profileID) |
| paddy@111 | 192 } |
| paddy@111 | 193 if w.Code != http.StatusBadRequest { |
| paddy@111 | 194 t.Errorf("Expected status %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@111 | 195 } |
| paddy@112 | 196 expectedBody := `{"error":"invalid_request"}` |
| paddy@112 | 197 if strings.TrimSpace(w.Body.String()) != expectedBody { |
| paddy@112 | 198 t.Errorf("Expected body of `%s`, got `%s`", expectedBody, strings.TrimSpace(w.Body.String())) |
| paddy@112 | 199 } |
| paddy@112 | 200 |
| paddy@112 | 201 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 202 if err != nil { |
| paddy@112 | 203 t.Fatal("Can't build request:", err) |
| paddy@112 | 204 } |
| paddy@112 | 205 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 206 w = httptest.NewRecorder() |
| paddy@112 | 207 params = url.Values{} |
| paddy@112 | 208 params.Set("code", "notmycode") |
| paddy@112 | 209 body = bytes.NewBufferString(params.Encode()) |
| paddy@112 | 210 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 211 err = req.ParseForm() |
| paddy@112 | 212 if err != nil { |
| paddy@112 | 213 t.Log(err) |
| paddy@112 | 214 } |
| paddy@112 | 215 scope, profileID, valid = authCodeGrantValidate(w, req, testContext) |
| paddy@112 | 216 if valid { |
| paddy@112 | 217 t.Fatalf("Expected invalid auth code, got scope `%s` and profileID `%s`.", scope, profileID) |
| paddy@112 | 218 } |
| paddy@112 | 219 if w.Code != http.StatusUnauthorized { |
| paddy@112 | 220 t.Errorf("Expected status %d, got %d", http.StatusUnauthorized, w.Code) |
| paddy@112 | 221 } |
| paddy@112 | 222 expectedBody = `{"error":"invalid_client"}` |
| paddy@112 | 223 if expectedBody != strings.TrimSpace(w.Body.String()) { |
| paddy@112 | 224 t.Errorf("Expected body of `%s`, got `%s`", expectedBody, strings.TrimSpace(w.Body.String())) |
| paddy@112 | 225 } |
| paddy@112 | 226 |
| paddy@112 | 227 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 228 if err != nil { |
| paddy@112 | 229 t.Fatal("Can't build request:", err) |
| paddy@112 | 230 } |
| paddy@112 | 231 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 232 req.SetBasicAuth(client.ID.String(), client.Secret) |
| paddy@112 | 233 w = httptest.NewRecorder() |
| paddy@112 | 234 params = url.Values{} |
| paddy@112 | 235 params.Set("code", "notmycode") |
| paddy@112 | 236 body = bytes.NewBufferString(params.Encode()) |
| paddy@112 | 237 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 238 err = req.ParseForm() |
| paddy@112 | 239 if err != nil { |
| paddy@112 | 240 t.Log(err) |
| paddy@112 | 241 } |
| paddy@112 | 242 scope, profileID, valid = authCodeGrantValidate(w, req, testContext) |
| paddy@112 | 243 if valid { |
| paddy@112 | 244 t.Fatalf("Expected invalid auth code, got scope `%s` and profileID `%s`.", scope, profileID) |
| paddy@112 | 245 } |
| paddy@112 | 246 if w.Code != http.StatusBadRequest { |
| paddy@112 | 247 t.Errorf("Expected status %d, got %d", http.StatusUnauthorized, w.Code) |
| paddy@112 | 248 } |
| paddy@112 | 249 expectedBody = `{"error":"invalid_grant"}` |
| paddy@112 | 250 if expectedBody != strings.TrimSpace(w.Body.String()) { |
| paddy@112 | 251 t.Errorf("Expected body of `%s`, got `%s`", expectedBody, strings.TrimSpace(w.Body.String())) |
| paddy@112 | 252 } |
| paddy@112 | 253 |
| paddy@112 | 254 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 255 if err != nil { |
| paddy@112 | 256 t.Fatal("Can't build request:", err) |
| paddy@112 | 257 } |
| paddy@112 | 258 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 259 req.SetBasicAuth(client.ID.String(), client.Secret) |
| paddy@112 | 260 w = httptest.NewRecorder() |
| paddy@112 | 261 params = url.Values{} |
| paddy@112 | 262 params.Set("code", code.Code) |
| paddy@112 | 263 params.Set("redirect_uri", "not my redirectURI") |
| paddy@112 | 264 body = bytes.NewBufferString(params.Encode()) |
| paddy@112 | 265 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 266 err = req.ParseForm() |
| paddy@112 | 267 if err != nil { |
| paddy@112 | 268 t.Log(err) |
| paddy@112 | 269 } |
| paddy@112 | 270 scope, profileID, valid = authCodeGrantValidate(w, req, testContext) |
| paddy@112 | 271 if valid { |
| paddy@112 | 272 t.Fatalf("Expected invalid auth code, got scope `%s` and profileID `%s`.", scope, profileID) |
| paddy@112 | 273 } |
| paddy@112 | 274 if w.Code != http.StatusBadRequest { |
| paddy@112 | 275 t.Errorf("Expected status %d, got %d", http.StatusUnauthorized, w.Code) |
| paddy@112 | 276 } |
| paddy@112 | 277 expectedBody = `{"error":"invalid_grant"}` |
| paddy@112 | 278 if expectedBody != strings.TrimSpace(w.Body.String()) { |
| paddy@112 | 279 t.Errorf("Expected body of `%s`, got `%s`", expectedBody, strings.TrimSpace(w.Body.String())) |
| paddy@112 | 280 } |
| paddy@112 | 281 |
| paddy@112 | 282 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 283 if err != nil { |
| paddy@112 | 284 t.Fatal("Can't build request:", err) |
| paddy@112 | 285 } |
| paddy@112 | 286 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 287 req.SetBasicAuth(client.ID.String(), client.Secret) |
| paddy@112 | 288 w = httptest.NewRecorder() |
| paddy@112 | 289 params = url.Values{} |
| paddy@112 | 290 params.Set("code", code.Code) |
| paddy@112 | 291 params.Set("redirect_uri", code.RedirectURI) |
| paddy@112 | 292 body = bytes.NewBufferString(params.Encode()) |
| paddy@112 | 293 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 294 err = req.ParseForm() |
| paddy@112 | 295 if err != nil { |
| paddy@112 | 296 t.Log(err) |
| paddy@112 | 297 } |
| paddy@112 | 298 scope, profileID, valid = authCodeGrantValidate(w, req, testContext) |
| paddy@112 | 299 if valid { |
| paddy@112 | 300 t.Fatalf("Expected invalid auth code, got scope `%s` and profileID `%s`.", scope, profileID) |
| paddy@112 | 301 } |
| paddy@112 | 302 if w.Code != http.StatusBadRequest { |
| paddy@112 | 303 t.Errorf("Expected status %d, got %d", http.StatusUnauthorized, w.Code) |
| paddy@112 | 304 } |
| paddy@112 | 305 expectedBody = `{"error":"invalid_grant"}` |
| paddy@112 | 306 if expectedBody != strings.TrimSpace(w.Body.String()) { |
| paddy@112 | 307 t.Errorf("Expected body of `%s`, got `%s`", expectedBody, strings.TrimSpace(w.Body.String())) |
| paddy@112 | 308 } |
| paddy@112 | 309 |
| paddy@112 | 310 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 311 if err != nil { |
| paddy@112 | 312 t.Fatal("Can't build request:", err) |
| paddy@112 | 313 } |
| paddy@112 | 314 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 315 req.SetBasicAuth(client.ID.String(), client.Secret) |
| paddy@112 | 316 w = httptest.NewRecorder() |
| paddy@112 | 317 params = url.Values{} |
| paddy@112 | 318 params.Set("code", code2.Code) |
| paddy@112 | 319 params.Set("redirect_uri", code2.RedirectURI) |
| paddy@112 | 320 body = bytes.NewBufferString(params.Encode()) |
| paddy@112 | 321 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 322 err = req.ParseForm() |
| paddy@112 | 323 if err != nil { |
| paddy@112 | 324 t.Log(err) |
| paddy@112 | 325 } |
| paddy@112 | 326 scope, profileID, valid = authCodeGrantValidate(w, req, testContext) |
| paddy@112 | 327 if !valid { |
| paddy@112 | 328 t.Fatalf("Expected valid auth code, was not valid.") |
| paddy@111 | 329 } |
| paddy@111 | 330 } |
| paddy@112 | 331 |
| paddy@112 | 332 func TestAuthCodeGrantInvalidate(t *testing.T) { |
| paddy@112 | 333 t.Parallel() |
| paddy@112 | 334 store := NewMemstore() |
| paddy@112 | 335 testContext := Context{ |
| paddy@112 | 336 clients: store, |
| paddy@112 | 337 authCodes: store, |
| paddy@112 | 338 profiles: store, |
| paddy@112 | 339 tokens: store, |
| paddy@112 | 340 sessions: store, |
| paddy@112 | 341 } |
| paddy@112 | 342 code := AuthorizationCode{ |
| paddy@112 | 343 Code: "myauthcode", |
| paddy@149 | 344 Created: time.Now().Round(time.Millisecond), |
| paddy@112 | 345 ExpiresIn: 180, |
| paddy@112 | 346 ClientID: uuid.NewID(), |
| paddy@181 | 347 Scopes: scopeTypes.StringsToScopes([]string{"scope"}), |
| paddy@112 | 348 RedirectURI: "redirectURI", |
| paddy@112 | 349 State: "state", |
| paddy@112 | 350 } |
| paddy@112 | 351 err := testContext.SaveAuthorizationCode(code) |
| paddy@112 | 352 if err != nil { |
| paddy@112 | 353 t.Fatal("Can't add auth code:", err) |
| paddy@112 | 354 } |
| paddy@112 | 355 req, err := http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 356 if err != nil { |
| paddy@112 | 357 t.Fatal("Can't build request:", err) |
| paddy@112 | 358 } |
| paddy@112 | 359 err = authCodeGrantInvalidate(req, testContext) |
| paddy@112 | 360 if err != ErrAuthorizationCodeNotFound { |
| paddy@112 | 361 t.Errorf("Expected `%s`, got `%+v`", ErrAuthorizationCodeNotFound, err) |
| paddy@112 | 362 } |
| paddy@112 | 363 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 364 if err != nil { |
| paddy@112 | 365 t.Fatal("Can't build request:", err) |
| paddy@112 | 366 } |
| paddy@112 | 367 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 368 params := url.Values{} |
| paddy@112 | 369 params.Set("code", "notmycode") |
| paddy@112 | 370 body := bytes.NewBufferString(params.Encode()) |
| paddy@112 | 371 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 372 err = authCodeGrantInvalidate(req, testContext) |
| paddy@112 | 373 if err != ErrAuthorizationCodeNotFound { |
| paddy@112 | 374 t.Errorf("Expected `%s`, got `%+v`", ErrAuthorizationCodeNotFound, err) |
| paddy@112 | 375 } |
| paddy@112 | 376 req, err = http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@112 | 377 if err != nil { |
| paddy@112 | 378 t.Fatal("Can't build request:", err) |
| paddy@112 | 379 } |
| paddy@112 | 380 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") |
| paddy@112 | 381 params.Set("code", code.Code) |
| paddy@112 | 382 body = bytes.NewBufferString(params.Encode()) |
| paddy@112 | 383 req.Body = ioutil.NopCloser(body) |
| paddy@112 | 384 err = authCodeGrantInvalidate(req, testContext) |
| paddy@112 | 385 if err != nil { |
| paddy@112 | 386 t.Error("Error invalidating auth code:", err) |
| paddy@112 | 387 } |
| paddy@112 | 388 authCode, err := testContext.GetAuthorizationCode(code.Code) |
| paddy@112 | 389 if err != nil { |
| paddy@112 | 390 t.Error("Error retrieving auth code:", err) |
| paddy@112 | 391 } |
| paddy@112 | 392 if !authCode.Used { |
| paddy@112 | 393 t.Error("Expected auth code to be used, was not.") |
| paddy@112 | 394 } |
| paddy@112 | 395 } |