func (d *Discharger) login(w http.ResponseWriter, r *http.Request) { r.ParseForm() if d.LoginHandler != nil { d.LoginHandler(d, w, r) return } al, err := d.GetAgentLogin(r) if err != nil { d.WriteJSON(w, http.StatusBadRequest, httpbakery.Error{ Message: fmt.Sprintf("cannot read agent login: %s", err), }) return } _, err = httpbakery.CheckRequest(d.Bakery, r, nil, nil) if err == nil { d.FinishWait(w, r, nil) d.WriteJSON(w, http.StatusOK, agent.AgentResponse{ AgentLogin: true, }) return } m, err := d.Bakery.NewMacaroon("", nil, []checkers.Caveat{ bakery.LocalThirdPartyCaveat(al.PublicKey), }) if err != nil { d.WriteJSON(w, http.StatusInternalServerError, httpbakery.Error{ Message: fmt.Sprintf("cannot create macaroon: %s", err), }) return } httpbakery.WriteDischargeRequiredError(w, m, "", nil) }
func (*suite) TestMacaraq(c *gc.C) { checked := false d := bakerytest.NewDischarger(nil, func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { if cond != "something" { return nil, fmt.Errorf("unexpected 3rd party cond") } checked = true return nil, nil }) bsvc, err := bakery.NewService(bakery.NewServiceParams{ Location: "here", Locator: d, }) c.Assert(err, gc.IsNil) svc := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { req.ParseForm() _, checkErr := httpbakery.CheckRequest(bsvc, req, nil, checkers.New()) if checkErr == nil { w.Header().Set("Content-Type", "application/json") data, err := json.Marshal(req.Form) c.Check(err, gc.IsNil) w.Write(data) return } m, err := bsvc.NewMacaroon("", nil, []checkers.Caveat{{ Location: d.Service.Location(), Condition: "something", }}) c.Check(err, gc.IsNil) httpbakery.WriteDischargeRequiredError(w, m, "/", checkErr) })) fset := flag.NewFlagSet("http", flag.ContinueOnError) ctxt, params, err := newContext(fset, []string{ svc.URL, "x=y", }) c.Assert(err, gc.IsNil) client := httpbakery.NewClient() resp, err := ctxt.doRequest(client, nil) c.Assert(err, gc.IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, gc.Equals, http.StatusOK) c.Assert(checked, jc.IsTrue) var stdout bytes.Buffer err = showResponse(params, resp, &stdout) c.Assert(err, gc.IsNil) c.Assert(stdout.String(), gc.Equals, `{ x: [ "y" ] } `) }
func (s *ErrorSuite) TestWriteDischargeRequiredError(c *gc.C) { m, err := macaroon.New([]byte("secret"), "id", "a location") c.Assert(err, gc.IsNil) tests := []struct { about string path string err error expectedResponse httpbakery.Error }{{ about: `write discharge required with "an error" but no path`, path: "", err: errors.New("an error"), expectedResponse: httpbakery.Error{ Code: httpbakery.ErrDischargeRequired, Message: "an error", Info: &httpbakery.ErrorInfo{ Macaroon: m, }, }, }, { about: `write discharge required with "an error" but and set a path`, path: "http://foobar:1234", err: errors.New("an error"), expectedResponse: httpbakery.Error{ Code: httpbakery.ErrDischargeRequired, Message: "an error", Info: &httpbakery.ErrorInfo{ Macaroon: m, MacaroonPath: "http://foobar:1234", }, }, }, { about: `write discharge required with nil error but set a path`, path: "http://foobar:1234", err: nil, expectedResponse: httpbakery.Error{ Code: httpbakery.ErrDischargeRequired, Message: httpbakery.ErrDischargeRequired.Error(), Info: &httpbakery.ErrorInfo{ Macaroon: m, MacaroonPath: "http://foobar:1234", }, }, }, } for i, t := range tests { c.Logf("Running test %d %s", i, t.about) response := httptest.NewRecorder() httpbakery.WriteDischargeRequiredError(response, m, t.path, t.err) httptesting.AssertJSONResponse(c, response, http.StatusProxyAuthRequired, t.expectedResponse) } }