// checkCreds validates the entities credentials in the current environment. // If the entity is a user, and lookForEnvUser is true, an env user must exist // for the environment. In the case of a user logging in to the server, but // not an environment, there is no env user needed. While we have the env // user, if we do have it, update the last login time. func checkCreds(st *state.State, req params.LoginRequest, lookForEnvUser bool) (state.Entity, *time.Time, error) { tag, err := names.ParseTag(req.AuthTag) if err != nil { return nil, nil, err } entity, err := st.FindEntity(tag) if errors.IsNotFound(err) { // We return the same error when an entity does not exist as for a bad // password, so that we don't allow unauthenticated users to find // information about existing entities. logger.Debugf("entity %q not found", tag) return nil, nil, common.ErrBadCreds } if err != nil { return nil, nil, errors.Trace(err) } authenticator, err := authentication.FindEntityAuthenticator(entity) if err != nil { return nil, nil, err } if err = authenticator.Authenticate(entity, req.Credentials, req.Nonce); err != nil { logger.Debugf("bad credentials") return nil, nil, err } // For user logins, update the last login time. // NOTE: this code path is only for local users. When we support remote // user logins with bearer tokens, we will need to make sure that we also // update the last connection times for the environment users there. var lastLogin *time.Time if user, ok := entity.(*state.User); ok { userLastLogin, err := user.LastLogin() if err != nil && !state.IsNeverLoggedInError(err) { return nil, nil, errors.Trace(err) } if lookForEnvUser { envUser, err := st.EnvironmentUser(user.UserTag()) if err != nil { return nil, nil, errors.Wrap(err, common.ErrBadCreds) } // The last connection for the environment takes precedence over // the local user last login time. userLastLogin, err = envUser.LastConnection() if err != nil && !state.IsNeverConnectedError(err) { return nil, nil, errors.Trace(err) } envUser.UpdateLastConnection() } // Only update the user's last login time if it is a successful // login, meaning that if we are logging into an environment, make // sure that there is an environment user in that environment for // this user. user.UpdateLastLogin() lastLogin = &userLastLogin } return entity, lastLogin, nil }
func addEnvUsers(c *gc.C, st *state.State) (expected []*state.EnvironmentUser) { // get the environment owner testAdmin := names.NewUserTag("test-admin") owner, err := st.EnvironmentUser(testAdmin) c.Assert(err, jc.ErrorIsNil) f := factory.NewFactory(st) return []*state.EnvironmentUser{ // we expect the owner to be an existing environment user owner, // add new users to the environment f.MakeEnvUser(c, nil), f.MakeEnvUser(c, nil), f.MakeEnvUser(c, nil), } }
func checkCreds(st *state.State, c params.Creds) (state.Entity, error) { tag, err := names.ParseTag(c.AuthTag) if err != nil { return nil, err } entity, err := st.FindEntity(tag) if errors.IsNotFound(err) { // We return the same error when an entity does not exist as for a bad // password, so that we don't allow unauthenticated users to find // information about existing entities. logger.Debugf("entity %q not found", tag) return nil, common.ErrBadCreds } if err != nil { return nil, errors.Trace(err) } authenticator, err := authentication.FindEntityAuthenticator(entity) if err != nil { return nil, err } if err = authenticator.Authenticate(entity, c.Password, c.Nonce); err != nil { logger.Debugf("bad credentials") return nil, err } // For user logins, ensure the user is allowed to access the environment. if user, ok := entity.Tag().(names.UserTag); ok { _, err := st.EnvironmentUser(user) if err != nil { return nil, errors.Wrap(err, common.ErrBadCreds) } } return entity, nil }