示例#1
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,
	}
}
示例#2
0
func (d *Discharger) ServeMux() *http.ServeMux {
	mux := http.NewServeMux()
	httpbakery.AddDischargeHandler(mux, "/", d.Bakery, d.checker)
	mux.Handle("/login", http.HandlerFunc(d.login))
	mux.Handle("/wait", http.HandlerFunc(d.wait))
	mux.Handle("/", http.HandlerFunc(d.notfound))
	return mux
}
示例#3
0
文件: client_test.go 项目: cmars/oo
func newHTTPDischarger(locator bakery.PublicKeyLocator, checker func(svc *bakery.Service, req *http.Request, cavId, cav string) ([]checkers.Caveat, error)) (*bakery.PublicKey, http.Handler) {
	svc := newService("loc", locator)
	mux := http.NewServeMux()
	httpbakery.AddDischargeHandler(mux, "/", svc, func(req *http.Request, cavId, cav string) ([]checkers.Caveat, error) {
		return checker(svc, req, cavId, cav)
	})
	return svc.PublicKey(), mux
}
示例#4
0
文件: authservice.go 项目: cmars/oo
// 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
}
示例#5
0
文件: service.go 项目: cmars/quorum
// 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
}
示例#6
0
文件: idservice.go 项目: cmars/oo
// 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
}
示例#7
0
// NewInteractiveDischarger returns a new InteractiveDischarger. The
// InteractiveDischarger will serve the following endpoints by default:
//
//     /discharge - always causes interaction to be required.
//     /publickey - gets the bakery public key.
//     /visit - delegates to visitHandler.
//     /wait - blocks waiting for the interaction to complete.
//
// Additional endpoints may be added to Mux as necessary.
//
// The /discharge endpoint generates a error with the code
// httpbakery.ErrInterractionRequired. The visitURL and waitURL will
// point to the /visit and /wait endpoints of the InteractiveDischarger
// respectively. These URLs will also carry context information in query
// parameters, any handlers should be careful to preserve this context
// information between calls. The easiest way to do this is to always use
// the URL method when generating new URLs.
//
// The /visit endpoint is handled by the provided visitHandler. This
// handler performs the required interactions and should result in the
// FinishInteraction method being called. This handler may process the
// interaction in a number of steps, possibly using additional handlers,
// so long as FinishInteraction is called when no further interaction is
// required.
//
// The /wait endpoint blocks until FinishInteraction has been called by
// the corresponding /visit endpoint, or another endpoint triggered by
// visitHandler.
//
// 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.
//
// The returned InteractiveDischarger must be closed when finished with.
func NewInteractiveDischarger(locator bakery.PublicKeyLocator, visitHandler http.Handler) *InteractiveDischarger {
	d := &InteractiveDischarger{
		Mux:     http.NewServeMux(),
		waiting: map[string]discharge{},
	}
	d.Mux.Handle("/visit", visitHandler)
	d.Mux.Handle("/wait", http.HandlerFunc(d.wait))
	server := httptest.NewTLSServer(d.Mux)
	svc, err := bakery.NewService(bakery.NewServiceParams{
		Location: server.URL,
		Locator:  locator,
	})
	if err != nil {
		panic(err)
	}
	httpbakery.AddDischargeHandler(d.Mux, "/", svc, d.checker)
	startSkipVerify()
	d.Discharger = Discharger{
		Service: svc,
		server:  server,
	}
	return d
}
示例#8
0
文件: apiserver.go 项目: kat-co/juju
func (srv *Server) endpoints() []apihttp.Endpoint {
	httpCtxt := httpContext{
		srv: srv,
	}

	endpoints := common.ResolveAPIEndpoints(srv.newHandlerArgs)

	// TODO(ericsnow) Add the following to the registry instead.

	add := func(pattern string, handler http.Handler) {
		// TODO: We can switch from all methods to specific ones for entries
		// where we only want to support specific request methods. However, our
		// tests currently assert that errors come back as application/json and
		// pat only does "text/plain" responses.
		for _, method := range common.DefaultHTTPMethods {
			endpoints = append(endpoints, apihttp.Endpoint{
				Pattern: pattern,
				Method:  method,
				Handler: handler,
			})
		}
	}

	strictCtxt := httpCtxt
	strictCtxt.strictValidation = true
	strictCtxt.controllerModelOnly = true

	mainAPIHandler := srv.trackRequests(http.HandlerFunc(srv.apiHandler))
	logSinkHandler := srv.trackRequests(newLogSinkHandler(httpCtxt, srv.logDir))
	logStreamHandler := srv.trackRequests(newLogStreamEndpointHandler(strictCtxt))
	debugLogHandler := srv.trackRequests(newDebugLogDBHandler(httpCtxt))

	add("/model/:modeluuid/logsink", logSinkHandler)
	add("/model/:modeluuid/logstream", logStreamHandler)
	add("/model/:modeluuid/log", debugLogHandler)
	add("/model/:modeluuid/charms",
		&charmsHandler{
			ctxt:    httpCtxt,
			dataDir: srv.dataDir},
	)
	add("/model/:modeluuid/tools",
		&toolsUploadHandler{
			ctxt: httpCtxt,
		},
	)
	add("/model/:modeluuid/tools/:version",
		&toolsDownloadHandler{
			ctxt: httpCtxt,
		},
	)
	add("/model/:modeluuid/backups",
		&backupHandler{
			ctxt: strictCtxt,
		},
	)
	add("/model/:modeluuid/api", mainAPIHandler)

	endpoints = append(endpoints, guiEndpoints("/gui/:modeluuid/", srv.dataDir, httpCtxt)...)
	add("/gui-archive", &guiArchiveHandler{
		ctxt: httpCtxt,
	})
	add("/gui-version", &guiVersionHandler{
		ctxt: httpCtxt,
	})

	// For backwards compatibility we register all the old paths
	add("/log", debugLogHandler)

	add("/charms",
		&charmsHandler{
			ctxt:    httpCtxt,
			dataDir: srv.dataDir,
		},
	)
	add("/tools",
		&toolsUploadHandler{
			ctxt: httpCtxt,
		},
	)
	add("/tools/:version",
		&toolsDownloadHandler{
			ctxt: httpCtxt,
		},
	)
	add("/register",
		&registerUserHandler{
			ctxt: httpCtxt,
		},
	)
	add("/api", mainAPIHandler)
	// Serve the API at / (only) for backward compatiblity. Note that the
	// pat muxer special-cases / so that it does not serve all
	// possible endpoints, but only / itself.
	add("/", mainAPIHandler)

	// Add HTTP handlers for local-user macaroon authentication.
	localLoginHandlers := &localLoginHandlers{srv.authCtxt, srv.state}
	dischargeMux := http.NewServeMux()
	httpbakery.AddDischargeHandler(
		dischargeMux,
		localUserIdentityLocationPath,
		localLoginHandlers.authCtxt.localUserThirdPartyBakeryService,
		localLoginHandlers.checkThirdPartyCaveat,
	)
	dischargeMux.Handle(
		localUserIdentityLocationPath+"/login",
		makeHandler(handleJSON(localLoginHandlers.serveLogin)),
	)
	dischargeMux.Handle(
		localUserIdentityLocationPath+"/wait",
		makeHandler(handleJSON(localLoginHandlers.serveWait)),
	)
	add(localUserIdentityLocationPath+"/discharge", dischargeMux)
	add(localUserIdentityLocationPath+"/publickey", dischargeMux)
	add(localUserIdentityLocationPath+"/login", dischargeMux)
	add(localUserIdentityLocationPath+"/wait", dischargeMux)

	return endpoints
}