auth
auth/http_test.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.
| 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@56 | 87 func TestGetGrantCodeInvalidURI(t *testing.T) { |
| paddy@56 | 88 t.Parallel() |
| paddy@56 | 89 store := NewMemstore() |
| paddy@56 | 90 testContext := Context{ |
| paddy@56 | 91 template: template.Must(template.New(getGrantTemplateName).Parse("{{ .error }}")), |
| paddy@56 | 92 clients: store, |
| paddy@56 | 93 grants: store, |
| paddy@56 | 94 profiles: store, |
| paddy@56 | 95 tokens: store, |
| paddy@56 | 96 } |
| paddy@56 | 97 client := Client{ |
| paddy@56 | 98 ID: uuid.NewID(), |
| paddy@56 | 99 Secret: "super secret!", |
| paddy@56 | 100 OwnerID: uuid.NewID(), |
| paddy@56 | 101 Name: "My test client", |
| paddy@56 | 102 Type: "public", |
| paddy@56 | 103 } |
| paddy@56 | 104 uri, err := url.Parse("https://test.secondbit.org/redirect") |
| paddy@56 | 105 if err != nil { |
| paddy@56 | 106 t.Fatal("Can't parse URL:", err) |
| paddy@56 | 107 } |
| paddy@56 | 108 endpoint := Endpoint{ |
| paddy@56 | 109 ID: uuid.NewID(), |
| paddy@56 | 110 ClientID: client.ID, |
| paddy@56 | 111 URI: *uri, |
| paddy@56 | 112 Added: time.Now(), |
| paddy@56 | 113 } |
| paddy@56 | 114 err = testContext.SaveClient(client) |
| paddy@56 | 115 if err != nil { |
| paddy@56 | 116 t.Fatal("Can't store client:", err) |
| paddy@56 | 117 } |
| paddy@56 | 118 err = testContext.AddEndpoint(client.ID, endpoint) |
| paddy@56 | 119 if err != nil { |
| paddy@56 | 120 t.Fatal("Can't store endpoint:", err) |
| paddy@56 | 121 } |
| paddy@56 | 122 req, err := http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@56 | 123 if err != nil { |
| paddy@56 | 124 t.Fatal("Can't build request:", err) |
| paddy@56 | 125 } |
| paddy@56 | 126 w := httptest.NewRecorder() |
| paddy@56 | 127 params := url.Values{} |
| paddy@56 | 128 params.Set("response_type", "code") |
| paddy@56 | 129 params.Set("client_id", client.ID.String()) |
| paddy@56 | 130 params.Set("redirect_uri", "https://test.secondbit.org/wrong") |
| paddy@56 | 131 req.URL.RawQuery = params.Encode() |
| paddy@56 | 132 GetGrantHandler(w, req, testContext) |
| paddy@56 | 133 if w.Code != http.StatusBadRequest { |
| paddy@56 | 134 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@56 | 135 } |
| paddy@56 | 136 if w.Body.String() != "The redirect_uri specified is not valid." { |
| paddy@56 | 137 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "The redirect_uri specified is not valid.", w.Body.String()) |
| paddy@56 | 138 } |
| paddy@60 | 139 req, err = http.NewRequest("GET", "https://test.auth.secondbit.org/oauth2/grant", nil) |
| paddy@60 | 140 if err != nil { |
| paddy@60 | 141 t.Fatal("Can't build request:", err) |
| paddy@60 | 142 } |
| paddy@60 | 143 w = httptest.NewRecorder() |
| paddy@60 | 144 params.Set("redirect_uri", "not a URL") |
| paddy@60 | 145 req.URL.RawQuery = params.Encode() |
| paddy@60 | 146 GetGrantHandler(w, req, testContext) |
| paddy@60 | 147 if w.Code != http.StatusBadRequest { |
| paddy@60 | 148 t.Errorf("Expected status code to be %d, got %d", http.StatusBadRequest, w.Code) |
| paddy@60 | 149 } |
| paddy@60 | 150 if w.Body.String() != "The redirect_uri specified is not valid." { |
| paddy@60 | 151 t.Errorf(`Expected output to be "%s", got "%s" instead.`, "The redirect_uri specified is not valid.", w.Body.String()) |
| paddy@60 | 152 } |
| paddy@56 | 153 } |