// AddEnvironmentUser adds a new user to the database. func (st *State) AddEnvironmentUser(user, createdBy names.UserTag, displayName string) (*EnvironmentUser, error) { // Ensure local user exists in state before adding them as an environment user. if user.IsLocal() { localUser, err := st.User(user) if err != nil { return nil, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", user.Name())) } if displayName == "" { displayName = localUser.DisplayName() } } // Ensure local createdBy user exists. if createdBy.IsLocal() { if _, err := st.User(createdBy); err != nil { return nil, errors.Annotate(err, fmt.Sprintf("createdBy user %q does not exist locally", createdBy.Name())) } } envuuid := st.EnvironUUID() op, doc := createEnvUserOpAndDoc(envuuid, user, createdBy, displayName) err := st.runTransaction([]txn.Op{op}) if err == txn.ErrAborted { err = errors.AlreadyExistsf("environment user %q", user.Username()) } if err != nil { return nil, errors.Trace(err) } return &EnvironmentUser{st: st, doc: *doc}, nil }
// User returns the state User for the given name. func (st *State) User(tag names.UserTag) (*User, error) { if !tag.IsLocal() { return nil, errors.NotFoundf("user %q", tag.Canonical()) } user := &User{st: st} if err := st.getUser(tag.Name(), &user.doc); err != nil { return nil, errors.Trace(err) } return user, nil }
func createInitialUserOp(st *State, user names.UserTag, password string) txn.Op { doc := userDoc{ Name: user.Name(), DisplayName: user.Name(), PasswordHash: password, // Empty PasswordSalt means utils.CompatSalt CreatedBy: user.Name(), DateCreated: nowToTheSecond(), } return txn.Op{ C: usersC, Id: doc.Name, Assert: txn.DocMissing, Insert: &doc, } }
func (st *State) envSetupOps(cfg *config.Config, envUUID, serverUUID string, owner names.UserTag) ([]txn.Op, error) { if err := checkEnvironConfig(cfg); err != nil { return nil, errors.Trace(err) } // When creating the state server environment, the new environment // UUID is also used as the state server UUID. if serverUUID == "" { serverUUID = envUUID } envUserOp := createEnvUserOp(envUUID, owner, owner, owner.Name(), false) ops := []txn.Op{ createConstraintsOp(st, environGlobalKey, constraints.Value{}), createSettingsOp(environGlobalKey, cfg.AllAttrs()), incHostedEnvironCountOp(), createEnvironmentOp(st, owner, cfg.Name(), envUUID, serverUUID), createUniqueOwnerEnvNameOp(owner, cfg.Name()), envUserOp, } return ops, nil }
func (st *State) envSetupOps(cfg *config.Config, modelUUID, serverUUID string, owner names.UserTag) ([]txn.Op, error) { if err := checkModelConfig(cfg); err != nil { return nil, errors.Trace(err) } // When creating the state server model, the new model // UUID is also used as the state server UUID. if serverUUID == "" { serverUUID = modelUUID } modelUserOp := createModelUserOp(modelUUID, owner, owner, owner.Name(), false) ops := []txn.Op{ createConstraintsOp(st, modelGlobalKey, constraints.Value{}), createSettingsOp(modelGlobalKey, cfg.AllAttrs()), incHostedModelCountOp(), createModelOp(st, owner, cfg.Name(), modelUUID, serverUUID), createUniqueOwnerModelNameOp(owner, cfg.Name()), modelUserOp, } return ops, nil }
func (c *LoginCommand) updatePassword(ctx *cmd.Context, conn api.Connection, userTag names.UserTag, serverInfo configstore.EnvironInfo) error { password, err := utils.RandomPassword() if err != nil { return errors.Annotate(err, "failed to generate random password") } userManager, err := c.getUserManager(conn) if err != nil { return errors.Trace(err) } if err := userManager.SetPassword(userTag.Name(), password); err != nil { errors.Trace(err) } ctx.Infof("password updated\n") creds := serverInfo.APICredentials() creds.Password = password serverInfo.SetAPICredentials(creds) if err = serverInfo.Write(); err != nil { return errors.Trace(err) } return nil }
func (st *State) modelSetupOps(cfg *config.Config, modelUUID, serverUUID string, owner names.UserTag, mode MigrationMode) ([]txn.Op, error) { if err := checkModelConfig(cfg); err != nil { return nil, errors.Trace(err) } modelStatusDoc := statusDoc{ ModelUUID: modelUUID, // TODO(fwereade): 2016-03-17 lp:1558657 Updated: time.Now().UnixNano(), // TODO(axw) 2016-04-13 lp:1569632 // We need to decide how we will // represent migration in model status. Status: status.StatusAvailable, } // When creating the controller model, the new model // UUID is also used as the controller UUID. if serverUUID == "" { serverUUID = modelUUID } modelUserOp := createModelUserOp(modelUUID, owner, owner, owner.Name(), nowToTheSecond(), ModelAdminAccess) ops := []txn.Op{ createStatusOp(st, modelGlobalKey, modelStatusDoc), createConstraintsOp(st, modelGlobalKey, constraints.Value{}), createSettingsOp(modelGlobalKey, cfg.AllAttrs()), } if modelUUID != serverUUID { ops = append(ops, incHostedModelCountOp()) } ops = append(ops, createModelEntityRefsOp(st, modelUUID), createModelOp(st, owner, cfg.Name(), modelUUID, serverUUID, mode), createUniqueOwnerModelNameOp(owner, cfg.Name()), modelUserOp, ) return ops, nil }
// AddEnvironmentUser adds a new user to the database. func (st *State) AddEnvironmentUser(user, createdBy names.UserTag, displayName string) (*EnvironmentUser, error) { // Ensure local user exists in state before adding them as an environment user. if user.Provider() == names.LocalProvider { if _, err := st.User(user.Name()); err != nil { return nil, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", user.Name())) } } // Ensure local createdBy user exists. if createdBy.Provider() == names.LocalProvider { if _, err := st.User(createdBy.Name()); err != nil { return nil, errors.Annotate(err, fmt.Sprintf("createdBy user %q does not exist locally", createdBy.Name())) } } username := user.Username() envuuid := st.EnvironTag().Id() id := envUserID(envuuid, username) envUser := &EnvironmentUser{ st: st, doc: envUserDoc{ ID: id, EnvUUID: envuuid, UserName: username, DisplayName: displayName, CreatedBy: createdBy.Username(), DateCreated: nowToTheSecond(), }} ops := []txn.Op{{ C: envUsersC, Id: id, Assert: txn.DocMissing, Insert: &envUser.doc, }} err := st.runTransaction(ops) if err == txn.ErrAborted { err = errors.New("env user already exists") } if err != nil { return nil, errors.Trace(err) } return envUser, nil }
func createInitialUserOp(st *State, user names.UserTag, password, salt string) txn.Op { nameToLower := strings.ToLower(user.Name()) doc := userDoc{ DocID: nameToLower, Name: user.Name(), DisplayName: user.Name(), PasswordHash: utils.UserPasswordHash(password, salt), PasswordSalt: salt, CreatedBy: user.Name(), DateCreated: nowToTheSecond(), } return txn.Op{ C: usersC, Id: nameToLower, Assert: txn.DocMissing, Insert: &doc, } }