Пример #1
0
func deleteWorkspaces(res interface{}) error {
	ws := res.(*models.Workspace)

	_, err := helper.GetMachineByUid(ws.MachineUID)
	if err == mgo.ErrNotFound {
		fmt.Printf("deleting WS with UID (corresponding machine does not exist) %q\n", ws.ObjectId.Hex())
		if !*flagDry {
			return helper.RemoveWorkspace(ws.ObjectId)
		}
	}

	if !getAccountByID(ws.OriginId.Hex()) {
		fmt.Printf("deleting WS with owner (corresponding acc does not exist) %q\n", ws.ObjectId.Hex())
		if !*flagDry {
			return helper.RemoveWorkspace(ws.ObjectId)
		}
	}

	return nil
}
Пример #2
0
func TestUnshareMachine(t *testing.T) {
	db := modeltesthelper.NewMongoDB(t)
	defer db.Close()

	m := createMachine(t)
	defer modelhelper.DeleteMachine(m.ObjectId)

	if err := modelhelper.UnshareMachineByUid(m.Uid); err != nil {
		t.Error(err)
	}

	m2, err := modelhelper.GetMachineByUid(m.Uid)
	if err != nil {
		t.Error(err.Error())
	}

	if len(m2.Users) != 1 {
		t.Errorf("user count should be 1, got: %d", len(m2.Users))
	}

	if !(m2.Users[0].Sudo && m2.Users[0].Owner) {
		t.Errorf("only owner should have sudo and owner priv.")
	}
}
Пример #3
0
func (c *Controller) findToBeRemovedUsers(ping *models.Ping) ([]bson.ObjectId, error) {
	ws, err := modelhelper.GetWorkspaceByChannelId(
		strconv.FormatInt(ping.ChannelId, 10),
	)
	if err != nil {
		return nil, filterErr(err)
	}

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

	ownerMachineUser := machine.Owner()
	if ownerMachineUser == nil {
		c.log.Critical("owner couldnt found %+v", ping)
		return nil, nil // if we cant find the owner, we cant process the users
	}

	ownerAccount, err := modelhelper.GetAccountByUserId(ownerMachineUser.Id)
	if err != nil {
		return nil, filterErr(err)
	}

	//	get workspaces of the owner
	ownersWorkspaces, err := modelhelper.GetWorkspaces(ownerAccount.Id)
	if err != nil {
		return nil, filterErr(err)
	}

	users := partitionUsers(ownerAccount, ownersWorkspaces, ws)

	var toBeRemovedUsers []bson.ObjectId
	for accountID, count := range users {
		// if we count the user more than once, that means user is in another
		// workspace too
		if count > 1 {
			continue
		}

		u, err := modelhelper.GetUserByAccountId(accountID)
		if err != nil {
			return nil, err
		}

		toBeRemovedUsers = append(toBeRemovedUsers, u.ObjectId)
	}

	var filteredUsers []bson.ObjectId
	permanentUsers := make(map[string]struct{})
	for _, user := range machine.Users {
		if user.Permanent {
			permanentUsers[user.Id.Hex()] = struct{}{}
		}
	}

	for _, toBeRemovedUser := range toBeRemovedUsers {
		if _, ok := permanentUsers[toBeRemovedUser.Hex()]; !ok {
			filteredUsers = append(filteredUsers, toBeRemovedUser)
		}
	}

	return filteredUsers, nil
}
Пример #4
0
func TestCollaborationOperationsUnshareVM(t *testing.T) {
	r := runner.New("collaboration-UnshareVM-tests")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

	appConfig := config.MustRead(r.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	// init with defaults
	mongoCache := cache.NewMongoCacheWithTTL(modelhelper.Mongo.Session)
	defer mongoCache.StopGC()

	handler := New(r.Log, mongoCache, appConfig, r.Kite)

	Convey("while testing UnshareVM", t, func() {

		Convey("should be able to create the channel and workspace first", func() {

			Convey("should be able to UnshareVM", func() {

				creator, err := socialapimodels.CreateAccountInBothDbs() // init account
				So(err, ShouldBeNil)

				participant1, err := socialapimodels.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				participant2, err := socialapimodels.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				m1, m1ws1 := prepareSingleWorkspace(creator, participant1, participant2)

				channelId, err := strconv.ParseInt(m1ws1.ChannelId, 10, 64)
				So(err, ShouldBeNil)

				req1 := &models.Ping{
					AccountId: creator.Id,
					FileId:    fmt.Sprintf("%d", rand.Int63()),
					ChannelId: channelId,
				}

				toBeRemovedUsers, err := handler.findToBeRemovedUsers(req1)
				So(err, ShouldBeNil)
				So(toBeRemovedUsers, ShouldNotBeNil)

				err = handler.UnshareVM(req1, toBeRemovedUsers)
				So(err, ShouldBeNil)

				err = handler.EndPrivateMessage(req1)
				So(err, ShouldBeNil)

				Convey("remove users should not be in the machine", func() {
					mm1, err := modelhelper.GetMachineByUid(m1.Uid)
					So(err, ShouldBeNil)
					So(mm1, ShouldNotBeNil)
					So(len(mm1.Users), ShouldEqual, 1)
					ownerUser, err := modelhelper.GetUserByAccountId(creator.OldId)
					So(err, ShouldBeNil)
					So(mm1.Users[0].Id.Hex(), ShouldEqual, ownerUser.ObjectId.Hex())
				})
			})

			Convey("if participant and owner shares multiple workspaces", func() {

				creator, err := socialapimodels.CreateAccountInBothDbs() // init account
				So(err, ShouldBeNil)

				participant1, err := socialapimodels.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				participant2, err := socialapimodels.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				participant3, err := socialapimodels.CreateAccountInBothDbs()
				So(err, ShouldBeNil)

				_, _, m2, m2ws1, m2ws2 := prepareWorkspace(creator, participant1, participant2, participant3)

				Convey("remove from first workspace", func() {
					channelId, err := strconv.ParseInt(m2ws1.ChannelId, 10, 64)
					So(err, ShouldBeNil)

					req := &models.Ping{
						AccountId: creator.Id,
						FileId:    fmt.Sprintf("%d", rand.Int63()),
						ChannelId: channelId,
					}

					toBeRemovedUsers, err := handler.findToBeRemovedUsers(req)
					So(err, ShouldBeNil)
					So(toBeRemovedUsers, ShouldNotBeNil)

					err = handler.UnshareVM(req, toBeRemovedUsers)
					So(err, ShouldBeNil)

					err = handler.EndPrivateMessage(req)
					So(err, ShouldBeNil)

					Convey("participants should still be in the second machine", func() {
						mm2, err := modelhelper.GetMachineByUid(m2.Uid)
						So(err, ShouldBeNil)
						So(mm2, ShouldNotBeNil)
						So(len(mm2.Users), ShouldEqual, 3)

						// participant1 is not in the second WS, so it should be removed from the machine
						ownerUser, err := modelhelper.GetUserByAccountId(creator.OldId)
						So(err, ShouldBeNil)
						So(mm2.Users[0].Id.Hex(), ShouldEqual, ownerUser.ObjectId.Hex())

						participant2User, err := modelhelper.GetUserByAccountId(participant2.OldId)
						So(err, ShouldBeNil)
						So(mm2.Users[1].Id.Hex(), ShouldEqual, participant2User.ObjectId.Hex())

						participant3User, err := modelhelper.GetUserByAccountId(participant3.OldId)
						So(err, ShouldBeNil)
						So(mm2.Users[2].Id.Hex(), ShouldEqual, participant3User.ObjectId.Hex())

						Convey("after removing from second WS", func() {
							// remove from second WS too
							channelId, err := strconv.ParseInt(m2ws2.ChannelId, 10, 64)
							So(err, ShouldBeNil)

							req := &models.Ping{
								AccountId: creator.Id,
								FileId:    fmt.Sprintf("%d", rand.Int63()),
								ChannelId: channelId,
							}

							toBeRemovedUsers, err := handler.findToBeRemovedUsers(req)
							So(err, ShouldBeNil)
							So(toBeRemovedUsers, ShouldNotBeNil)

							err = handler.UnshareVM(req, toBeRemovedUsers)
							So(err, ShouldBeNil)

							err = handler.EndPrivateMessage(req)
							So(err, ShouldBeNil)

							Convey("owner and permanent should still stay", func() {
								mm2, err := modelhelper.GetMachineByUid(m2.Uid)
								So(err, ShouldBeNil)
								So(mm2, ShouldNotBeNil)
								So(len(mm2.Users), ShouldEqual, 2)

								ownerUser, err := modelhelper.GetUserByAccountId(creator.OldId)
								So(err, ShouldBeNil)
								So(mm2.Users[0].Id.Hex(), ShouldEqual, ownerUser.ObjectId.Hex())

								participant1User, err := modelhelper.GetUserByAccountId(participant3.OldId)
								So(err, ShouldBeNil)
								So(mm2.Users[1].Id.Hex(), ShouldEqual, participant1User.ObjectId.Hex())
							})
						})
					})
				})
			})
		})
	})
}
Пример #5
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

}