diff --git a/defaults/responder.go b/defaults/responder.go index d97c10e..55aa9cb 100644 --- a/defaults/responder.go +++ b/defaults/responder.go @@ -8,40 +8,16 @@ import ( // Responder helps respond to http requests type Responder struct { - // CRSFHandler creates csrf tokens for inclusion on rendered forms - CSRFMaker CSRFMaker - // CRSFName is the name of the field that will include the token - CSRFName string - Renderer authboss.Renderer } -// CSRFMaker returns an opaque string when handed a request and response -// to be included in the data as a -type CSRFMaker func(w http.ResponseWriter, r *http.Request) string - -// Respond to an HTTP request. Renders templates, flash messages, does CSRF -// and writes the headers out. +// Respond to an HTTP request. It's main job is to merge data that comes in from +// various middlewares via the context with the data sent by the controller and render that. func (r *Responder) Respond(w http.ResponseWriter, req *http.Request, code int, templateName string, data authboss.HTMLData) error { - data.MergeKV( - r.CSRFName, r.CSRFMaker(w, req), - ) - - /* - TODO(aarondl): Add middlewares for accumulating eventual view data using contexts - if a.LayoutDataMaker != nil { - data.Merge(a.LayoutDataMaker(w, req)) - } - - flashSuccess := authboss.FlashSuccess(w, req) - flashError := authboss.FlashError(w, req) - if len(flashSuccess) != 0 { - data.MergeKV(authboss.FlashSuccessKey, flashSuccess) - } - if len(flashError) != 0 { - data.MergeKV(authboss.FlashErrorKey, flashError) - } - */ + ctxData := req.Context().Value(authboss.CTXKeyData) + if ctxData != nil { + data.Merge(ctxData.(authboss.HTMLData)) + } rendered, mime, err := r.Renderer.Render(req.Context(), templateName, data) if err != nil { diff --git a/defaults/responder_test.go b/defaults/responder_test.go index 863c63d..5b03393 100644 --- a/defaults/responder_test.go +++ b/defaults/responder_test.go @@ -20,24 +20,34 @@ func (t testRenderer) Render(ctx context.Context, name string, data authboss.HTM return t.Callback(ctx, name, data) } +func testJSONRender(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) { + b, err := json.Marshal(data) + if err != nil { + panic(err) + } + + return b, "application/json", nil +} + func TestResponder(t *testing.T) { t.Parallel() renderer := testRenderer{ - Callback: func(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) { - return nil, "", nil - }, + Callback: testJSONRender, } responder := Responder{ - Renderer: renderer, - CSRFName: "csrf", - CSRFMaker: func(w http.ResponseWriter, r *http.Request) string { return "csrftoken" }, + Renderer: renderer, } r := httptest.NewRequest("GET", "/", nil) w := httptest.NewRecorder() + r = r.WithContext(context.WithValue(context.Background(), authboss.CTXKeyData, authboss.HTMLData{ + "csrfname": "csrf", + "csrftoken": "12345", + })) + err := responder.Respond(w, r, http.StatusCreated, "some_template.tpl", authboss.HTMLData{"auth_happy": true}) if err != nil { t.Error(err) @@ -52,9 +62,8 @@ func TestResponder(t *testing.T) { } expectData := authboss.HTMLData{ - "csrfName": "xsrf", - "csrfToken": "xsrftoken", - "hello": "world", + "csrfname": "csrf", + "csrftoken": "12345", "auth_happy": true, } @@ -71,9 +80,7 @@ func TestRedirector(t *testing.T) { t.Parallel() renderer := testRenderer{ - Callback: func(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) { - return nil, "", nil - }, + Callback: testJSONRender, } redir := Redirector{ @@ -102,7 +109,7 @@ func TestRedirector(t *testing.T) { var gotData map[string]string if err := json.Unmarshal(w.Body.Bytes(), &gotData); err != nil { - t.Error(err) + t.Fatal(err) } if got := gotData["status"]; got != "success" { @@ -120,9 +127,7 @@ func TestResponseRedirectAPIFollowRedir(t *testing.T) { t.Parallel() renderer := testRenderer{ - Callback: func(ctx context.Context, name string, data authboss.HTMLData) ([]byte, string, error) { - return nil, "", nil - }, + Callback: testJSONRender, } redir := Redirector{ @@ -151,7 +156,7 @@ func TestResponseRedirectAPIFollowRedir(t *testing.T) { var gotData map[string]string if err := json.Unmarshal(w.Body.Bytes(), &gotData); err != nil { - t.Error(err) + t.Fatal(err) } if got := gotData["status"]; got != "failure" { diff --git a/defaults/router_test.go b/defaults/router_test.go index ddbb08f..ad97ef2 100644 --- a/defaults/router_test.go +++ b/defaults/router_test.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "strings" "testing" ) @@ -39,12 +40,29 @@ func TestRouter(t *testing.T) { delete = string(b) })) + wr := httptest.NewRecorder() + req := httptest.NewRequest("GET", "/test", strings.NewReader("testget")) + r.ServeHTTP(wr, req) if get != wantGet { t.Error("want:", wantGet, "got:", get) } + if len(post) != 0 || len(delete) != 0 { + t.Error("should be empty:", post, delete) + } + + wr = httptest.NewRecorder() + req = httptest.NewRequest("POST", "/test", strings.NewReader("testpost")) + r.ServeHTTP(wr, req) if post != wantPost { t.Error("want:", wantPost, "got:", post) } + if len(delete) != 0 { + t.Error("should be empty:", delete) + } + + wr = httptest.NewRecorder() + req = httptest.NewRequest("DELETE", "/test", strings.NewReader("testdelete")) + r.ServeHTTP(wr, req) if delete != wantDelete { t.Error("want:", wantDelete, "got:", delete) } diff --git a/defaults/validation.go b/defaults/validation.go index 159113d..6a0c455 100644 --- a/defaults/validation.go +++ b/defaults/validation.go @@ -27,7 +27,6 @@ func (h HTTPFormValidator) Validate(r *http.Request) authboss.ErrorList { } for i := 0; i < len(h.ConfirmFields)-1; i += 2 { - fmt.Println(h.ConfirmFields) main := r.FormValue(h.ConfirmFields[i]) if len(main) == 0 { continue