Beispiel #1
0
// validateEnvironUUID is the common validator for the various
// apiserver components that need to check for a valid environment
// UUID.  An empty envUUID means that the connection has come in at
// the root of the URL space and refers to the state server
// environment.
//
// It returns the validated environment UUID.
func validateEnvironUUID(args validateArgs) (string, error) {
	ssState := args.statePool.SystemState()
	if args.envUUID == "" {
		// We allow the environUUID to be empty for 2 cases
		// 1) Compatibility with older clients
		// 2) TODO: server a limited API at the root (empty envUUID)
		//    with just the user manager and environment manager
		//    if the connection comes over a sufficiently up to date
		//    login command.
		if args.strict {
			return "", errors.Trace(common.UnknownEnvironmentError(args.envUUID))
		}
		logger.Debugf("validate env uuid: empty envUUID")
		return ssState.EnvironUUID(), nil
	}
	if args.envUUID == ssState.EnvironUUID() {
		logger.Debugf("validate env uuid: state server environment - %s", args.envUUID)
		return args.envUUID, nil
	}
	if args.stateServerEnvOnly {
		return "", errors.Unauthorizedf("requested environment %q is not the state server environment", args.envUUID)
	}
	if !names.IsValidEnvironment(args.envUUID) {
		return "", errors.Trace(common.UnknownEnvironmentError(args.envUUID))
	}
	envTag := names.NewEnvironTag(args.envUUID)
	if _, err := ssState.GetEnvironment(envTag); err != nil {
		return "", errors.Wrap(err, common.UnknownEnvironmentError(args.envUUID))
	}
	logger.Debugf("validate env uuid: %s", args.envUUID)
	return args.envUUID, nil
}
Beispiel #2
0
Datei: utils.go Projekt: bac/juju
// validateModelUUID is the common validator for the various
// apiserver components that need to check for a valid model
// UUID.  An empty modelUUID means that the connection has come in at
// the root of the URL space and refers to the controller
// model.
//
// It returns the validated model UUID.
func validateModelUUID(args validateArgs) (string, error) {
	ssState := args.statePool.SystemState()
	if args.modelUUID == "" {
		// We allow the modelUUID to be empty so that:
		//    TODO: server a limited API at the root (empty modelUUID)
		//    just the user manager and model manager are able to accept
		//    requests that don't require a modelUUID, like add-model.
		if args.strict {
			return "", errors.Trace(common.UnknownModelError(args.modelUUID))
		}
		return ssState.ModelUUID(), nil
	}
	if args.modelUUID == ssState.ModelUUID() {
		return args.modelUUID, nil
	}
	if args.controllerModelOnly {
		return "", errors.Unauthorizedf("requested model %q is not the controller model", args.modelUUID)
	}
	if !names.IsValidModel(args.modelUUID) {
		return "", errors.Trace(common.UnknownModelError(args.modelUUID))
	}
	modelTag := names.NewModelTag(args.modelUUID)
	if _, err := ssState.GetModel(modelTag); err != nil {
		return "", errors.Wrap(err, common.UnknownModelError(args.modelUUID))
	}
	return args.modelUUID, nil
}
Beispiel #3
0
// validateModelUUID is the common validator for the various
// apiserver components that need to check for a valid model
// UUID.  An empty modelUUID means that the connection has come in at
// the root of the URL space and refers to the controller
// model.
//
// It returns the validated model UUID.
func validateModelUUID(args validateArgs) (string, error) {
	ssState := args.statePool.SystemState()
	if args.modelUUID == "" {
		// We allow the modelUUID to be empty for 2 cases
		// 1) Compatibility with older clients
		// 2) TODO: server a limited API at the root (empty modelUUID)
		//    with just the user manager and model manager
		//    if the connection comes over a sufficiently up to date
		//    login command.
		if args.strict {
			return "", errors.Trace(common.UnknownModelError(args.modelUUID))
		}
		logger.Debugf("validate model uuid: empty modelUUID")
		return ssState.ModelUUID(), nil
	}
	if args.modelUUID == ssState.ModelUUID() {
		logger.Debugf("validate model uuid: controller model - %s", args.modelUUID)
		return args.modelUUID, nil
	}
	if args.controllerModelOnly {
		return "", errors.Unauthorizedf("requested model %q is not the controller model", args.modelUUID)
	}
	if !names.IsValidModel(args.modelUUID) {
		return "", errors.Trace(common.UnknownModelError(args.modelUUID))
	}
	modelTag := names.NewModelTag(args.modelUUID)
	if _, err := ssState.GetModel(modelTag); err != nil {
		return "", errors.Wrap(err, common.UnknownModelError(args.modelUUID))
	}
	logger.Debugf("validate model uuid: %s", args.modelUUID)
	return args.modelUUID, nil
}
Beispiel #4
0
func maybeUnauthorized(err error, msg string) error {
	if err == nil {
		return nil
	}
	if isUnauthorized(err) {
		return errors.Unauthorizedf("%s: unauthorized mongo access: %v", msg, err)
	}
	return errors.Annotatef(err, msg)
}
Beispiel #5
0
// Disable deactivates the user.  Disabled identities cannot log in.
func (u *User) Disable() error {
	environment, err := u.st.ControllerEnvironment()
	if err != nil {
		return errors.Trace(err)
	}
	if u.doc.Name == environment.Owner().Name() {
		return errors.Unauthorizedf("cannot disable state server environment owner")
	}
	return errors.Annotatef(u.setDeactivated(true), "cannot disable user %q", u.Name())
}
Beispiel #6
0
func (s *verifyStorageSuite) TestVerifyStorageFails(c *gc.C) {
	ctx := testing.Context(c)
	environ, err := environs.PrepareFromName("test", ctx, configstore.NewMem())
	c.Assert(err, gc.IsNil)
	stor := environ.Storage()
	someError := errors.Unauthorizedf("you shall not pass")
	dummy.Poison(stor, environs.VerificationFilename, someError)
	err = environs.VerifyStorage(stor)
	c.Assert(err, gc.Equals, environs.VerifyStorageError)
}
Beispiel #7
0
// NewLeadershipService constructs a new LeadershipService.
func NewLeadershipService(
	claimer leadership.Claimer, authorizer common.Authorizer,
) (LeadershipService, error) {

	if !authorizer.AuthUnitAgent() {
		return nil, errors.Unauthorizedf("permission denied")
	}

	return &leadershipService{
		claimer:    claimer,
		authorizer: authorizer,
	}, nil
}
Beispiel #8
0
Datei: user.go Projekt: bac/juju
// Disable deactivates the user.  Disabled identities cannot log in.
func (u *User) Disable() error {
	if err := u.ensureNotDeleted(); err != nil {
		return errors.Annotate(err, "cannot disable")
	}
	environment, err := u.st.ControllerModel()
	if err != nil {
		return errors.Trace(err)
	}
	if u.doc.Name == environment.Owner().Name() {
		return errors.Unauthorizedf("cannot disable controller model owner")
	}
	return errors.Annotatef(u.setDeactivated(true), "cannot disable user %q", u.Name())
}
Beispiel #9
0
func (s *BootstrapSuite) TestInitialPassword(c *gc.C) {
	machineConf, cmd, err := s.initBootstrapCommand(c, nil, "--env-config", s.envcfg, "--instance-id", string(s.instanceId))
	c.Assert(err, gc.IsNil)

	err = cmd.Run(nil)
	c.Assert(err, gc.IsNil)

	// Check that we cannot now connect to the state without a
	// password.
	info := &authentication.MongoInfo{
		Info: mongo.Info{
			Addrs:  []string{gitjujutesting.MgoServer.Addr()},
			CACert: testing.CACert,
		},
	}
	testOpenState(c, info, errors.Unauthorizedf(""))

	// Check we can log in to mongo as admin.
	// TODO(dfc) does passing nil for the admin user name make your skin crawl ? mine too.
	info.Tag, info.Password = nil, testPasswordHash()
	st, err := state.Open(info, mongo.DefaultDialOpts(), environs.NewStatePolicy())
	c.Assert(err, gc.IsNil)
	// Reset password so the tests can continue to use the same server.
	defer st.Close()
	defer st.SetAdminMongoPassword("")

	// Check that the admin user has been given an appropriate
	// password
	u, err := st.User("admin")
	c.Assert(err, gc.IsNil)
	c.Assert(u.PasswordValid(testPassword), gc.Equals, true)

	// Check that the machine configuration has been given a new
	// password and that we can connect to mongo as that machine
	// and that the in-mongo password also verifies correctly.
	machineConf1, err := agent.ReadConfig(agent.ConfigPath(machineConf.DataDir(), names.NewMachineTag("0")))
	c.Assert(err, gc.IsNil)

	stateinfo, ok := machineConf1.MongoInfo()
	c.Assert(ok, jc.IsTrue)
	st, err = state.Open(stateinfo, mongo.DialOpts{}, environs.NewStatePolicy())
	c.Assert(err, gc.IsNil)
	defer st.Close()

	m, err := st.Machine("0")
	c.Assert(err, gc.IsNil)
	c.Assert(m.HasVote(), jc.IsTrue)
}
Beispiel #10
0
func (c *updateCloudsCommand) Run(ctxt *cmd.Context) error {
	fmt.Fprint(ctxt.Stdout, "Fetching latest public cloud list... ")
	client := utils.GetHTTPClient(utils.VerifySSLHostnames)
	resp, err := client.Get(c.publicCloudURL)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	noNewClouds := "\nno new public cloud information available at this time"
	if resp.StatusCode != http.StatusOK {
		switch resp.StatusCode {
		case http.StatusNotFound:
			fmt.Fprintln(ctxt.Stdout, noNewClouds)
			return nil
		case http.StatusUnauthorized:
			return errors.Unauthorizedf("unauthorised access to URL %q", c.publicCloudURL)
		}
		return fmt.Errorf("cannot read public cloud information at URL %q, %q", c.publicCloudURL, resp.Status)
	}

	cloudData, err := decodeCheckSignature(resp.Body, c.publicSigningKey)
	if err != nil {
		return errors.Annotate(err, "error receiving updated cloud data")
	}
	newPublicClouds, err := jujucloud.ParseCloudMetadata(cloudData)
	if err != nil {
		return errors.Annotate(err, "invalid cloud data received when updating clouds")
	}
	currentPublicClouds, _, err := jujucloud.PublicCloudMetadata(jujucloud.JujuPublicCloudsPath())
	if err != nil {
		return errors.Annotate(err, "invalid local public cloud data")
	}
	sameCloudInfo, err := jujucloud.IsSameCloudMetadata(newPublicClouds, currentPublicClouds)
	if err != nil {
		// Should never happen.
		return err
	}
	if sameCloudInfo {
		fmt.Fprintln(ctxt.Stdout, noNewClouds)
		return nil
	}
	if err := jujucloud.WritePublicCloudMetadata(newPublicClouds); err != nil {
		return errors.Annotate(err, "error writing new local public cloud data")
	}
	fmt.Fprintln(ctxt.Stdout, "done.")
	return nil
}
Beispiel #11
0
func (s *checkEnvironmentSuite) TestCheckEnvironmentGetFails(c *gc.C) {
	ctx := testing.Context(c)
	environ, err := environs.PrepareFromName("test", ctx, configstore.NewMem())
	c.Assert(err, gc.IsNil)

	// VerifyStorage is sufficient for our tests and much simpler
	// than Bootstrap which calls it.
	stor := environ.Storage()
	err = environs.VerifyStorage(stor)
	c.Assert(err, gc.IsNil)

	// When fetching the verification file from storage fails,
	// we get an InvalidEnvironmentError.
	someError := errors.Unauthorizedf("you shall not pass")
	dummy.Poison(stor, environs.VerificationFilename, someError)
	err = environs.CheckEnvironment(environ)
	c.Assert(err, gc.Equals, someError)
}
Beispiel #12
0
func (u *User) Deactivate() error {
	if u.doc.Name == AdminUser {
		return errors.Unauthorizedf("Can't deactivate admin user")
	}
	ops := []txn.Op{{
		C:      usersC,
		Id:     u.Name(),
		Update: bson.D{{"$set", bson.D{{"deactivated", true}}}},
		Assert: txn.DocExists,
	}}
	if err := u.st.runTransaction(ops); err != nil {
		if err == txn.ErrAborted {
			err = fmt.Errorf("user no longer exists")
		}
		return fmt.Errorf("cannot deactivate user %q: %v", u.Name(), err)
	}
	u.doc.Deactivated = true
	return nil
}
Beispiel #13
0
// Fetch is defined in simplestreams.DataSource.
func (h *urlDataSource) Fetch(path string) (io.ReadCloser, string, error) {
	dataURL := urlJoin(h.baseURL, path)
	client := utils.GetHTTPClient(h.hostnameVerification)
	// dataURL can be http:// or file://
	resp, err := client.Get(dataURL)
	if err != nil {
		logger.Debugf("Got error requesting %q: %v", dataURL, err)
		return nil, dataURL, errors.NotFoundf("invalid URL %q", dataURL)
	}
	if resp.StatusCode == http.StatusNotFound {
		return nil, dataURL, errors.NotFoundf("cannot find URL %q", dataURL)
	}
	if resp.StatusCode == http.StatusUnauthorized {
		return nil, dataURL, errors.Unauthorizedf("unauthorised access to URL %q", dataURL)
	}
	if resp.StatusCode != http.StatusOK {
		return nil, dataURL, fmt.Errorf("cannot access URL %q, %q", dataURL, resp.Status)
	}
	return resp.Body, dataURL, nil
}
Beispiel #14
0
// Fetch is defined in simplestreams.DataSource.
func (h *urlDataSource) Fetch(path string) (io.ReadCloser, string, error) {
	dataURL := urlJoin(h.baseURL, path)
	client := utils.GetHTTPClient(h.hostnameVerification)
	// dataURL can be http:// or file://
	// MakeFileURL will only modify the URL if it's a file URL
	dataURL = utils.MakeFileURL(dataURL)
	resp, err := client.Get(dataURL)
	if err != nil {
		logger.Tracef("Got error requesting %q: %v", dataURL, err)
		return nil, dataURL, errors.NotFoundf("invalid URL %q", dataURL)
	}
	if resp.StatusCode != http.StatusOK {
		resp.Body.Close()
		switch resp.StatusCode {
		case http.StatusNotFound:
			return nil, dataURL, errors.NotFoundf("cannot find URL %q", dataURL)
		case http.StatusUnauthorized:
			return nil, dataURL, errors.Unauthorizedf("unauthorised access to URL %q", dataURL)
		}
		return nil, dataURL, fmt.Errorf("cannot access URL %q, %q", dataURL, resp.Status)
	}
	return resp.Body, dataURL, nil
}
Beispiel #15
0
// validateEnvironUUID is the common validator for the various apiserver
// components that need to check for a valid environment UUID.
// An empty envUUID means that the connection has come in at the root
// of the URL space and refers to the state server environment.
// The *state.State parameter is expected to be the state server State
// connection.  The return *state.State is a connection for the specified
// environment UUID if the UUID refers to an environment contained in the
// database.  If the bool return value is true, the state connection must
// be closed by the caller at the end of serving the client connection.
func validateEnvironUUID(args validateArgs) (*state.State, bool, error) {
	if args.envUUID == "" {
		// We allow the environUUID to be empty for 2 cases
		// 1) Compatibility with older clients
		// 2) TODO: server a limited API at the root (empty envUUID)
		//    with just the user manager and environment manager
		//    if the connection comes over a sufficiently up to date
		//    login command.
		if args.strict {
			return nil, false, errors.Trace(common.UnknownEnvironmentError(args.envUUID))
		}
		logger.Debugf("validate env uuid: empty envUUID")
		return args.st, false, nil
	}
	if args.envUUID == args.st.EnvironUUID() {
		logger.Debugf("validate env uuid: state server environment - %s", args.envUUID)
		return args.st, false, nil
	}
	if args.stateServerEnvOnly {
		return nil, false, errors.Unauthorizedf("requested environment %q is not the state server environment", args.envUUID)
	}
	if !names.IsValidEnvironment(args.envUUID) {
		return nil, false, errors.Trace(common.UnknownEnvironmentError(args.envUUID))
	}
	envTag := names.NewEnvironTag(args.envUUID)
	if env, err := args.st.GetEnvironment(envTag); err != nil {
		return nil, false, errors.Wrap(err, common.UnknownEnvironmentError(args.envUUID))
	} else if env.Life() != state.Alive {
		return nil, false, errors.Errorf("environment %q is no longer live", args.envUUID)
	}
	logger.Debugf("validate env uuid: %s", args.envUUID)
	result, err := args.st.ForEnviron(envTag)
	if err != nil {
		return nil, false, errors.Trace(err)
	}
	return result, true, nil
}
Beispiel #16
0
type errorsSuite struct {
	testing.BaseSuite
}

