// CredentialModelsAndOwnerAccess returns all models that use given cloud credential as well as
// what access the credential owner has on these models.
495915
func (st *State) CredentialModelsAndOwnerAccess(tag names.CloudCredentialTag) ([]CredentialOwnerModelAccess, error) {
	models, err := st.CredentialModels(tag)
	if err != nil {
		return nil, errors.Trace(err)
	}

	var results []CredentialOwnerModelAccess
	for uuid, name := range models {
		ownerAccess, err := st.UserAccess(tag.Owner(), names.NewModelTag(uuid))
		if err != nil {
			if errors.IsNotFound(err) {
				results = append(results, CredentialOwnerModelAccess{ModelName: name, ModelUUID: uuid, OwnerAccess: permission.NoAccess})
				continue
			}
			results = append(results, CredentialOwnerModelAccess{ModelName: name, ModelUUID: uuid, Error: errors.Trace(err)})
			continue
		}
		results = append(results, CredentialOwnerModelAccess{ModelName: name, ModelUUID: uuid, OwnerAccess: ownerAccess.Access})
	}
	return results, nil
}
47706
func (b *backend) ModelCredential() (*ModelCredential, error) {
	m, err := b.Model()
	if err != nil {
		return nil, errors.Trace(err)
	}

	modelCredentialTag, exists := m.CloudCredential()
	result := &ModelCredential{Model: m.ModelTag(), Exists: exists}
	if !exists {
		// A model credential is not set, we must check if the model
		// is on the cloud that requires a credential.
		supportsEmptyAuth, err := b.cloudSupportsNoAuth(m.Cloud())
		if err != nil {
			return nil, errors.Trace(err)
		}
		result.Valid = supportsEmptyAuth
		if !supportsEmptyAuth {
			// TODO (anastasiamac 2018-11-12) Figure out how to notify the users here - maybe set a model status?...
			logger.Warningf("model credential is not set for the model but the cloud requires it")
		}
		return result, nil
	}

	result.Credential = modelCredentialTag
	credential, err := b.CloudCredential(modelCredentialTag)
	if err != nil {
		if !errors.IsNotFound(err) {
			return nil, errors.Trace(err)
		}
		// In this situation, a model refers to a credential that does not exist in credentials collection.
		// TODO (anastasiamac 2018-11-12) Figure out how to notify the users here - maybe set a model status?...
		logger.Warningf("cloud credential reference is set for the model but the credential content is no longer on the controller")
		result.Valid = false
		return result, nil
	}
	result.Valid = credential.IsValid()
	return result, nil
}
911285
func (c *Facade) InvalidateModelCredential(reason string) error {
	in := params.InvalidateCredentialArg{reason}
	var result params.ErrorResult
	err := c.facade.FacadeCall("InvalidateModelCredential", in, &result)
	if err != nil {
		return errors.Trace(err)
	}

	if result.Error != nil {
		return errors.Trace(result.Error)
	}
	return nil
}
602001
func RegisterCredentials(
	ctx *cmd.Context,
	store jujuclient.CredentialStore,
	provider environs.EnvironProvider,
	args modelcmd.RegisterCredentialsParams,
) error {
	credentials, err := modelcmd.RegisterCredentials(provider, args)
	switch {
	case errors.IsNotFound(err):
		return nil
	case err != nil:
		return errors.Trace(err)
	case credentials == nil:
		return nil
	}

	ctx.Verbosef("updating credential store")

	for name, credential := range credentials {
		if err := store.UpdateCredential(name, *credential); err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
155336
func (environProviderCredentials) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema {
	return map[cloud.AuthType]cloud.CredentialSchema{
		// TODO(axw) we need a more appropriate name for this authentication
		//           type. ssh?
		cloud.UserPassAuthType: {{
			credAttrSDCUser, cloud.CredentialAttr{Description: "SmartDataCenter user ID"},
		}, {
			credAttrSDCKeyID, cloud.CredentialAttr{Description: "SmartDataCenter key ID"},
		}, {
			credAttrPrivateKey, cloud.CredentialAttr{
				Description: "Private key used to sign requests",
				Hidden:      true,
				FileAttr:    "private-key-path",
			},
		}, {
			credAttrAlgorithm, cloud.CredentialAttr{
				Description: "Algorithm used to generate the private key (default rsa-sha256)",
				Optional:    true,
				Options:     []interface{}{"rsa-sha256", "rsa-sha1", "rsa-sha224", "rsa-sha384", "rsa-sha512"},
			},
		}},
	}
}
115354
func ValidateModelAccess(access Access) error {
	switch access {
	case ReadAccess, WriteAccess, AdminAccess:
		return nil
	}
	return errors.NotValidf("%q model access", access)
}
426090
func (api *CloudAPI) UserCredentials(args params.UserClouds) (params.StringsResults, error) {
	results := params.StringsResults{
		Results: make([]params.StringsResult, len(args.UserClouds)),
	}
	authFunc, err := api.getCredentialsAuthFunc()
	if err != nil {
		return results, err
	}
	for i, arg := range args.UserClouds {
		userTag, err := names.ParseUserTag(arg.UserTag)
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		if !authFunc(userTag) {
			results.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}
		cloudTag, err := names.ParseCloudTag(arg.CloudTag)
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		cloudCredentials, err := api.backend.CloudCredentials(userTag, cloudTag.Id())
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		out := make([]string, 0, len(cloudCredentials))
		for tagId := range cloudCredentials {
			if !names.IsValidCloudCredential(tagId) {
				results.Results[i].Error = common.ServerError(errors.NotValidf("cloud credential ID %q", tagId))
				continue
			}
			out = append(out, names.NewCloudCredentialTag(tagId).String())
		}
		results.Results[i].Result = out
	}
	return results, nil
}
141465
func (c Config) AllowModelAccess() bool {
	value, _ := c[AllowModelAccessKey].(bool)
	return value
}
274304
func (c *Client) CreateModel(
	name, owner, cloud, cloudRegion string,
	cloudCredential names.CloudCredentialTag,
	config map[string]interface{},
) (base.ModelInfo, error) {
	var result base.ModelInfo
	if !names.IsValidUser(owner) {
		return result, errors.Errorf("invalid owner name %q", owner)
	}
	var cloudTag string
	if cloud != "" {
		if !names.IsValidCloud(cloud) {
			return result, errors.Errorf("invalid cloud name %q", cloud)
		}
		cloudTag = names.NewCloudTag(cloud).String()
	}
	var cloudCredentialTag string
	if cloudCredential != (names.CloudCredentialTag{}) {
		cloudCredentialTag = cloudCredential.String()
	}
	createArgs := params.ModelCreateArgs{
		Name:               name,
		OwnerTag:           names.NewUserTag(owner).String(),
		Config:             config,
		CloudTag:           cloudTag,
		CloudRegion:        cloudRegion,
		CloudCredentialTag: cloudCredentialTag,
	}
	var modelInfo params.ModelInfo
	err := c.facade.FacadeCall("CreateModel", createArgs, &modelInfo)
	if err != nil {
		// We don't want the message to contain the "(already exists)" suffix.
		if rpcErr, ok := errors.Cause(err).(*rpc.RequestError); ok {
			return result, errors.New(rpcErr.Message)
		}
		return result, errors.Trace(err)
	}
	return convertParamsModelInfo(modelInfo)
}
962542
func (m *Model) ValidateCloudCredential(tag names.CloudCredentialTag, credential cloud.Credential) error {
	cloud, err := m.st.Cloud(m.Cloud())
	if err != nil {
		return errors.Annotatef(err, "getting cloud %q", m.Cloud())
	}

	err = validateCredentialForCloud(cloud, tag, convertCloudCredentialToState(tag, credential))
	if err != nil {
		return errors.Annotatef(err, "validating credential %q for cloud %q", tag.Id(), cloud.Name)
	}
	return nil
}
1095300
func RegisterCredentialProvider(name string, provider DockerConfigProvider) {
	providersMutex.Lock()
	defer providersMutex.Unlock()
	_, found := providers[name]
	if found {
		glog.Fatalf("Credential provider %q was registered twice", name)
	}
	glog.V(1).Infof("Registered credential provider %q", name)
	providers[name] = provider
}
687166
func (c *Core) teardownCredentials(ctx context.Context) error {
	c.authLock.Lock()
	defer c.authLock.Unlock()

	if c.auth != nil {
		authTable := c.auth.shallowClone()
		for _, e := range authTable.Entries {
			backend := c.router.MatchingBackend(namespace.ContextWithNamespace(ctx, e.namespace), credentialRoutePrefix+e.Path)
			if backend != nil {
				backend.Cleanup(ctx)
			}

			viewPath := e.ViewPath()
			removePathCheckers(c, e, viewPath)
		}
	}

	c.auth = nil
	c.tokenStore = nil
	return nil
}
1329071
func (st *State) AllCloudCredentials(user names.UserTag) ([]Credential, error) {
	coll, cleanup := st.db().GetCollection(cloudCredentialsC)
	defer cleanup()

	// There are 2 ways of getting a credential for a user:
	// 1. user name stored in the credential tag (aka doc id);
	// 2. look up using Owner field.
	// We use Owner field below as credential tag or doc ID may be changed
	// in the future to be a real Primary Key that has nothing to do with
	// the data it identifies, i.e. no business meaning.
	clause := bson.D{{"owner", user.Id()}}

	var docs []cloudCredentialDoc
	err := coll.Find(clause).Sort("cloud").All(&docs)
	if err != nil {
		return nil, errors.Annotatef(err, "getting cloud credentials for %q", user.Id())
	}

	if len(docs) == 0 {
		return nil, errors.NotFoundf("cloud credentials for %q", user.Id())
	}

	credentials := make([]Credential, len(docs))
	for i, doc := range docs {
		credentials[i] = Credential{doc}
	}
	return credentials, nil
}
536727
func (ctxt *CredentialHelperContext) GetCredentialHelper(helper CredentialHelper, u *url.URL) (CredentialHelper, Creds) {
	rawurl := fmt.Sprintf("%s://%s%s", u.Scheme, u.Host, u.Path)
	input := Creds{"protocol": u.Scheme, "host": u.Host}
	if u.User != nil && u.User.Username() != "" {
		input["username"] = u.User.Username()
	}
	if u.Scheme == "cert" || ctxt.urlConfig.Bool("credential", rawurl, "usehttppath", false) {
		input["path"] = strings.TrimPrefix(u.Path, "/")
	}

	if helper != nil {
		return helper, input
	}

	helpers := make([]CredentialHelper, 0, 4)
	if ctxt.netrcCredHelper != nil {
		helpers = append(helpers, ctxt.netrcCredHelper)
	}
	if ctxt.cachingCredHelper != nil {
		helpers = append(helpers, ctxt.cachingCredHelper)
	}
	if ctxt.askpassCredHelper != nil {
		helper, _ := ctxt.urlConfig.Get("credential", rawurl, "helper")
		if len(helper) == 0 {
			helpers = append(helpers, ctxt.askpassCredHelper)
		}
	}

	return NewCredentialHelpers(append(helpers, ctxt.commandCredHelper)), input
}
1182107
func (c *ControllerAPI) HostedModelConfigs() (params.HostedModelConfigsResults, error) {
	result := params.HostedModelConfigsResults{}
	if err := c.checkHasAdmin(); err != nil {
		return result, errors.Trace(err)
	}

	modelUUIDs, err := c.state.AllModelUUIDs()
	if err != nil {
		return result, errors.Trace(err)
	}

	for _, modelUUID := range modelUUIDs {
		if modelUUID == c.state.ControllerModelUUID() {
			continue
		}
		st, err := c.statePool.Get(modelUUID)
		if err != nil {
			// This model could have been removed.
			if errors.IsNotFound(err) {
				continue
			}
			return result, errors.Trace(err)
		}
		defer st.Release()
		model, err := st.Model()
		if err != nil {
			return result, errors.Trace(err)
		}

		config := params.HostedModelConfig{
			Name:     model.Name(),
			OwnerTag: model.Owner().String(),
		}
		modelConf, err := model.Config()
		if err != nil {
			config.Error = common.ServerError(err)
		} else {
			config.Config = modelConf.AllAttrs()
		}
		cloudSpec := c.GetCloudSpec(model.ModelTag())
		if config.Error == nil {
			config.CloudSpec = cloudSpec.Result
			config.Error = cloudSpec.Error
		}
		result.Models = append(result.Models, config)
	}

	return result, nil
}
802159
func (r Network_Storage_Hub_Cleversafe_Account) CredentialDelete(credential *datatypes.Network_Storage_Credential) (resp bool, err error) {
	params := []interface{}{
		credential,
	}
	err = r.Session.DoRequest("SoftLayer_Network_Storage_Hub_Cleversafe_Account", "credentialDelete", params, &r.Options, &resp)
	return
}
186713
func (api *CloudAPI) RevokeCredentialsCheckModels(args params.RevokeCredentialArgs) (params.ErrorResults, error) {
	// TODO (anastasiamac 2018-11-13) the behavior here needs to be changed to performed promised models checks and authorise use of force.
	results := params.ErrorResults{
		Results: make([]params.ErrorResult, len(args.Credentials)),
	}
	authFunc, err := api.getCredentialsAuthFunc()
	if err != nil {
		return results, err
	}

	opMessage := func(force bool) string {
		if force {
			return "will be deleted but"
		}
		return "cannot be deleted as"
	}

	for i, arg := range args.Credentials {
		tag, err := names.ParseCloudCredentialTag(arg.Tag)
		if err != nil {
			results.Results[i].Error = common.ServerError(err)
			continue
		}
		// NOTE(axw) if we add ACLs for cloud credentials, we'll need
		// to change this auth check.
		if !authFunc(tag.Owner()) {
			results.Results[i].Error = common.ServerError(common.ErrPerm)
			continue
		}

		models, err := api.credentialModels(tag)
		if err != nil {
			if !arg.Force {
				// Could not determine if credential has models - do not continue updating this credential...
				results.Results[i].Error = common.ServerError(err)
				continue
			}
			logger.Warningf("could not get models that use credential %v: %v", tag, err)
		}
		if len(models) != 0 {
			logger.Warningf("credential %v %v it is used by model%v",
				tag,
				opMessage(arg.Force),
				modelsPretty(models),
			)
			if !arg.Force {
				// Some models still use this credential - do not delete this credential...
				results.Results[i].Error = common.ServerError(errors.Errorf("cannot delete credential %v: it is still used by %d model%v", tag, len(models), plural(len(models))))
				continue
			}
		}

		if err := api.backend.RemoveCloudCredential(tag); err != nil {
			results.Results[i].Error = common.ServerError(err)
		}
	}
	return results, nil
}