auth

Paddy 2014-10-26 Parent:a5987795707e Child:0cc717e02c9b

58:b3cd7765a7c8 Go to Latest

auth/http_test.go

Require full URLs for Endpoints. The spec says that we SHOULD require full URLs for redirection, but we _can_ offer the ability to set a URL as a "partial URL" if we really must. I see no particular reason to do this, so I've simplified the code by pulling that option out. This means that URLs (as long as they're normalized, which I've filed a bug in the codebase to do) can be checked using simple string comparison, which makes the likelihood of bugs across clientStorage implementations a lot lower.

History
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@56 139 }