Beispiel #1
0
func DeleteUser(userId bson.ObjectId) error {
	user, err := modelhelper.GetUserById(userId.Hex())
	if err != nil {
		return err
	}

	userQuery := func(c *mgo.Collection) error {
		return c.Remove(bson.M{"_id": userId})
	}

	err = modelhelper.Mongo.Run(modelhelper.UserColl, userQuery)
	if err != nil {
		return err
	}

	accQuery := func(c *mgo.Collection) error {
		return c.Remove(bson.M{"profile.nickname": user.Name})
	}

	return modelhelper.Mongo.Run(modelhelper.AccountsColl, accQuery)
}
Beispiel #2
0
// BuildMachine ensures the user and group of the spec are
// inserted into db.
func (spec *MachineSpec) BuildMachine(createUser bool) error {
	// If MachineID is not nil, ensure it exists and reuse it if it does.
	if spec.HasMachine() {
		m, err := modelhelper.GetMachine(spec.Machine.ObjectId.Hex())
		if err != nil {
			return err
		}
		spec.Machine = *m
		return nil
	}

	// If no existing group is provided, create or use 'hackathon' one,
	// which will make VMs invisible to users until they're assigned
	// to proper group before the hackathon.
	if !spec.HasGroup() {
		group, err := modelhelper.GetGroup("koding")
		if err != nil {
			return err
		}
		spec.Machine.Groups = []models.MachineGroup{{Id: group.Id}}
	}

	// If no existing user is provided, create one.
	if !spec.HasUser() {
		// Try to lookup user by username first.
		user, err := modelhelper.GetUser(spec.Username())
		if err != nil {
			if !createUser {
				return fmt.Errorf("user %q does not exist", spec.Username())
			}

			spec.User.ObjectId = bson.NewObjectId()
			if spec.User.RegisteredAt.IsZero() {
				spec.User.RegisteredAt = time.Now()
			}

			if spec.User.LastLoginDate.IsZero() {
				spec.User.LastLoginDate = spec.User.RegisteredAt
			}

			if err = modelhelper.CreateUser(&spec.User); err != nil {
				return err
			}

			user = &spec.User
		}

		spec.User.ObjectId = user.ObjectId
		spec.User.Name = spec.Username()
	}

	// Ensure the user is assigned to the machine.
	if len(spec.Machine.Users) == 0 {
		spec.Machine.Users = []models.MachineUser{{
			Sudo:  true,
			Owner: true,
		}}
	}
	if spec.Machine.Users[0].Id == "" {
		spec.Machine.Users[0].Id = spec.User.ObjectId
	}
	if spec.Machine.Users[0].Username == "" {
		spec.Machine.Users[0].Username = spec.User.Name
	}

	// Lookup username for existing user.
	if spec.Machine.Users[0].Username == "" {
		user, err := modelhelper.GetUserById(spec.Machine.Users[0].Id.Hex())
		if err != nil {
			return err
		}
		spec.Machine.Users[0].Username = user.Name
	}

	// Lookup group and init Uid.
	group, err := modelhelper.GetGroupById(spec.Machine.Groups[0].Id.Hex())
	if err != nil {
		return err
	}

	spec.Machine.Uid = fmt.Sprintf("u%c%c%c",
		spec.Machine.Users[0].Username[0],
		group.Slug[0],
		spec.Machine.Provider[0],
	)

	m, err := modelhelper.GetMachineBySlug(spec.Machine.Users[0].Id, spec.Machine.Slug)
	if err == mgo.ErrNotFound {
		return nil
	}
	if err != nil {
		return err
	}

	switch m.State() {
	case machinestate.Building, machinestate.Starting:
		return ErrAlreadyBuilding
	case machinestate.Running:
		return ErrAlreadyRunning
	case machinestate.NotInitialized:
		spec.Machine.ObjectId = m.ObjectId
		return ErrRebuild
	default:
		return fmt.Errorf("machine state is %q; needs to be deleted and build "+
			"again (jMachine.ObjectId = %q)", m.State(), m.ObjectId.Hex())
	}
}
Beispiel #3
0
// RemoveUsersFromMachine removes the collaboraters from the host machine
func (c *Controller) RemoveUsersFromMachine(ping *models.Ping, toBeRemovedUsers []bson.ObjectId) error {
	// if channel id is nil, there is nothing to do
	if ping.ChannelId == 0 {
		return nil
	}

	ws, err := modelhelper.GetWorkspaceByChannelId(strconv.FormatInt(ping.ChannelId, 10))
	if err != nil {
		return filterErr(err)
	}

	m, err := modelhelper.GetMachineByUid(ws.MachineUID)
	if err != nil {
		return filterErr(err)
	}

	// Get the klient.
	klientRef, err := klient.ConnectTimeout(c.kite, m.QueryString, time.Second*10)
	if err != nil {
		if err == klient.ErrDialingFailed || err == kite.ErrNoKitesAvailable {
			c.log.Error(
				"[%s] Klient is not registered to Kontrol. Err: %s",
				m.QueryString,
				err,
			)

			return nil // if the machine is not open, we cant do anything
		}

		return err
	}
	defer klientRef.Close()

	type args struct {
		Username string

		// we are not gonna use this propery here, just for reference
		// Permanent bool
	}

	var iterErr error

	for _, toBeDeletedUser := range toBeRemovedUsers {

		// fetch user for its username
		u, err := modelhelper.GetUserById(toBeDeletedUser.Hex())
		if err != nil {
			c.log.Error("couldnt get user", err.Error())

			// if we cant find the regarding user, do not do anything
			if err == mgo.ErrNotFound {
				continue
			}

			iterErr = err

			continue // do not stop iterating, unshare from others
		}

		param := args{
			Username: u.Name,
		}

		_, err = klientRef.Client.Tell("klient.unshare", param)
		if err != nil {
			c.log.Error("couldnt unshare %+v", err.Error())

			// those are so error prone, force klient side not to change the API
			// or make them exported to some other package?
			if strings.Contains(err.Error(), "user is permanent") {
				continue
			}

			if strings.Contains(err.Error(), "user is not in the shared list") {
				continue
			}

			if strings.Contains(err.Error(), "User not found") {
				continue
			}

			iterErr = err

			continue // do not stop iterating, unshare from others
		}
	}

	res, err := klientRef.Client.Tell("klient.shared", nil)
	if err == nil {
		c.log.Info("other users in the machine: %+v", res.MustString())
	}

	// iterErr will be nil if we dont encounter to any error in iter
	return iterErr

}