Пример #1
0
// targetService implements a "target service", representing
// an arbitrary web service that wants to delegate authorization
// to third parties.
func targetService(endpoint, authEndpoint string, authPK *bakery.PublicKey) (http.Handler, error) {
	key, err := bakery.GenerateKey()
	if err != nil {
		return nil, err
	}
	pkLocator := bakery.NewPublicKeyRing()
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Key:      key,
		Location: endpoint,
		Locator:  pkLocator,
	})
	if err != nil {
		return nil, err
	}
	log.Printf("adding public key for location %s: %v", authEndpoint, authPK)
	pkLocator.AddPublicKeyForLocation(authEndpoint, true, authPK)
	mux := http.NewServeMux()
	srv := &targetServiceHandler{
		svc:          svc,
		authEndpoint: authEndpoint,
	}
	mux.HandleFunc("/gold/", srv.serveGold)
	mux.HandleFunc("/silver/", srv.serveSilver)
	return mux, nil
}
Пример #2
0
func (s *suite) TestLoginDischargerError(c *gc.C) {
	var d *bakerytest.InteractiveDischarger
	d = bakerytest.NewInteractiveDischarger(nil, http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			d.FinishInteraction(w, r, nil, errors.New("test error"))
		},
	))
	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)
	client := httpbakery.NewClient()
	client.VisitWebPage = func(u *url.URL) error {
		c.Logf("visiting %s", u)
		var c httprequest.Client
		return c.Get(u.String(), nil)
	}
	_, err = client.DischargeAll(m)
	c.Assert(err, gc.ErrorMatches, `cannot get discharge from ".*": failed to acquire macaroon after waiting: third party refused discharge: test error`)
}
Пример #3
0
func (s *formSuite) TestFormTitle(c *gc.C) {
	d := &formDischarger{}
	d.discharger = bakerytest.NewInteractiveDischarger(nil, http.HandlerFunc(d.login))
	defer d.discharger.Close()
	d.discharger.Mux.Handle("/form", http.HandlerFunc(d.form))
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Locator: testLocator{
			loc:     d.discharger.Location(),
			locator: d.discharger,
		},
	})
	c.Assert(err, gc.IsNil)
	for i, test := range formTitleTests {
		c.Logf("%d. %s", i, test.host)
		m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{
			Location:  "https://" + test.host,
			Condition: "test condition",
		}})
		c.Assert(err, gc.Equals, nil)
		client := httpbakery.NewClient()
		client.Client.Transport = httptesting.URLRewritingTransport{
			MatchPrefix:  "https://" + test.host,
			Replace:      d.discharger.Location(),
			RoundTripper: http.DefaultTransport,
		}
		f := new(titleTestFiller)
		form.SetUpAuth(client, f)

		ms, err := client.DischargeAll(m)
		c.Assert(err, gc.IsNil)
		c.Assert(len(ms), gc.Equals, 2)
		c.Assert(f.title, gc.Equals, test.expect)
	}
}
Пример #4
0
func (s *formSuite) TestFormLogin(c *gc.C) {
	d := &formDischarger{}
	d.discharger = bakerytest.NewInteractiveDischarger(nil, http.HandlerFunc(d.login))
	defer d.discharger.Close()
	d.discharger.Mux.Handle("/form", http.HandlerFunc(d.form))
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Locator: d.discharger,
	})
	c.Assert(err, gc.IsNil)
	for i, test := range formLoginTests {
		c.Logf("%d. %s", i, test.about)
		d.dischargeOptions = test.opts
		m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{
			Location:  d.discharger.Location(),
			Condition: "test condition",
		}})
		c.Assert(err, gc.Equals, nil)
		client := httpbakery.NewClient()
		h := defaultFiller
		if test.filler != nil {
			h = test.filler
		}
		client.VisitWebPage = test.fallback
		form.SetUpAuth(client, h)

		ms, err := client.DischargeAll(m)
		if test.expectError != "" {
			c.Assert(err, gc.ErrorMatches, test.expectError)
			continue
		}
		c.Assert(err, gc.IsNil)
		c.Assert(len(ms), gc.Equals, 2)
	}
}
Пример #5
0
// NewDischarger returns a new third party caveat discharger
// which uses the given function to check caveats.
// The cond and arg arguments to the function are as returned
// by checkers.ParseCaveat.
//
// If locator is non-nil, it will be used to find public keys
// for any third party caveats returned by the checker.
//
// Calling this function has the side-effect of setting
// InsecureSkipVerify in http.DefaultTransport.TLSClientConfig
// until all the dischargers are closed.
func NewDischarger(
	locator bakery.PublicKeyLocator,
	checker func(req *http.Request, cond, arg string) ([]checkers.Caveat, error),
) *Discharger {
	mux := http.NewServeMux()
	server := httptest.NewTLSServer(mux)
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: server.URL,
		Locator:  locator,
	})
	if err != nil {
		panic(err)
	}
	checker1 := func(req *http.Request, cavId, cav string) ([]checkers.Caveat, error) {
		cond, arg, err := checkers.ParseCaveat(cav)
		if err != nil {
			return nil, err
		}
		return checker(req, cond, arg)
	}
	httpbakery.AddDischargeHandler(mux, "/", svc, checker1)
	startSkipVerify()
	return &Discharger{
		Service: svc,
		server:  server,
	}
}
Пример #6
0
func (s *suite) TestInteractiveDischargerURL(c *gc.C) {
	var d *bakerytest.InteractiveDischarger
	d = bakerytest.NewInteractiveDischarger(nil, http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			http.Redirect(w, r, d.URL("/redirect", r), http.StatusFound)
		},
	))
	defer d.Close()
	d.Mux.Handle("/redirect", http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			d.FinishInteraction(w, r, nil, nil)
		},
	))
	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)
	client := httpbakery.NewClient()
	client.VisitWebPage = func(u *url.URL) error {
		var c httprequest.Client
		return c.Get(u.String(), nil)
	}
	ms, err := client.DischargeAll(m)
	c.Assert(err, gc.IsNil)
	c.Assert(ms, gc.HasLen, 2)

	err = svc.Check(ms, failChecker)
	c.Assert(err, gc.IsNil)
}
Пример #7
0
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"
	]
}
`)
}
Пример #8
0
func newService(location string, locator bakery.PublicKeyLocator) *bakery.Service {
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: location,
		Locator:  locator,
	})
	if err != nil {
		panic(err)
	}
	return svc
}
Пример #9
0
func (s *agentSuite) SetUpSuite(c *gc.C) {
	key, err := bakery.GenerateKey()
	c.Assert(err, gc.IsNil)
	s.dischargeKey = &key.Public
	c.Assert(err, gc.IsNil)
	bak, err := bakery.NewService(bakery.NewServiceParams{
		Key: key,
	})
	c.Assert(err, gc.IsNil)
	s.discharger = &Discharger{
		Bakery: bak,
	}
	s.server = s.discharger.Serve()
	s.bakery, err = bakery.NewService(bakery.NewServiceParams{
		Locator: bakery.PublicKeyLocatorMap{
			s.discharger.URL: &key.Public,
		},
	})
}
Пример #10
0
func (ctx condContext) addThirdPartyCaveat(m *macaroon.Macaroon, location, condition string) error {
	agent, err := bakery.NewService(bakery.NewServiceParams{
		// TODO: persistent key pair for client
		Locator: ctx,
	})
	if err != nil {
		return err
	}
	return agent.AddCaveat(m, checkers.Caveat{Location: location, Condition: condition})
}
Пример #11
0
// authService implements an authorization service,
// that can discharge third-party caveats added
// to other macaroons.
func authService(endpoint string, key *bakery.KeyPair) (http.Handler, error) {
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: endpoint,
		Key:      key,
		Locator:  bakery.NewPublicKeyRing(),
	})
	if err != nil {
		return nil, err
	}
	mux := http.NewServeMux()
	httpbakery.AddDischargeHandler(mux, "/", svc, thirdPartyChecker)
	return mux, nil
}
Пример #12
0
// ExpireStorageAt implements authentication.ExpirableStorageBakeryService.
func (s *expirableStorageBakeryService) ExpireStorageAt(t time.Time) (authentication.ExpirableStorageBakeryService, error) {
	store := s.store.ExpireAt(t)
	service, err := bakery.NewService(bakery.NewServiceParams{
		Location: s.Location(),
		Store:    store,
		Key:      s.key,
		Locator:  s.locator,
	})
	if err != nil {
		return nil, errors.Trace(err)
	}
	return &expirableStorageBakeryService{service, s.key, store, s.locator}, nil
}
Пример #13
0
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)
}
Пример #14
0
func newService(c *gc.C, location string, locator bakery.PublicKeyLocatorMap) *bakery.Service {
	keyPair, err := bakery.GenerateKey()
	c.Assert(err, gc.IsNil)

	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: location,
		Key:      keyPair,
		Locator:  locator,
	})
	c.Assert(err, gc.IsNil)
	if locator != nil {
		locator[location] = &keyPair.Public
	}
	return svc
}
Пример #15
0
func newMockAPI() (*mockapi, error) {
	kp, err := bakery.GenerateKey()
	if err != nil {
		return nil, errors.Trace(err)
	}
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: "omnibus",
		Key:      kp,
	})
	if err != nil {
		return nil, errors.Trace(err)
	}
	return &mockapi{
		service: svc,
	}, nil
}
Пример #16
0
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)
		}
	}
}
Пример #17
0
// NewService returns a new Service instance.
func NewService(config ServiceConfig) (*Service, error) {
	bakeryService, err := bakery.NewService(bakery.NewServiceParams{})
	if err != nil {
		return nil, errgo.Mask(err, errgo.Any)
	}

	s := &Service{bakery: bakeryService, prefix: config.Prefix}

	s.mux = http.NewServeMux()
	httpbakery.AddDischargeHandler(s.mux, config.Prefix+"/discharger", s.bakery, s.checker)
	r := httprouter.New()
	r.GET(config.Prefix+"/wait/:election", s.wait)
	r.GET(config.Prefix+"/approve/:ballot", s.approve)
	r.GET(config.Prefix+"/deny/:ballot", s.deny)
	s.mux.Handle("/", r)
	return s, nil
}
Пример #18
0
func (s *ServiceSuite) TestNewMacaroonWithRootKeyStorage(c *gc.C) {
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: "somewhere",
	})
	c.Assert(err, gc.IsNil)

	store := bakery.NewMemRootKeyStorage()
	key, id, err := store.RootKey()
	c.Assert(err, gc.IsNil)

	svc = svc.WithRootKeyStore(store)

	m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{
		Location:  "",
		Condition: "something",
	}})
	c.Assert(err, gc.IsNil)
	c.Assert(m.Location(), gc.Equals, "somewhere")
	id1 := m.Id()
	c.Assert(id1, gc.Matches, id+"-[0-9a-f]{32}")

	err = svc.Check(macaroon.Slice{m}, strcmpChecker("something"))
	c.Assert(err, gc.IsNil)

	// Check that it's really using the root key returned from
	// the store.
	err = m.Verify(key, func(string) error {
		return nil
	}, nil)
	c.Assert(err, gc.IsNil)

	// Create another one and check that it re-uses the
	// same key but has a different id.
	m, err = svc.NewMacaroon("", nil, []checkers.Caveat{{
		Location:  "",
		Condition: "something",
	}})
	c.Assert(err, gc.IsNil)
	c.Assert(m.Location(), gc.Equals, "somewhere")
	id2 := m.Id()
	c.Assert(id2, gc.Matches, id+"-[0-9a-f]{32}")
	c.Assert(id2, gc.Not(gc.Equals), id1)
	err = m.Verify(key, func(string) error { return nil }, nil)
	c.Assert(err, gc.IsNil)
}
Пример #19
0
func (*DischargeSuite) TestDischargeAllLocalDischarge(c *gc.C) {
	svc, err := bakery.NewService(bakery.NewServiceParams{})
	c.Assert(err, gc.IsNil)

	clientKey, err := bakery.GenerateKey()
	c.Assert(err, gc.IsNil)

	m, err := svc.NewMacaroon("", nil, []checkers.Caveat{
		bakery.LocalThirdPartyCaveat(&clientKey.Public),
	})
	c.Assert(err, gc.IsNil)

	ms, err := bakery.DischargeAllWithKey(m, noDischarge(c), clientKey)
	c.Assert(err, gc.IsNil)

	err = svc.Check(ms, checkers.New())
	c.Assert(err, gc.IsNil)
}
Пример #20
0
func (s *ServiceSuite) TestNewMacaroonWithExplicitIdAndRootKeyStorage(c *gc.C) {
	store := bakery.NewMemRootKeyStorage()

	// Check that we can create a bakery with the root key store
	// in its parameters too.
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location:     "somewhere",
		RootKeyStore: store,
	})
	c.Assert(err, gc.IsNil)

	m, err := svc.NewMacaroon("someid", nil, nil)
	c.Assert(err, gc.ErrorMatches, `cannot choose root key or id when using RootKeyStore`)
	c.Assert(m, gc.IsNil)

	m, err = svc.NewMacaroon("", []byte{1}, nil)
	c.Assert(err, gc.ErrorMatches, `cannot choose root key or id when using RootKeyStore`)
	c.Assert(m, gc.IsNil)
}
Пример #21
0
func (ctx newContext) addThirdPartyCaveat(m *macaroon.Macaroon, env *envelope) error {
	condition, err := env.MarshalJSON()
	if err != nil {
		return err
	}
	mgr := keyManager{ctx.Context}
	kp, err := mgr.keyPair()
	if err != nil {
		return err
	}
	agent, err := bakery.NewService(bakery.NewServiceParams{
		Key:     kp.KeyPair,
		Locator: clientLocator{ctx.Context, kp},
	})
	if err != nil {
		return err
	}
	return agent.AddCaveat(m, checkers.Caveat{Location: "client:encrypt", Condition: string(condition)})
}
Пример #22
0
// New returns a new handler that services an identity-providing
// service. This acts as a login service and can discharge third-party caveats
// for users.
func New(p Params) (http.Handler, error) {
	svc, err := bakery.NewService(p.Service)
	if err != nil {
		return nil, err
	}
	h := &handler{
		svc:   svc,
		users: p.Users,
		place: &place{meeting.New()},
	}
	mux := http.NewServeMux()
	httpbakery.AddDischargeHandler(mux, "/", svc, h.checkThirdPartyCaveat)
	mux.Handle("/user/", mkHandler(handleJSON(h.userHandler)))
	mux.HandleFunc("/login", h.loginHandler)
	mux.Handle("/question", mkHandler(handleJSON(h.questionHandler)))
	mux.Handle("/wait", mkHandler(handleJSON(h.waitHandler)))
	mux.HandleFunc("/loginattempt", h.loginAttemptHandler)
	return mux, nil
}
Пример #23
0
func (s *BakeryStorageSuite) initService(c *gc.C, enableExpiry bool) {
	store, err := bakerystorage.New(bakerystorage.Config{
		GetCollection: func() (mongo.Collection, func()) {
			return mongo.CollectionFromName(s.db, s.coll.Name)
		},
	})
	c.Assert(err, jc.ErrorIsNil)
	if enableExpiry {
		store = store.ExpireAt(time.Now())
	}
	s.store = store

	service, err := bakery.NewService(bakery.NewServiceParams{
		Location: "straya",
		Store:    s.store,
	})
	c.Assert(err, jc.ErrorIsNil)
	s.service = service
}
Пример #24
0
// newBakeryService creates a new bakery.Service.
func newBakeryService(
	st *state.State,
	store bakerystorage.ExpirableStorage,
	locator bakery.PublicKeyLocator,
) (*bakery.Service, *bakery.KeyPair, error) {
	key, err := bakery.GenerateKey()
	if err != nil {
		return nil, nil, errors.Annotate(err, "generating key for bakery service")
	}
	service, err := bakery.NewService(bakery.NewServiceParams{
		Location: "juju model " + st.ModelUUID(),
		Store:    store,
		Key:      key,
		Locator:  locator,
	})
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	return service, key, nil
}
Пример #25
0
func (s *ServiceSuite) TestNewMacaroonWithRootKeyStorageInParams(c *gc.C) {
	store := bakery.NewMemRootKeyStorage()
	_, id, err := store.RootKey()
	c.Assert(err, gc.IsNil)

	// Check that we can create a bakery with the root key store
	// in its parameters too.
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location:     "elsewhere",
		RootKeyStore: store,
	})
	c.Assert(err, gc.IsNil)

	m, err := svc.NewMacaroon("", nil, nil)
	c.Assert(err, gc.IsNil)
	c.Assert(m.Id(), gc.Matches, id+"-[0-9a-f]{32}")

	err = svc.Check(macaroon.Slice{m}, checkers.New())
	c.Assert(err, gc.IsNil)
}
Пример #26
0
func (s *formSuite) TestFormLogin(c *gc.C) {
	d := &formDischarger{}
	d.discharger = bakerytest.NewInteractiveDischarger(nil, http.HandlerFunc(d.visit))
	defer d.discharger.Close()
	d.discharger.Mux.Handle("/form", http.HandlerFunc(d.form))
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Locator: d.discharger,
	})
	c.Assert(err, gc.IsNil)
	for i, test := range formLoginTests {
		c.Logf("test %d: %s", i, test.about)
		d.dischargeOptions = test.opts
		m, err := svc.NewMacaroon("", nil, []checkers.Caveat{{
			Location:  d.discharger.Location(),
			Condition: "test condition",
		}})
		c.Assert(err, gc.Equals, nil)
		client := httpbakery.NewClient()
		filler := defaultFiller
		if test.filler != nil {
			filler = test.filler
		}
		handlers := []httpbakery.Visitor{
			form.Visitor{
				Filler: filler,
			},
		}
		if test.fallback != nil {
			handlers = append(handlers, test.fallback)
		}
		client.WebPageVisitor = httpbakery.NewMultiVisitor(handlers...)

		ms, err := client.DischargeAll(m)
		if test.expectError != "" {
			c.Assert(err, gc.ErrorMatches, test.expectError)
			continue
		}
		c.Assert(err, gc.IsNil)
		c.Assert(len(ms), gc.Equals, 2)
	}
}
Пример #27
0
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)
}
Пример #28
0
// NewService creates a new opaque object storage service.
func NewService(config ServiceConfig) (*Service, error) {
	bakeryService, err := bakery.NewService(bakery.NewServiceParams{
		Store: config.BakeryStore,
	})
	if err != nil {
		return nil, err
	}
	s := &Service{
		bakery: bakeryService,
		store:  config.ObjectStore,
	}

	prefix := "/"
	if config.Prefix != "" {
		prefix = config.Prefix
	}
	s.router = httprouter.New()
	s.router.POST(prefix, s.create)
	s.router.POST(path.Join(prefix, ":object"), s.fetch)
	s.router.DELETE(path.Join(prefix, ":object"), s.del)
	return s, nil
}
Пример #29
0
// newMacaroonAuth returns an authenticator that can authenticate
// macaroon-based logins. This is just a helper function for authCtxt.macaroonAuth.
func newMacaroonAuth(st *state.State) (*authentication.MacaroonAuthenticator, error) {
	envCfg, err := st.EnvironConfig()
	if err != nil {
		return nil, errors.Annotate(err, "cannot get environment config")
	}
	idURL := envCfg.IdentityURL()
	if idURL == "" {
		return nil, errMacaroonAuthNotConfigured
	}
	// The identity server has been configured,
	// so configure the bakery service appropriately.
	idPK := envCfg.IdentityPublicKey()
	if idPK == nil {
		// No public key supplied - retrieve it from the identity manager.
		idPK, err = httpbakery.PublicKeyForLocation(http.DefaultClient, idURL)
		if err != nil {
			return nil, errors.Annotate(err, "cannot get identity public key")
		}
	}
	svc, err := bakery.NewService(
		bakery.NewServiceParams{
			Location: "juju environment " + st.EnvironUUID(),
			Locator: bakery.PublicKeyLocatorMap{
				idURL: idPK,
			},
		},
	)
	if err != nil {
		return nil, errors.Annotate(err, "cannot make bakery service")
	}
	var auth authentication.MacaroonAuthenticator
	auth.Service = svc
	auth.Macaroon, err = svc.NewMacaroon("api-login", nil, nil)
	if err != nil {
		return nil, errors.Annotate(err, "cannot make macaroon")
	}
	auth.IdentityLocation = idURL
	return &auth, nil
}
Пример #30
0
func (s *suite) TestInteractiveDischarger(c *gc.C) {
	var d *bakerytest.InteractiveDischarger
	d = bakerytest.NewInteractiveDischarger(nil, http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			d.FinishInteraction(w, r, []checkers.Caveat{
				checkers.Caveat{
					Condition: "test pass",
				},
			}, nil)
		},
	))
	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)
	client := httpbakery.NewClient()
	client.VisitWebPage = func(u *url.URL) error {
		var c httprequest.Client
		return c.Get(u.String(), nil)
	}
	ms, err := client.DischargeAll(m)
	c.Assert(err, gc.IsNil)
	c.Assert(ms, gc.HasLen, 2)

	var r recordingChecker
	err = svc.Check(ms, &r)
	c.Assert(err, gc.IsNil)
	c.Assert(r.caveats, gc.HasLen, 1)
	c.Assert(r.caveats[0], gc.Equals, "test pass")
}