func (s *suite) TestDischargerTwoLevels(c *gc.C) { d1checker := func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { if cond != "xtrue" { return nil, fmt.Errorf("caveat refused") } return nil, nil } d1 := bakerytest.NewDischarger(nil, d1checker) defer d1.Close() d2checker := func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { return []checkers.Caveat{{ Location: d1.Location(), Condition: "x" + cond, }}, nil } d2 := bakerytest.NewDischarger(d1, d2checker) defer d2.Close() locator := bakery.PublicKeyLocatorMap{ d1.Location(): d1.Service.PublicKey(), d2.Location(): d2.Service.PublicKey(), } c.Logf("map: %s", locator) svc, err := bakery.NewService(bakery.NewServiceParams{ Location: "here", Locator: locator, }) c.Assert(err, gc.IsNil) m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{ Location: d2.Location(), Condition: "true", }}) c.Assert(err, gc.IsNil) ms, err := s.client.DischargeAll(m) c.Assert(err, gc.IsNil) c.Assert(ms, gc.HasLen, 3) err = svc.Check(ms, failChecker) c.Assert(err, gc.IsNil) err = svc.AddCaveat(m, checkers.Caveat{ Location: d2.Location(), Condition: "nope", }) c.Assert(err, gc.IsNil) ms, err = s.client.DischargeAll(m) c.Assert(err, gc.ErrorMatches, `cannot get discharge from "https://[^"]*": third party refused discharge: cannot discharge: caveat refused`) c.Assert(ms, gc.HasLen, 0) }
func (s ClientSuite) TestWithLargeBody(c *gc.C) { // This test is designed to fail when run with the race // checker enabled and when go issue #12796 // is not fixed. d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() // Create a target service. svc := newService("loc", d) ts := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, authLocation: d.Location(), })) defer ts.Close() // Create a client request. req, err := http.NewRequest("POST", ts.URL+"/no-body", nil) c.Assert(err, gc.IsNil) body := &largeReader{total: 3 * 1024 * 1024} resp, err := httpbakery.NewClient().DoWithBody(req, body) c.Assert(err, gc.IsNil) resp.Body.Close() body.Close() c.Assert(resp.StatusCode, gc.Equals, http.StatusOK) }
func (s *ClientSuite) TestThirdPartyDischargeRefused(c *gc.C) { d := bakerytest.NewDischarger(nil, func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { return nil, errgo.New("boo! cond " + cond) }) defer d.Close() // Create a target service. svc := newService("loc", d) ts := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, authLocation: d.Location(), })) defer ts.Close() // Create a client request. req, err := http.NewRequest("GET", ts.URL, nil) c.Assert(err, gc.IsNil) client := httpbakery.NewClient() // Make the request to the server. resp, err := client.Do(req) c.Assert(errgo.Cause(err), gc.FitsTypeOf, (*httpbakery.DischargeError)(nil)) c.Assert(err, gc.ErrorMatches, `cannot get discharge from ".*": third party refused discharge: cannot discharge: boo! cond is-ok`) c.Assert(resp, gc.IsNil) }
func (s *macaroonServerSuite) SetUpTest(c *gc.C) { s.discharger = bakerytest.NewDischarger(nil, noCheck) s.ConfigAttrs = map[string]interface{}{ config.IdentityURL: s.discharger.Location(), } s.JujuConnSuite.SetUpTest(c) }
func (s *CharmStoreSuite) SetUpTest(c *gc.C) { s.CleanupSuite.SetUpTest(c) s.discharger = bakerytest.NewDischarger(nil, func(_ *http.Request, cond string, arg string) ([]checkers.Caveat, error) { if s.DischargeUser == "" { return nil, fmt.Errorf("discharge denied") } return []checkers.Caveat{ checkers.DeclaredCaveat("username", s.DischargeUser), }, nil }) db := s.Session.DB("juju-testing") params := charmstore.ServerParams{ AuthUsername: "******", AuthPassword: "******", IdentityLocation: s.discharger.Location(), PublicKeyLocator: s.discharger, } handler, err := charmstore.NewServer(db, nil, "", params, charmstore.V4) c.Assert(err, jc.ErrorIsNil) s.handler = handler s.Srv = httptest.NewServer(handler) s.Client = csclient.New(csclient.Params{ URL: s.Srv.URL, User: params.AuthUsername, Password: params.AuthPassword, }) s.PatchValue(&charmrepo.CacheDir, c.MkDir()) s.PatchValue(&service.NewCharmStore, func(p charmrepo.NewCharmStoreParams) charmrepo.Interface { p.URL = s.Srv.URL return charmrepo.NewCharmStore(p) }) }
func (s *suite) TestInsecureSkipVerifyRestoration(c *gc.C) { d1 := bakerytest.NewDischarger(nil, noCaveatChecker) d2 := bakerytest.NewDischarger(nil, noCaveatChecker) d2.Close() c.Assert(http.DefaultTransport.(*http.Transport).TLSClientConfig.InsecureSkipVerify, gc.Equals, true) d1.Close() c.Assert(http.DefaultTransport.(*http.Transport).TLSClientConfig.InsecureSkipVerify, gc.Equals, false) // When InsecureSkipVerify is already true, it should not // be restored to false. http.DefaultTransport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = true d3 := bakerytest.NewDischarger(nil, noCaveatChecker) d3.Close() c.Assert(http.DefaultTransport.(*http.Transport).TLSClientConfig.InsecureSkipVerify, gc.Equals, true) }
func (s *charmStoreSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) // Set up the third party discharger. s.discharger = bakerytest.NewDischarger(nil, func(req *http.Request, cond string, arg string) ([]checkers.Caveat, error) { cookie, err := req.Cookie(clientUserCookie) if err != nil { return nil, errors.Annotate(err, "discharge denied to non-clients") } return []checkers.Caveat{ checkers.DeclaredCaveat("username", cookie.Value), }, nil }) // Set up the charm store testing server. db := s.Session.DB("juju-testing") params := charmstore.ServerParams{ AuthUsername: "******", AuthPassword: "******", IdentityLocation: s.discharger.Location(), PublicKeyLocator: s.discharger, } handler, err := charmstore.NewServer(db, nil, "", params, charmstore.V4) c.Assert(err, jc.ErrorIsNil) s.handler = handler s.srv = httptest.NewServer(handler) s.client = csclient.New(csclient.Params{ URL: s.srv.URL, User: params.AuthUsername, Password: params.AuthPassword, }) // Initialize the charm cache dir. s.PatchValue(&charmrepo.CacheDir, c.MkDir()) // Point the CLI to the charm store testing server. original := newCharmStoreClient s.PatchValue(&newCharmStoreClient, func() (*csClient, error) { csclient, err := original() if err != nil { return nil, err } csclient.params.URL = s.srv.URL // Add a cookie so that the discharger can detect whether the // HTTP client is the juju environment or the juju client. lurl, err := url.Parse(s.discharger.Location()) if err != nil { panic(err) } csclient.params.HTTPClient.Jar.SetCookies(lurl, []*http.Cookie{{ Name: clientUserCookie, Value: clientUserName, }}) return csclient, nil }) // Point the Juju API server to the charm store testing server. s.PatchValue(&csclient.ServerURL, s.srv.URL) }
func (s *ClientSuite) TestDoWithBodyAndCustomError(c *gc.C) { d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() // Create a target service. svc := newService("loc", d) type customError struct { CustomError *httpbakery.Error } callCount := 0 handler := func(w http.ResponseWriter, req *http.Request) { callCount++ if _, checkErr := httpbakery.CheckRequest(svc, req, nil, checkers.New()); checkErr != nil { httprequest.WriteJSON(w, http.StatusTeapot, customError{ CustomError: newDischargeRequiredError(svc, d.Location(), nil, checkErr, req).(*httpbakery.Error), }) return } fmt.Fprintf(w, "hello there") } srv := httptest.NewServer(http.HandlerFunc(handler)) defer srv.Close() req, err := http.NewRequest("GET", srv.URL, nil) c.Assert(err, gc.IsNil) // First check that a normal request fails. resp, err := httpbakery.NewClient().Do(req) c.Assert(err, gc.IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, gc.Equals, http.StatusTeapot) c.Assert(callCount, gc.Equals, 1) callCount = 0 // Then check that a request with a custom error getter succeeds. errorGetter := func(resp *http.Response) error { if resp.StatusCode != http.StatusTeapot { return nil } data, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } var respErr customError if err := json.Unmarshal(data, &respErr); err != nil { panic(err) } return respErr.CustomError } resp, err = httpbakery.NewClient().DoWithBodyAndCustomError(req, nil, errorGetter) c.Assert(err, gc.IsNil) data, err := ioutil.ReadAll(resp.Body) c.Assert(err, gc.IsNil) c.Assert(string(data), gc.Equals, "hello there") c.Assert(callCount, gc.Equals, 2) }
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 *macaroonServerWrongPublicKeySuite) SetUpTest(c *gc.C) { s.discharger = bakerytest.NewDischarger(nil, noCheck) wrongKey, err := bakery.GenerateKey() c.Assert(err, gc.IsNil) s.ConfigAttrs = map[string]interface{}{ config.IdentityURL: s.discharger.Location(), config.IdentityPublicKey: wrongKey.Public.String(), } s.JujuConnSuite.SetUpTest(c) }
func (s *ClientSuite) TestHandleError(c *gc.C) { d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() // Create a target service. svc := newService("loc", d) srv := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, authLocation: "unknown", mutateError: nil, })) defer srv.Close() m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{ Location: d.Location(), Condition: "something", }}) c.Assert(err, gc.IsNil) u, err := url.Parse(srv.URL + "/bar") c.Assert(err, gc.IsNil) respErr := &httpbakery.Error{ Message: "an error", Code: httpbakery.ErrDischargeRequired, Info: &httpbakery.ErrorInfo{ Macaroon: m, MacaroonPath: "/foo", }, } client := httpbakery.NewClient() err = client.HandleError(u, respErr) c.Assert(err, gc.Equals, nil) // No cookies at the original location. c.Assert(client.Client.Jar.Cookies(u), gc.HasLen, 0) u.Path = "/foo" cookies := client.Client.Jar.Cookies(u) c.Assert(cookies, gc.HasLen, 1) // Check that we can actually make a request // with the newly acquired macaroon cookies. req, err := http.NewRequest("GET", srv.URL+"/foo", nil) c.Assert(err, gc.IsNil) resp, err := client.Do(req) c.Assert(err, gc.IsNil) resp.Body.Close() c.Assert(resp.StatusCode, gc.Equals, http.StatusOK) }
func (s *suite) TestConcurrentDischargers(c *gc.C) { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { d := bakerytest.NewDischarger(nil, noCaveatChecker) d.Close() wg.Done() }() } wg.Wait() c.Assert(http.DefaultTransport.(*http.Transport).TLSClientConfig.InsecureSkipVerify, gc.Equals, false) }
func (s *KeyringSuite) TestPublicKey(c *gc.C) { d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() client := httpbakery.NewHTTPClient() publicKey, err := httpbakery.PublicKeyForLocation(client, d.Location()) c.Assert(err, gc.IsNil) expectedKey := d.Service.PublicKey() c.Assert(publicKey, gc.DeepEquals, expectedKey) // Check that it works with client==nil. publicKey, err = httpbakery.PublicKeyForLocation(nil, d.Location()) c.Assert(err, gc.IsNil) c.Assert(publicKey, gc.DeepEquals, expectedKey) }
func (s *ClientSuite) TestDischargeWithVisitURLError(c *gc.C) { visitor := newVisitHandler(nil) visitSrv := httptest.NewServer(visitor) defer visitSrv.Close() d := bakerytest.NewDischarger(nil, func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { return nil, &httpbakery.Error{ Code: httpbakery.ErrInteractionRequired, Message: "interaction required", Info: &httpbakery.ErrorInfo{ VisitURL: visitSrv.URL + "/visit", WaitURL: visitSrv.URL + "/wait", }, } }) defer d.Close() // Create a target service. svc := newService("loc", d) ts := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, authLocation: d.Location(), })) defer ts.Close() for i, test := range dischargeWithVisitURLErrorTests { c.Logf("test %d: %s", i, test.about) visitor.respond = test.respond client := httpbakery.NewClient() client.VisitWebPage = func(u *url.URL) error { resp, err := http.Get(u.String()) if err != nil { return err } resp.Body.Close() return nil } // Create a client request. req, err := http.NewRequest("GET", ts.URL, nil) c.Assert(err, gc.IsNil) // Make the request to the server. _, err = client.Do(req) c.Assert(err, gc.ErrorMatches, test.expectError) } }
func (s *macaroonAuthenticatorSuite) TestMacaroonAuthentication(c *gc.C) { discharger := bakerytest.NewDischarger(nil, s.Checker) defer discharger.Close() for i, test := range authenticateSuccessTests { c.Logf("\ntest %d; %s", i, test.about) s.username = test.dischargedUsername svc, err := bakery.NewService(bakery.NewServiceParams{ Locator: discharger, }) c.Assert(err, jc.ErrorIsNil) mac, err := svc.NewMacaroon("", nil, nil) c.Assert(err, jc.ErrorIsNil) authenticator := &authentication.ExternalMacaroonAuthenticator{ Service: svc, IdentityLocation: discharger.Location(), Macaroon: mac, } // Authenticate once to obtain the macaroon to be discharged. _, err = authenticator.Authenticate(test.finder, nil, params.LoginRequest{ Credentials: "", Nonce: "", Macaroons: nil, }) // Discharge the macaroon. dischargeErr := errors.Cause(err).(*common.DischargeRequiredError) client := httpbakery.NewClient() ms, err := client.DischargeAll(dischargeErr.Macaroon) c.Assert(err, jc.ErrorIsNil) // Authenticate again with the discharged macaroon. entity, err := authenticator.Authenticate(test.finder, nil, params.LoginRequest{ Credentials: "", Nonce: "", Macaroons: []macaroon.Slice{ms}, }) if test.expectError != "" { c.Assert(err, gc.ErrorMatches, test.expectError) c.Assert(entity, gc.Equals, nil) } else { c.Assert(err, jc.ErrorIsNil) c.Assert(entity.Tag().String(), gc.Equals, test.expectTag) } } }
func (s *KeyringSuite) TestCacheMiss(c *gc.C) { d := bakerytest.NewDischarger(nil, nil) defer d.Close() kr := httpbakery.NewPublicKeyRing(nil, nil) expectPublicKey := d.Service.PublicKey() pk, err := kr.PublicKeyForLocation(d.Location()) c.Assert(err, gc.IsNil) c.Assert(*pk, gc.Equals, *expectPublicKey) // Close down the service and make sure that // the key is cached. d.Close() pk, err = kr.PublicKeyForLocation(d.Location()) c.Assert(err, gc.IsNil) c.Assert(*pk, gc.Equals, *expectPublicKey) }
func (s *ClientSuite) TestRepeatedRequestWithBody(c *gc.C) { d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() // Create a target service. svc := newService("loc", d) ts := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, authLocation: d.Location(), alwaysReadBody: true, })) defer ts.Close() // Create a client request. req, err := http.NewRequest("POST", ts.URL, nil) c.Assert(err, gc.IsNil) // Make the request to the server. // First try with a body in the request, which should be denied // because we must use DoWithBody. req.Body = ioutil.NopCloser(strings.NewReader("postbody")) resp, err := httpbakery.NewClient().Do(req) c.Assert(err, gc.ErrorMatches, "body unexpectedly provided in request - use DoWithBody") c.Assert(resp, gc.IsNil) // Then try with no authorization, so make sure that httpbakery.Do // really will retry the request. req.Body = nil bodyText := "postbody" bodyReader := &readCounter{ReadSeeker: strings.NewReader(bodyText)} resp, err = httpbakery.NewClient().DoWithBody(req, bodyReader) c.Assert(err, gc.IsNil) defer resp.Body.Close() assertResponse(c, resp, "done postbody") // Sanity check that the body really was read twice and hence // that we are checking the logic we intend to check. c.Assert(bodyReader.byteCount, gc.Equals, len(bodyText)*2) }
func (s *MacaroonSuite) SetUpTest(c *gc.C) { s.discharger = bakerytest.NewDischarger(nil, func(req *http.Request, cond, arg string) ([]checkers.Caveat, error) { if cond != "is-authenticated-user" { return nil, errors.New("unknown caveat") } var username string if s.DischargerLogin != nil { username = s.DischargerLogin() } if username == "" { return nil, errors.New("login denied by discharger") } return []checkers.Caveat{checkers.DeclaredCaveat("username", username)}, nil }) s.JujuConnSuite.ConfigAttrs = map[string]interface{}{ config.IdentityURL: s.discharger.Location(), } s.JujuConnSuite.SetUpTest(c) }
func (s *ClientSuite) TestDischargeWithInteractionRequiredErrorAndWebPageVisitor(c *gc.C) { d := bakerytest.NewDischarger(nil, func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { return nil, &httpbakery.Error{ Code: httpbakery.ErrInteractionRequired, Message: "interaction required", Info: &httpbakery.ErrorInfo{ VisitURL: "http://0.1.2.3/", WaitURL: "http://0.1.2.3/", }, } }) defer d.Close() // Create a target service. svc := newService("loc", d) ts := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, authLocation: d.Location(), })) defer ts.Close() // Create a client request. req, err := http.NewRequest("GET", ts.URL, nil) c.Assert(err, gc.IsNil) errCannotVisit := errgo.New("cannot visit") client := httpbakery.NewClient() client.WebPageVisitor = visitorFunc(func(_ *httpbakery.Client, m map[string]*url.URL) error { return errCannotVisit }) // Make the request to the server. resp, err := client.Do(req) c.Assert(err, gc.ErrorMatches, `cannot get discharge from "https://.*": cannot start interactive session: cannot visit`) c.Assert(httpbakery.IsInteractionError(errgo.Cause(err)), gc.Equals, true) ierr, ok := errgo.Cause(err).(*httpbakery.InteractionError) c.Assert(ok, gc.Equals, true) c.Assert(ierr.Reason, gc.Equals, errCannotVisit) c.Assert(resp, gc.IsNil) }
func (s *suite) TestDischargerSimple(c *gc.C) { d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() svc, err := bakery.NewService(bakery.NewServiceParams{ Location: "here", Locator: d, }) c.Assert(err, gc.IsNil) m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{ Location: d.Location(), Condition: "something", }}) c.Assert(err, gc.IsNil) ms, err := s.client.DischargeAll(m) c.Assert(err, gc.IsNil) c.Assert(ms, gc.HasLen, 2) err = svc.Check(ms, failChecker) c.Assert(err, gc.IsNil) }
func (s *KeyringSuite) TestInsecureURL(c *gc.C) { // Set up a discharger with an non-HTTPS access point. d := bakerytest.NewDischarger(nil, nil) defer d.Close() httpsDischargeURL, err := url.Parse(d.Location()) c.Assert(err, gc.IsNil) srv := httptest.NewServer(httputil.NewSingleHostReverseProxy(httpsDischargeURL)) defer srv.Close() // Check that we are refused because it's an insecure URL. kr := httpbakery.NewPublicKeyRing(nil, nil) pk, err := kr.PublicKeyForLocation(srv.URL) c.Assert(err, gc.ErrorMatches, `untrusted discharge URL "http://.*"`) c.Assert(pk, gc.IsNil) // Check that it does work when we've enabled AllowInsecure. kr.AllowInsecure() pk, err = kr.PublicKeyForLocation(srv.URL) c.Assert(err, gc.IsNil) c.Assert(*pk, gc.Equals, *d.Service.PublicKey()) }
func (s *suite) startServer(c *gc.C, session *mgo.Session) { s.discharge = func(cond, arg string) ([]checkers.Caveat, error) { return nil, fmt.Errorf("no discharge") } discharger := bakerytest.NewDischarger(nil, func(_ *http.Request, cond, arg string) ([]checkers.Caveat, error) { return s.discharge(cond, arg) }) serverParams := charmstore.ServerParams{ AuthUsername: "******", AuthPassword: "******", IdentityLocation: discharger.Service.Location(), PublicKeyLocator: discharger, } db := session.DB("charmstore") handler, err := charmstore.NewServer(db, nil, "", serverParams, charmstore.V4) c.Assert(err, gc.IsNil) s.handler = handler s.srv = httptest.NewServer(handler) s.serverParams = serverParams }
func (s *ClientSuite) TestMacaroonCookieName(c *gc.C) { d := bakerytest.NewDischarger(nil, noCaveatChecker) defer d.Close() svc := newService("loc", nil) // We arrange things so that although we use the same client // (with the same cookie jar), the macaroon verification only // succeeds once, so the client always fetches a new macaroon. caveatSeq := 0 checked := make(map[string]bool) cookieName := "" ts := httptest.NewServer(serverHandler(serverHandlerParams{ service: svc, mutateError: func(e *httpbakery.Error) { e.Info.CookieNameSuffix = cookieName e.Info.MacaroonPath = "/" }, checker: checkers.CheckerFunc{ Condition_: "once", Check_: func(_, arg string) error { if checked[arg] { return errgo.Newf("caveat %q has already been checked once", arg) } checked[arg] = true return nil }, }, caveats: func() []checkers.Caveat { caveatSeq++ return []checkers.Caveat{{ Condition: fmt.Sprintf("once %d", caveatSeq), }} }, })) defer ts.Close() client := httpbakery.NewClient() doRequest := func() { req, err := http.NewRequest("GET", ts.URL+"/foo/bar/", nil) c.Assert(err, gc.IsNil) resp, err := client.Do(req) c.Assert(err, gc.IsNil) defer resp.Body.Close() assertResponse(c, resp, "done") } assertCookieNames := func(names ...string) { u, err := url.Parse(ts.URL) c.Assert(err, gc.IsNil) sort.Strings(names) var gotNames []string for _, c := range client.Jar.Cookies(u) { gotNames = append(gotNames, c.Name) } sort.Strings(gotNames) c.Assert(gotNames, jc.DeepEquals, names) } cookieName = "foo" doRequest() assertCookieNames("macaroon-foo") // Another request with the same cookie name should // overwrite the old cookie. doRequest() assertCookieNames("macaroon-foo") // A subsequent request with a different cookie name // should create a new cookie, but the old one will still // be around. cookieName = "bar" doRequest() assertCookieNames("macaroon-foo", "macaroon-bar") }
func (s *charmStoreSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) // Set up the third party discharger. s.discharger = bakerytest.NewDischarger(nil, func(req *http.Request, cond string, arg string) ([]checkers.Caveat, error) { cookie, err := req.Cookie(clientUserCookie) if err != nil { return nil, errors.Annotate(err, "discharge denied to non-clients") } return []checkers.Caveat{ checkers.DeclaredCaveat("username", cookie.Value), }, nil }) s.termsDischargerError = nil // Set up the third party terms discharger. s.termsDischarger = bakerytest.NewDischarger(nil, func(req *http.Request, cond string, arg string) ([]checkers.Caveat, error) { s.termsString = arg return nil, s.termsDischargerError }) s.termsString = "" keyring := bakery.NewPublicKeyRing() pk, err := httpbakery.PublicKeyForLocation(http.DefaultClient, s.discharger.Location()) c.Assert(err, gc.IsNil) err = keyring.AddPublicKeyForLocation(s.discharger.Location(), true, pk) c.Assert(err, gc.IsNil) pk, err = httpbakery.PublicKeyForLocation(http.DefaultClient, s.termsDischarger.Location()) c.Assert(err, gc.IsNil) err = keyring.AddPublicKeyForLocation(s.termsDischarger.Location(), true, pk) c.Assert(err, gc.IsNil) // Set up the charm store testing server. db := s.Session.DB("juju-testing") params := charmstore.ServerParams{ AuthUsername: "******", AuthPassword: "******", IdentityLocation: s.discharger.Location(), PublicKeyLocator: keyring, TermsLocation: s.termsDischarger.Location(), } handler, err := charmstore.NewServer(db, nil, "", params, charmstore.V5) c.Assert(err, jc.ErrorIsNil) s.handler = handler s.srv = httptest.NewServer(handler) c.Logf("started charmstore on %v", s.srv.URL) s.client = csclient.New(csclient.Params{ URL: s.srv.URL, User: params.AuthUsername, Password: params.AuthPassword, }) // Initialize the charm cache dir. s.PatchValue(&charmrepo.CacheDir, c.MkDir()) // Point the CLI to the charm store testing server. s.PatchValue(&newCharmStoreClient, func(client *httpbakery.Client) *csclient.Client { // Add a cookie so that the discharger can detect whether the // HTTP client is the juju environment or the juju client. lurl, err := url.Parse(s.discharger.Location()) c.Assert(err, jc.ErrorIsNil) client.Jar.SetCookies(lurl, []*http.Cookie{{ Name: clientUserCookie, Value: clientUserName, }}) return csclient.New(csclient.Params{ URL: s.srv.URL, BakeryClient: client, }) }) // Point the Juju API server to the charm store testing server. s.PatchValue(&csclient.ServerURL, s.srv.URL) }
func (s *macaroonAuthenticatorSuite) SetUpTest(c *gc.C) { s.discharger = bakerytest.NewDischarger(nil, s.Checker) }