Пример #1
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())
							})
						})
					})
				})
			})
		})
	})
}
Пример #2
0
func prepareSingleWorkspace(creator, participant1, participant2 *socialapimodels.Account) (
	*mongomodels.Machine, // m1
	*mongomodels.Workspace, // m1 ws1
) {

	ownerUser, err := modelhelper.GetUserByAccountId(creator.OldId)
	So(err, ShouldBeNil)

	participant1User, err := modelhelper.GetUserByAccountId(participant1.OldId)
	So(err, ShouldBeNil)

	participant2User, err := modelhelper.GetUserByAccountId(participant2.OldId)
	So(err, ShouldBeNil)

	// sample  machine struct
	m1 := &mongomodels.Machine{
		ObjectId: bson.NewObjectId(),
		Uid:      bson.NewObjectId().Hex(),
		Users: []mongomodels.MachineUser{
			{ // real owner
				Id:    ownerUser.ObjectId,
				Sudo:  true,
				Owner: true,
			},
			{ // secondary owner
				Id:        participant1User.ObjectId,
				Sudo:      false,
				Owner:     true,
				Permanent: false,
			},
			{ // random
				Id:        participant2User.ObjectId,
				Sudo:      false,
				Owner:     true,
				Permanent: false,
			},
		},
		CreatedAt: time.Now().UTC(),
		Status: mongomodels.MachineStatus{
			State:      "running",
			ModifiedAt: time.Now().UTC(),
		},
		Assignee:    mongomodels.MachineAssignee{},
		UserDeleted: false,
	}

	So(modelhelper.CreateMachine(m1), ShouldBeNil)

	//
	// create the first channel
	//
	c1 := socialapimodels.NewChannel() // init channel
	c1.CreatorId = creator.Id          // set Creator id
	c1.TypeConstant = socialapimodels.Channel_TYPE_COLLABORATION
	So(c1.Create(), ShouldBeNil)

	c1p1, err := c1.AddParticipant(creator.Id)
	So(err, ShouldBeNil)
	So(c1p1, ShouldNotBeNil)

	c1p2, err := c1.AddParticipant(participant1.Id)
	So(err, ShouldBeNil)
	So(c1p2, ShouldNotBeNil)

	c1p3, err := c1.AddParticipant(participant2.Id)
	So(err, ShouldBeNil)
	So(c1p3, ShouldNotBeNil)

	m1ws1 := &mongomodels.Workspace{
		ObjectId:     bson.NewObjectId(),
		OriginId:     bson.ObjectIdHex(creator.OldId),
		Name:         "My Workspace",
		Slug:         "m1ws1",
		ChannelId:    strconv.FormatInt(c1.Id, 10),
		MachineUID:   m1.Uid,
		MachineLabel: "koding-vm-0",
		Owner:        "cihangir",
		RootPath:     "/home/cihangir",
		IsDefault:    true,
	}

	So(modelhelper.CreateWorkspace(m1ws1), ShouldBeNil)

	return m1, m1ws1
}
Пример #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
}