Beispiel #1
0
func TestUnsetSocialChannelFromWorkspace(t *testing.T) {
	db := modeltesthelper.NewMongoDB(t)
	defer db.Close()

	rand.Seed(time.Now().UnixNano())

	w, err := createWorkspace()
	if err != nil {
		t.Fatalf(err.Error())
	}

	// first fetch it
	w2, err := modelhelper.GetWorkspaceByChannelId(w.ChannelId)
	if err != nil {
		t.Errorf(err.Error())
	}

	if w2 == nil {
		t.Errorf("couldnt fetch workspace by channel id got nil, expected: %+v", w)
	}

	if w2.ObjectId.Hex() != w.ObjectId.Hex() {
		t.Errorf("workspaces are not same: expected: %+v, got: ", w)
	}

	err = modelhelper.UnsetSocialChannelFromWorkspace(w.ObjectId)
	if err != nil {
		t.Errorf("we should be able to unset social channel id")
	}

	_, err = modelhelper.GetWorkspaceByChannelId(w.ChannelId)
	if err == nil {
		t.Errorf("we should not be able to find the WS")
	}
}
Beispiel #2
0
func TestGetWorkspaceByChannelId(t *testing.T) {
	db := modeltesthelper.NewMongoDB(t)
	defer db.Close()

	rand.Seed(time.Now().UnixNano())

	w, err := createWorkspace()
	if err != nil {
		t.Fatalf(err.Error())
	}

	w2, err := modelhelper.GetWorkspaceByChannelId(w.ChannelId)
	if err != nil {
		t.Errorf(err.Error())
	}

	if w2 == nil {
		t.Errorf("couldnt fetch workspace by channel id got nil, expected: %+v", w)
	}

	if w2.ObjectId.Hex() != w.ObjectId.Hex() {
		t.Errorf("workspaces are not same: expected: %+v, got: ", w)
	}

	_, err = modelhelper.GetWorkspaceByChannelId(strconv.FormatInt(rand.Int63(), 10))
	if err == nil {
		t.Errorf("we should not be able to find the WS")
	}
}
Beispiel #3
0
// UnshareVM removes the users from JMachine document
func (c *Controller) UnshareVM(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)
	}

	if len(toBeRemovedUsers) == 0 {
		return nil // no one to remove
	}

	return modelhelper.RemoveUsersFromMachineByIds(ws.MachineUID, toBeRemovedUsers)
}
Beispiel #4
0
// EndPrivateMessage stops the collaboration session and deletes the all
// messages from db
func (c *Controller) EndPrivateMessage(ping *models.Ping) error {
	// if channel id is nil, there is nothing to do
	if ping.ChannelId == 0 {
		return nil
	}

	// fetch the channel
	channel := socialapimodels.NewChannel()
	if err := channel.ById(ping.ChannelId); err != nil {
		// if channel is not there, do not do anyting
		if err == bongo.RecordNotFound {
			return nil
		}

		return err
	}

	canOpen, err := channel.CanOpen(ping.AccountId)
	if err != nil {
		return err
	}

	if !canOpen {
		return nil // if the requester can not open the channel do not process
	}

	// delete the channel
	err = channel.Delete()
	if err != nil {
		return err
	}

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

	return modelhelper.UnsetSocialChannelFromWorkspace(ws.ObjectId)
}
Beispiel #5
0
func TestCollaborationOperationsEndPrivateMessage(t *testing.T) {
	r := runner.New("collaboration-EndPrivateMessage-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 EndPrivateMessage", t, func() {
		req := &models.Ping{
			AccountId: 1,
			FileId:    fmt.Sprintf("%d", rand.Int63()),
		}
		Convey("should be able to create the channel first", func() {
			creator := socialapimodels.CreateAccountWithTest() // init account
			c := socialapimodels.NewChannel()                  // init channel
			c.CreatorId = creator.Id                           // set Creator id
			c.TypeConstant = socialapimodels.Channel_TYPE_COLLABORATION
			So(c.Create(), ShouldBeNil)
			cp, err := c.AddParticipant(creator.Id)
			So(err, ShouldBeNil)
			So(cp, ShouldNotBeNil)

			req.AccountId = c.CreatorId // set real account id
			req.ChannelId = c.Id        // set real channel id

			ws := &mongomodels.Workspace{
				ObjectId:     bson.NewObjectId(),
				OriginId:     bson.NewObjectId(),
				Name:         "My Workspace",
				Slug:         "my-workspace",
				ChannelId:    strconv.FormatInt(req.ChannelId, 10),
				MachineUID:   bson.NewObjectId().Hex(),
				MachineLabel: "koding-vm-0",
				Owner:        "cihangir",
				RootPath:     "/home/cihangir",
				IsDefault:    true,
			}

			So(modelhelper.CreateWorkspace(ws), ShouldBeNil)

			Convey("should be able to delete channel", func() {
				err = handler.EndPrivateMessage(req)
				So(err, ShouldBeNil)
				Convey("deleted channel should not be exist", func() {
					channel := socialapimodels.NewChannel()
					err := channel.ById(req.ChannelId)
					So(err, ShouldEqual, bongo.RecordNotFound)
				})
				Convey("channel id in workspace should not be exist", func() {
					ws2, err := modelhelper.GetWorkspaceByChannelId(
						strconv.FormatInt(req.ChannelId, 10),
					)
					So(err, ShouldEqual, mgo.ErrNotFound)
					So(ws2, ShouldEqual, nil)
				})
			})

			Convey("if not a participant, should not be able to delete channel", func() {
				req.AccountId = 1
				err = handler.EndPrivateMessage(req)
				So(err, ShouldBeNil)
				Convey("channel should exist", func() {
					channel := socialapimodels.NewChannel()
					err := channel.ById(req.ChannelId)
					So(err, ShouldBeNil)
				})
			})

			Convey("if channel doesnt exists, should success", func() {
				req.ChannelId = 1
				err = handler.EndPrivateMessage(req)
				So(err, ShouldBeNil)
				Convey("channel should not exist", func() {
					channel := socialapimodels.NewChannel()
					err := channel.ById(req.ChannelId)
					So(err, ShouldEqual, bongo.RecordNotFound)
				})
			})
		})
	})
}
Beispiel #6
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
}
Beispiel #7
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

}