var _ = gc.Suite(&errorsSuite{})

var errorTransformTests = []struct {
	err        error
	code       string
	helperFunc func(error) bool
}{{
	err:        errors.NotFoundf("hello"),
	code:       params.CodeNotFound,
	helperFunc: params.IsCodeNotFound,
}, {
	err:        errors.Unauthorizedf("hello"),
	code:       params.CodeUnauthorized,
	helperFunc: params.IsCodeUnauthorized,
}, {
	err:        state.ErrCannotEnterScopeYet,
	code:       params.CodeCannotEnterScopeYet,
	helperFunc: params.IsCodeCannotEnterScopeYet,
}, {
	err:        state.ErrCannotEnterScope,
	code:       params.CodeCannotEnterScope,
	helperFunc: params.IsCodeCannotEnterScope,
}, {
	err:        state.ErrExcessiveContention,
	code:       params.CodeExcessiveContention,
	helperFunc: params.IsCodeExcessiveContention,
}, {
Beispiel #17
0
// Deactivate deactivates the user.  Deactivated identities cannot log in.
func (u *User) Deactivate() error {
	if u.doc.Name == AdminUser {
		return errors.Unauthorizedf("cannot deactivate admin user")
	}
	return errors.Annotatef(u.setDeactivated(true), "cannot deactivate user %q", u.Name())
}
Beispiel #18
0
	"launchpad.net/tomb"
)

const (
	// There are no blocking calls, so this can be long. We just don't
	// want goroutines to hang around indefinitely, so notifications
	// will time out after this value.
	notificationTimeout = 1 * time.Minute

	// This is a useful thing to know in several contexts.
	maxDuration = time.Duration(1<<63 - 1)
)

var (
	LeaseClaimDeniedErr = errors.New("lease claim denied")
	NotLeaseOwnerErr    = errors.Unauthorizedf("caller did not own lease for namespace")
	errWorkerStopped    = errors.New("worker stopped")

	logger = loggo.GetLogger("juju.lease")
)

type leasePersistor interface {
	WriteToken(string, Token) error
	RemoveToken(id string) error
	PersistedTokens() ([]Token, error)
}

// Token represents a lease claim.
type Token struct {
	Namespace, Id string
	Expiration    time.Time
Beispiel #19
0
// Deactivate deactivates the identity.  Deactivated identities cannot log in.
func (i *Identity) Deactivate() error {
	if i.doc.Name == AdminIdentity {
		return errors.Unauthorizedf("cannot deactivate admin identity")
	}
	return errors.Annotatef(i.setDeactivated(true), "cannot deactivate identity %q", i.Name())
}