예제 #1
0
파일: group.go 프로젝트: koding/koding
func (cmd *GroupStack) details(username string) (*modelhelper.StackDetails, error) {
	user, err := modelhelper.GetUser(username)
	if err != nil {
		return nil, fmt.Errorf("unable to find a user %q: %s", username, err)
	}

	group, err := modelhelper.GetGroup(cmd.groupSlug)
	if err != nil {
		return nil, fmt.Errorf("unable to find a group %q: %s", cmd.groupSlug, err)
	}

	machine, err := modelhelper.GetMachineBySlug(user.ObjectId, cmd.machineSlug)
	if err != nil {
		return nil, fmt.Errorf("unable to find a machine slug=%q, userID=%q: %s", cmd.machineSlug, user.ObjectId.Hex(), err)
	}

	account, err := modelhelper.GetAccount(username)
	if err != nil {
		return nil, fmt.Errorf("unable to find an account for %q: %s", username, err)
	}

	sd := &modelhelper.StackDetails{
		UserID:    user.ObjectId,
		AccountID: account.Id,
		GroupID:   group.Id,

		UserName:  user.Name,
		GroupSlug: group.Slug,

		MachineID: machine.ObjectId,
		BaseID:    bson.ObjectIdHex(cmd.baseID),
	}

	return sd, nil
}
예제 #2
0
func getUserByNick(nick string) bool {
	if _, err := existingUserByNick.Get(nick); err == nil {
		return true
	}

	if _, err := deletedUserByNick.Get(nick); err == nil {
		return false
	}

	user, err := helper.GetUser(nick)
	if err == mgo.ErrNotFound {
		deletedUserByNick.Set(nick, struct{}{})
		return false
	}

	// treat them as existing on random errors
	if err != nil {
		fmt.Printf("err while getting user by nick %q, %s\n", nick, err.Error())
		return true
	}

	if user.Status == "deleted" {
		deletedUserByNick.Set(nick, struct{}{})
		return false
	}

	id := user.ObjectId.Hex()
	existingUserByID.Set(id, struct{}{})
	existingUserByNick.Set(user.Name, id)

	return true
}
예제 #3
0
파일: user_test.go 프로젝트: koding/koding
func TestBlockUser(t *testing.T) {
	db := modeltesthelper.NewMongoDB(t)
	defer db.Close()

	username, blockedReason := "testuser", "testing"

	user := &models.User{
		Name: username, ObjectId: bson.NewObjectId(), Status: models.UserBlocked,
	}

	defer func() {
		modelhelper.RemoveUser(username)
	}()

	err := modelhelper.CreateUser(user)
	if err != nil {
		t.Error(err)
	}

	err = modelhelper.BlockUser(username, blockedReason, 1*time.Hour)
	if err != nil {
		t.Error(err)
	}

	user, err = modelhelper.GetUser(username)
	if err != nil {
		t.Error(err)
	}

	if user.Status != models.UserBlocked {
		t.Errorf("User status is not blocked")
	}

	if user.BlockedReason != blockedReason {
		t.Errorf("User blocked reason is not: %s", blockedReason)
	}

	if user.BlockedUntil.IsZero() {
		t.Errorf("User blocked until date is not set")
	}

	id, err := modelhelper.GetUserID(user.Name)
	if err != nil {
		t.Fatalf("GetUserID()=%s", err)
	}

	if id != user.ObjectId {
		t.Fatalf("got %q, want %q", id.Hex(), user.ObjectId.Hex())
	}
}
예제 #4
0
파일: group.go 프로젝트: koding/koding
func (cmd *GroupClean) user(user string) (*models.User, error) {
	u, ok := cmd.uCache[user]
	if ok {
		return u, nil
	}

	u, err := modelhelper.GetUser(user)
	if err != nil {
		return nil, err
	}

	cmd.uCache[user] = u
	return u, nil
}
예제 #5
0
// Success handler is used for handling redirection requests from Callback handler
//
// We need this for handling the internal redirection of team requests
func (s *Slack) Success(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	errMessage := u.Query().Get("error")
	if len(errMessage) > 0 {
		h.Set("Location", "/Home/My-Team/Slack?error="+url.QueryEscape(errMessage))
		return http.StatusTemporaryRedirect, h, nil, nil
	}

	// get session data from state
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	// get user info
	user, err := modelhelper.GetUser(session.Username)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	// start exchanging code for a token
	code := u.Query().Get("code")
	if code == "" {
		return response.NewBadRequest(errors.New("code is not set"))
	}

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// update the slack data
	if err := updateUserSlackToken(user, session.GroupName, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	h.Set("Location", "/Home/My-Team/Slack")
	return http.StatusTemporaryRedirect, h, nil, nil
}
예제 #6
0
func populateCustomerParams(username, groupName string, initial *stripe.CustomerParams) (*stripe.CustomerParams, error) {
	if username == "" {
		return nil, socialapimodels.ErrNickIsNotSet
	}

	if groupName == "" {
		return nil, socialapimodels.ErrGroupNameIsNotSet
	}

	if initial == nil {
		initial = &stripe.CustomerParams{}
	}

	// whitelisted parameters
	req := &stripe.CustomerParams{
		Token:  initial.Token,
		Coupon: initial.Coupon,
		Source: initial.Source,
		Desc:   initial.Desc,
		Email:  initial.Email,
		Params: initial.Params,
		// plan can not be updated by hand, do not add it to whilelist. It should
		// only be updated automatically on invoice applications
		// Plan: initial.Plan,
	}

	user, err := modelhelper.GetUser(username)
	if err != nil {
		return nil, err
	}

	if req.Desc == "" {
		req.Desc = fmt.Sprintf("%s team", groupName)
	}
	if req.Email == "" {
		req.Email = user.Email
	}

	if req.Params.Meta == nil {
		req.Params.Meta = make(map[string]string)
	}
	req.Params.Meta["groupName"] = groupName
	req.Params.Meta["username"] = username

	return req, nil
}
예제 #7
0
func sendEventForCustomer(customerID string, eventName string, options map[string]interface{}) error {
	cus, err := customer.Get(customerID, nil)
	if err != nil {
		return err
	}

	if options == nil {
		options = make(map[string]interface{})
	}

	for key, val := range cus.Meta {
		options[key] = val
	}

	admins, err := modelhelper.FetchAdminAccounts(cus.Meta["groupName"])
	if err == mgo.ErrNotFound {
		return nil
	}

	if err != nil {
		return err
	}

	for _, admin := range admins {
		user, err := modelhelper.GetUser(admin.Profile.Nickname)
		if err != nil {
			return err
		}

		mail := &emailsender.Mail{
			To:      user.Email,
			Subject: eventName,
			Properties: &emailsender.Properties{
				Username: user.Name,
				Options:  options,
			},
		}

		if err := mailSender(mail); err != nil {
			return err
		}
	}

	return nil
}
예제 #8
0
func TestGetSocialIdFromEmail(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

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

	Convey("while getting account id in the mail", t, func() {
		Convey("From fields should be saved in db, otherwise return err", func() {

			m := &Mail{
				From: "mailisnotexist@abo",
			}

			gid, err := m.getSocialIdFromEmail()
			So(err, ShouldNotBeNil)
			So(err, ShouldEqual, ErrEmailIsNotFetched)
			So(gid, ShouldEqual, 0)
		})

		Convey("should not be any error if all is well", func() {

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

			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			m := &Mail{
				From: mongoUser.Email,
			}

			gid, err := m.getSocialIdFromEmail()
			So(err, ShouldBeNil)
			So(gid, ShouldEqual, acc.Id)

		})

	})
}
예제 #9
0
파일: user.go 프로젝트: koding/koding
func DeleteUsersAndMachines(username string) error {
	user, err := modelhelper.GetUser(username)
	if err != nil {
		return err
	}

	err = DeleteUsersByUsername(username)
	if err != nil {
		return err
	}

	deleteQuery := func(c *mgo.Collection) error {
		_, err := c.RemoveAll(bson.M{"users.id": user.ObjectId})
		return err
	}

	return modelhelper.Mongo.Run(modelhelper.MachinesColl, deleteQuery)
}
예제 #10
0
func TestGetAccount(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

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

	Convey("while testing get account", t, func() {
		Convey("returns empty if parameter is invalid", func() {
			acc, err := GetAccount("interestingEmail@somethinglikethat")
			So(err, ShouldNotBeNil)
			So(acc, ShouldBeNil)
		})

		Convey("returns empty if parameter is empty", func() {
			acc, err := GetAccount("")
			So(err, ShouldNotBeNil)
			So(acc, ShouldBeNil)
		})

		Convey("Should return blank if parameter is empty", func() {
			acc, err := socialapimodels.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			m := &Mail{
				From: mongoUser.Email,
			}
			ga, err := GetAccount(m.From)
			So(err, ShouldBeNil)
			So(ga, ShouldNotBeNil)
		})

	})
}
예제 #11
0
func TestMailParse(t *testing.T) {
	r := runner.New("test")
	err := r.Init()
	if err != nil {
		panic(err)
	}

	defer r.Close()

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

	Convey("while sending mail", t, func() {

		Convey("reponse should be success", func() {
			acc, err := socialapimodels.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			c := socialapimodels.CreateChannelWithTest(acc.Id)
			socialapimodels.AddParticipantsWithTest(c.Id, acc.Id)

			cm := socialapimodels.CreateMessage(c.Id, acc.Id, socialapimodels.ChannelMessage_TYPE_POST)
			So(cm, ShouldNotBeNil)

			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			p := &models.Mail{
				From:              mongoUser.Email,
				OriginalRecipient: fmt.Sprintf("*****@*****.**", c.Id),
				MailboxHash:       fmt.Sprintf("messageid.%d", cm.Id),
				TextBody:          "Its an example of text message",
				StrippedTextReply: "This one is reply message",
			}

			res, err := rest.MailParse(p)
			So(err, ShouldBeNil)
			So(res, ShouldNotBeNil)
		})
	})
}
예제 #12
0
// getSlackToken fetches the user's slack token with user's accountID
func getSlackToken(context *models.Context) (string, error) {
	var token string

	user, err := modelhelper.GetUser(context.Client.Account.Nick)
	if err != nil {
		return token, err
	}

	groupName := context.GroupName

	if user.ForeignAuth.Slack != nil {
		if gName, ok := user.ForeignAuth.Slack[groupName]; ok {
			if gName.Token != "" {
				return gName.Token, nil
			}
		}
	}

	return token, models.ErrTokenIsNotFound

}
예제 #13
0
func (c *Controller) getUserInfo(m *Mail) *eventexporter.User {
	if m.To == "" {
		u, err := modelhelper.GetUser(m.Properties.Username)
		if err == nil {
			m.To = u.Email
		}
	}

	user := &eventexporter.User{Email: m.To}

	if c.forcedRecipientEmail != "" {
		user.Email = c.forcedRecipientEmail
	}

	user.Username = m.Properties.Username
	if c.forcedRecipientUsername != "" {
		user.Username = c.forcedRecipientUsername
	}

	return user
}
예제 #14
0
func (f *Controller) handleAccount(data *models.Account, cleanupGuest bool, tagMap map[string]interface{}) error {
	// do not send guests to algolia
	if strings.HasPrefix(data.Nick, "guest-") {
		if cleanupGuest {
			return f.delete(IndexAccounts, data.OldId)
		}

		return nil
	}

	user, err := modelhelper.GetUser(data.Nick)
	if err != nil && err != mgo.ErrNotFound {
		return err
	}

	if err == mgo.ErrNotFound {
		f.log.Error("user %+v is not found in mongodb", data)
		return nil
	}

	mongoaccount, err := modelhelper.GetAccount(data.Nick)
	if err != nil && err != mgo.ErrNotFound {
		return err
	}

	if err == mgo.ErrNotFound {
		f.log.Error("account %+v is not found in mongodb", data)
		return nil
	}

	return f.partialUpdate(IndexAccounts, map[string]interface{}{
		"objectID":  data.OldId,
		"nick":      data.Nick,
		"email":     user.Email,
		"firstName": mongoaccount.Profile.FirstName,
		"lastName":  mongoaccount.Profile.LastName,
		"_tags":     tagMap,
	})
}
예제 #15
0
파일: group.go 프로젝트: koding/koding
func (cmd *GroupFixDomain) fixDomain(user string) (*dnsclient.Record, bson.ObjectId, error) {
	u, err := modelhelper.GetUser(user)
	if err != nil {
		return nil, "", err
	}

	m, err := modelhelper.GetMachineBySlug(u.ObjectId, cmd.machine)
	if err != nil {
		return nil, "", fmt.Errorf("fixing failed for %q user: %s", user, err)
	}

	if m.IpAddress == "" {
		return nil, "", errors.New("no ip address found for: " + user)
	}

	base := dnsZones[cmd.env]

	if strings.HasSuffix(m.Domain, base) {
		return nil, "", nil
	}

	if cmd.dry && m.State() != machinestate.Running {
		DefaultUi.Warn(fmt.Sprintf("machine %q of user %q is not running (%s)",
			m.ObjectId.Hex(), user, m.State()))
	}

	s := m.Domain
	if i := strings.Index(s, user); i != -1 {
		s = s[i+len(user):] + "." + base
	}

	return &dnsclient.Record{
		Name: s,
		IP:   m.IpAddress,
		Type: "A",
		TTL:  300,
	}, m.ObjectId, nil
}
예제 #16
0
파일: user_test.go 프로젝트: koding/koding
func TestRemoveUser(t *testing.T) {
	db := modeltesthelper.NewMongoDB(t)
	defer db.Close()

	username := "******"
	user := &models.User{
		Name: username, ObjectId: bson.NewObjectId(),
	}

	err := modelhelper.CreateUser(user)
	if err != nil {
		t.Error(err)
	}

	err = modelhelper.RemoveUser(username)
	if err != nil {
		t.Error(err)
	}

	user, err = modelhelper.GetUser(username)
	if err == nil {
		t.Errorf("User should've been deleted, but wasn't")
	}
}
예제 #17
0
func CreateAccountInBothDbsWithNick(nick string) (*Account, error) {
	accId := bson.NewObjectId()
	accHex := nick

	oldAcc, err := modelhelper.GetAccount(nick)
	if err == mgo.ErrNotFound {

		oldAcc = &kodingmodels.Account{
			Id: accId,
			Profile: struct {
				Nickname  string `bson:"nickname" json:"nickname"`
				FirstName string `bson:"firstName" json:"firstName"`
				LastName  string `bson:"lastName" json:"lastName"`
				Hash      string `bson:"hash" json:"hash"`
			}{
				Nickname: nick,
			},
		}

		err := modelhelper.CreateAccount(oldAcc)
		if err != nil {
			return nil, err
		}
	}

	oldUser, err := modelhelper.GetUser(nick)
	if err == mgo.ErrNotFound {
		oldUser = &kodingmodels.User{
			ObjectId:       bson.NewObjectId(),
			Password:       accHex,
			Salt:           accHex,
			Name:           nick,
			Email:          accHex + "@koding.com",
			Status:         "confirmed",
			EmailFrequency: &kodingmodels.EmailFrequency{},
		}

		err = modelhelper.CreateUser(oldUser)
		if err != nil {
			return nil, err
		}
	}

	a := NewAccount()
	a.Nick = nick
	a.OldId = accId.Hex()

	if err := a.ByNick(nick); err == bongo.RecordNotFound {
		if err := a.Create(); err != nil {
			return nil, err
		}
	}

	if oldAcc.SocialApiId != strconv.FormatInt(a.Id, 10) {
		s := modelhelper.Selector{"_id": oldAcc.Id}
		o := modelhelper.Selector{"$set": modelhelper.Selector{
			"socialApiId": strconv.FormatInt(a.Id, 10),
		}}

		if err := modelhelper.UpdateAccount(s, o); err != nil {
			return nil, err
		}
	}

	return a, nil
}
예제 #18
0
func TestAccountTesting(t *testing.T) {
	runner, handler := getTestHandler()
	defer runner.Close()

	// init mongo connection
	appConfig := config.MustRead(runner.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	Convey("given some fake account", t, func() {
		acc, _, name := models.CreateRandomGroupDataWithChecks()
		So(name, ShouldNotBeNil)
		So(acc, ShouldNotBeNil)

		Convey("it should save the document to algolia", func() {
			err := handler.AccountCreated(acc)
			So(err, ShouldBeNil)

			Convey("it should be able to fetch algolia data", func() {
				// make sure account is there
				So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

				_, err = modelhelper.GetUser(acc.Nick)
				So(err, ShouldBeNil)

				// update user's email
				selector := bson.M{"username": acc.Nick}
				newEmail := "mehmetalixsavasx1x2x" + models.RandomGroupName() + "@koding.com"
				updateQuery := bson.M{"email": newEmail}

				err = modelhelper.UpdateUser(selector, updateQuery)
				So(err, ShouldBeNil)

				err = handler.AccountUpdated(acc)
				So(err, ShouldBeNil)

				index, err := handler.indexes.GetIndex(IndexAccounts)
				So(err, ShouldBeNil)

				params := make(map[string]interface{})
				record, err := index.Search("mehmetalixsavasx1x2x", params)
				So(err, ShouldBeNil)

				hist, ok := record.(map[string]interface{})["hits"]

				usernames := make([]string, 0)
				objects := make([]string, 0)

				if ok {
					hinter, ok := hist.([]interface{})
					if ok {
						for _, v := range hinter {
							val, k := v.(map[string]interface{})
							if k {
								object := val["objectID"].(string)
								value := val["nick"].(string)

								usernames = append(usernames, value)
								objects = append(objects, object)

								_, err = index.DeleteObject(object)
								So(err, ShouldBeNil)
							}

						}
					}
				}

				So(usernames, ShouldNotBeNil)
				So(objects, ShouldNotBeNil)

			})

			Convey("it should be able to fetch many account with given query", func() {
				So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

				// we create 10 acc for algolia test
				for i := 0; i < 10; i++ {
					ac, _, _ := models.CreateRandomGroupDataWithChecks()

					err := handler.AccountCreated(ac)
					So(err, ShouldBeNil)

					selector := bson.M{"username": ac.Nick}
					newEmail := "mehmetali-test" + models.RandomGroupName() + "@koding.com"
					updateQuery := bson.M{"email": newEmail}
					err = modelhelper.UpdateUser(selector, updateQuery)
					So(err, ShouldBeNil)

					err = handler.AccountUpdated(ac)
					So(err, ShouldBeNil)
					time.Sleep(1 * time.Second)
				}

				//required for getting algolia datas correctly
				time.Sleep(5 * time.Second)

				_, err = modelhelper.GetUser(acc.Nick)
				So(err, ShouldBeNil)

				index, err := handler.indexes.GetIndex(IndexAccounts)
				So(err, ShouldBeNil)

				params := make(map[string]interface{})
				record, err := index.Search("mehmetali-test", params)
				So(err, ShouldBeNil)

				hist, ok := record.(map[string]interface{})["hits"]

				usernames := make([]string, 0)
				objects := make([]string, 0)

				if ok {
					hinter, ok := hist.([]interface{})
					if ok {
						for _, v := range hinter {
							val, k := v.(map[string]interface{})
							if k {
								object := val["objectID"].(string)
								value := val["nick"].(string)

								usernames = append(usernames, value)
								objects = append(objects, object)
							}

						}
					}
				}

				So(len(usernames), ShouldBeGreaterThan, 0)
				So(len(objects), ShouldBeGreaterThan, 0)

				Convey("it should be able to delete many account with given query", func() {

					So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

					for i := 0; i < 10; i++ {
						ac, _, _ := models.CreateRandomGroupDataWithChecks()

						err := handler.AccountCreated(ac)
						So(err, ShouldBeNil)

						selector := bson.M{"username": ac.Nick}
						newEmail := "mehmetali-test" + models.RandomGroupName() + "@koding.com"
						updateQuery := bson.M{"email": newEmail}
						err = modelhelper.UpdateUser(selector, updateQuery)
						So(err, ShouldBeNil)

						err = handler.AccountUpdated(ac)
						So(err, ShouldBeNil)
						time.Sleep(1 * time.Second)
					}

					time.Sleep(5 * time.Second)

					_, err = modelhelper.GetUser(acc.Nick)
					So(err, ShouldBeNil)

					_, err := handler.indexes.GetIndex(IndexAccounts)
					So(err, ShouldBeNil)

					usernames := make([]string, 0)
					objects := make([]string, 0)

					nbHits, _ := record.(map[string]interface{})["nbHits"]
					nbPages, _ := record.(map[string]interface{})["nbPages"]

					var pages float64 = nbPages.(float64)
					var nbHit float64 = nbHits.(float64)

					for pages > 0 && nbHit != 0 {
						record, err := index.Search("mehmetali-test", params)
						hist, ok := record.(map[string]interface{})["hits"]

						// fmt.Println("hist is :", hist)
						nbHits, _ := record.(map[string]interface{})["nbHits"]
						nbPages, _ := record.(map[string]interface{})["nbPages"]

						pages = nbPages.(float64)
						nbHit = nbHits.(float64)

						if ok {
							hinter, ok := hist.([]interface{})
							if ok {
								for _, v := range hinter {
									val, k := v.(map[string]interface{})
									if k {
										object := val["objectID"].(string)
										value := val["nick"].(string)

										usernames = append(usernames, value)
										objects = append(objects, object)
										_, err = index.DeleteObject(object)
										So(err, ShouldBeNil)
									}

								}
							}
						}
					}

					lenghtUsernames := len(usernames)
					lenghtObjects := len(objects)
					So(lenghtUsernames, ShouldBeGreaterThan, 10)
					So(lenghtObjects, ShouldBeGreaterThan, 10)

				})

				Convey("it should have delete algolia accounts", func() {
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					fmt.Println("it should have delete algolia accounts")
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					fmt.Println("=============>>>>>>>>>>>>>>>>>>>")
					// make sure account is there
					So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

					for i := 0; i < 10; i++ {
						rand.Seed(time.Now().UnixNano())
						strconv.FormatInt(rand.Int63(), 10)
						name := "guter-" + strconv.FormatInt(rand.Int63(), 10)
						ac, _ := models.CreateAccountInBothDbsWithNick(name)

						err := handler.AccountCreated(ac)
						So(err, ShouldBeNil)

						selector := bson.M{"username": ac.Nick}
						newEmail := "mehmetali-test" + models.RandomGroupName() + "@koding.com"
						updateQuery := bson.M{"email": newEmail}
						err = modelhelper.UpdateUser(selector, updateQuery)
						So(err, ShouldBeNil)

						err = handler.AccountUpdated(ac)
						So(err, ShouldBeNil)
						time.Sleep(1 * time.Second)
					}

					time.Sleep(5 * time.Second)

					_, err = handler.indexes.GetIndex(IndexAccounts)
					So(err, ShouldBeNil)

					// record, _ := index.Search("mehmetalisa", map[string]interface{}{"restrictSearchableAttributes": "email"})
					// params := make(map[string]interface{})
					params := map[string]interface{}{"restrictSearchableAttributes": "nick"}
					record, _ := index.Search("guter-", params)

					hits, _ := record.(map[string]interface{})["nbHits"]
					hit := hits.(float64)
					So(hit, ShouldBeGreaterThan, 0)

					err = handler.DeleteNicksWithQuery("guter-")
					So(err, ShouldBeNil)

					// necessary for getting datas from algolia,
					time.Sleep(5 * time.Second)

					r, err := index.Search("guter-", params)
					So(err, ShouldBeNil)
					nbHits, _ := r.(map[string]interface{})["nbHits"]
					nbHit := nbHits.(float64)
					So(nbHit, ShouldBeLessThan, 10)
				})
			})
		})
	})
}
예제 #19
0
func TestAccountSaved(t *testing.T) {
	runner, handler := getTestHandler()
	defer runner.Close()

	// init mongo connection
	appConfig := config.MustRead(runner.Conf.Path)
	modelhelper.Initialize(appConfig.Mongo)
	defer modelhelper.Close()

	Convey("given some fake account", t, func() {
		acc, err := models.CreateAccountInBothDbs()
		So(err, ShouldBeNil)
		So(acc, ShouldNotBeNil)

		Convey("it should save the document to algolia", func() {
			err := handler.AccountCreated(acc)
			So(err, ShouldBeNil)

			Convey("it should have email in it", func() {
				// make sure account is there
				So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)

				user, err := modelhelper.GetUser(acc.Nick)
				So(err, ShouldBeNil)

				err = makeSureWithSearch(
					handler,
					IndexAccounts,
					user.Email,
					map[string]interface{}{"restrictSearchableAttributes": "email"},
					func(record map[string]interface{}, err error) bool {
						if err != nil {
							return false
						}

						if record == nil {
							return false
						}

						hits, ok := record["nbHits"]
						if hits == nil || !ok {
							return false
						}

						if hits.(float64) <= 0 {
							return false
						}

						return true
					},
				)

				So(err, ShouldBeNil)
			})
		})

		Convey("saving same account to algolia should success", func() {
			err := handler.AccountCreated(acc)
			So(err, ShouldBeNil)
			So(doBasicTestForAccount(handler, acc.OldId), ShouldBeNil)
		})
	})
}
예제 #20
0
파일: builder.go 프로젝트: koding/koding
// BuildCredentials fetches credential details for current b.Stack from MongoDB.
//
// When nil error is returned, the b.Koding and  b.Credentials fields are non-nil.
//
// TODO(rjeczalik): Replace with *credential.Client
func (b *Builder) BuildCredentials(method, username, groupname string, identifiers []string) error {
	// fetch jaccount from username
	account, err := modelhelper.GetAccount(username)
	if err != nil {
		return models.ResError(err, "jAccount")
	}

	// fetch jUser from username
	user, err := modelhelper.GetUser(username)
	if err != nil {
		return models.ResError(err, "jUser")
	}

	kodingMeta := &KodingMeta{
		Email:     user.Email,
		Username:  user.Name,
		Nickname:  account.Profile.Nickname,
		Firstname: account.Profile.FirstName,
		Lastname:  account.Profile.LastName,
		Hash:      account.Profile.Hash,
	}

	if b.StackTemplate != nil {
		kodingMeta.TemplateID = b.StackTemplate.Id.Hex()
	}

	if b.Stack != nil {
		kodingMeta.StackID = b.Stack.Stack.Id.Hex()
		kodingMeta.TemplateID = b.Stack.Stack.BaseStackId.Hex()
	}

	groupIDs := []bson.ObjectId{account.Id}

	if groupname != "" {
		// fetch jGroup from group slug name
		group, err := modelhelper.GetGroup(groupname)
		if err != nil {
			return models.ResError(err, "jGroup")
		}

		// validate if username belongs to groupnam
		selector := modelhelper.Selector{
			"targetId": account.Id,
			"sourceId": group.Id,
			"as": bson.M{
				"$in": []string{"member"},
			},
		}

		count, err := modelhelper.RelationshipCount(selector)
		if err != nil || count == 0 {
			return fmt.Errorf("username '%s' does not belong to group '%s'", username, groupname)
		}

		kodingMeta.Title = group.Title
		kodingMeta.Slug = group.Slug

		groupIDs = append(groupIDs, group.Id)
	}

	// 2- fetch credential from identifiers via args
	credentials, err := modelhelper.GetCredentialsFromIdentifiers(identifiers...)
	if err != nil {
		return models.ResError(err, "jCredential")
	}

	credentialTitles := make(map[string]string, len(credentials))
	for _, cred := range credentials {
		credentialTitles[cred.Identifier] = cred.Title
	}

	// 3- count relationship with credential id and jaccount id as user or
	// owner. Any non valid credentials will be discarded
	validKeys := make(map[string]string, len(credentials))

	permittedTargets, ok := credPermissions[method]
	if !ok {
		return fmt.Errorf("no permission data available for method '%s'", method)
	}

	for _, cred := range credentials {
		selector := modelhelper.Selector{
			"targetId": cred.Id,
			"sourceId": bson.M{
				"$in": groupIDs,
			},
			"as": bson.M{"$in": permittedTargets},
		}

		count, err := modelhelper.RelationshipCount(selector)
		if err != nil {
			return models.ResError(err, "jRelationship")
		}
		if count == 0 {
			return fmt.Errorf("credential with identifier '%s' is not validated: %v", cred.Identifier, err)
		}

		validKeys[cred.Identifier] = cred.Provider
	}

	// 5- return list of keys.
	b.Koding = &stack.Credential{
		Provider:   "koding",
		Credential: kodingMeta,
	}

	creds := make([]*stack.Credential, 0, len(validKeys))

	for ident, provider := range validKeys {
		creds = append(creds, &stack.Credential{
			Title:      credentialTitles[ident],
			Provider:   provider,
			Identifier: ident,
		})
	}

	if err := b.FetchCredentials(username, creds...); err != nil {
		// TODO(rjeczalik): add *NotFoundError support to CredStore
		return models.ResError(err, "jCredentialData")
	}

	b.Credentials = append(b.Credentials, creds...)

	for i, cred := range b.Credentials {
		b.Log.Debug("Built credential #%d: %# v (%+v, %+v)", i, cred, cred.Credential, cred.Bootstrap)
	}

	return nil
}
예제 #21
0
파일: createuser.go 프로젝트: koding/koding
func CreateUser(opts *UserOptions) (*User, error) {
	username := opts.Username
	groupname := opts.Groupname
	provider := opts.Provider
	template := opts.Template

	privateKey, publicKey, err := sshutil.TemporaryKey()
	if err != nil {
		return nil, err
	}

	labels, err := machineLabels([]byte(template))
	if err != nil {
		return nil, err
	}

	relationExists := true

	// jAccounts
	account, err := modelhelper.GetAccount(username)
	if err == mgo.ErrNotFound {
		relationExists = false

		account = &models.Account{
			Id: bson.NewObjectId(),
			Profile: models.AccountProfile{
				Nickname: username,
			},
		}

		err = modelhelper.CreateAccount(account)
	}
	if err != nil {
		return nil, errors.New("failure looking up jAccounts: " + err.Error())
	}

	// jGroups
	group, err := modelhelper.GetGroup(groupname)
	if err == mgo.ErrNotFound {
		relationExists = false

		group = &models.Group{
			Id:    bson.NewObjectId(),
			Title: groupname,
			Slug:  groupname,
		}

		err = modelhelper.CreateGroup(group)
	}
	if err != nil {
		return nil, errors.New("failure looking up jGroups: " + err.Error())
	}

	if !relationExists {
		// add relation between use and group
		relationship := &models.Relationship{
			Id:         bson.NewObjectId(),
			TargetId:   account.Id,
			TargetName: "JAccount",
			SourceId:   group.Id,
			SourceName: "JGroup",
			As:         "member",
		}

		err := modelhelper.AddRelationship(relationship)
		if err != nil {
			return nil, errors.New("failure insering relationship: " + err.Error())
		}
	}

	// jUsers
	user, err := modelhelper.GetUser(username)
	if err == nil && len(user.SshKeys) != 0 {
		publicKey = user.SshKeys[0].Key
	}
	if err == mgo.ErrNotFound {
		user = &models.User{
			ObjectId:      bson.NewObjectId(),
			Email:         username + "@" + username + ".com",
			LastLoginDate: time.Now().UTC(),
			RegisteredAt:  time.Now().UTC(),
			Name:          username, // bson equivelant is username
			Password:      "******",
			Status:        "confirmed",
			SshKeys: []struct {
				Title string `bson:"title"`
				Key   string `bson:"key"`
			}{
				{Key: publicKey},
			},
		}

		err = modelhelper.CreateUser(user)
	}
	if err != nil {
		return nil, errors.New("failure looking up jUsers: " + err.Error())
	}

	queryString := protocol.Kite{ID: opts.KlientID}.String()

	cred := &models.Credential{
		Id:         bson.NewObjectId(),
		Provider:   opts.Provider,
		Identifier: bson.NewObjectId().Hex(),
		OriginId:   account.Id,
	}

	credData := &models.CredentialData{
		Id:         bson.NewObjectId(),
		Identifier: cred.Identifier,
		OriginId:   account.Id,
		Meta: bson.M{
			"queryString": queryString,
			"memory":      0,
			"cpu":         0,
			"box":         "",
		},
	}

	if err := modelhelper.InsertCredential(cred, credData); err != nil {
		return nil, err
	}

	relationship := &models.Relationship{
		Id:         bson.NewObjectId(),
		TargetId:   cred.Id,
		TargetName: "JCredential",
		SourceId:   account.Id,
		SourceName: "JAccount",
		As:         "owner",
	}

	if err := modelhelper.AddRelationship(relationship); err != nil {
		return nil, err
	}

	// jComputeStack and jStackTemplates
	stackTemplateId := bson.NewObjectId()
	stackTemplate := &models.StackTemplate{
		Id: stackTemplateId,
		Credentials: map[string][]string{
			"vagrant": {cred.Identifier},
		},
	}
	stackTemplate.Template.Content = template

	if err := modelhelper.CreateStackTemplate(stackTemplate); err != nil {
		return nil, err
	}

	// later we can add more users with "Owner:false" to test sharing capabilities
	users := []models.MachineUser{
		{Id: user.ObjectId, Sudo: true, Owner: true},
	}

	machineIds := make([]bson.ObjectId, len(labels))

	for i, label := range labels {
		machineId := bson.NewObjectId()
		machine := &models.Machine{
			ObjectId:   machineId,
			Label:      label,
			Domain:     username + ".dev.koding.io",
			Provider:   provider,
			CreatedAt:  time.Now().UTC(),
			Users:      users,
			Meta:       make(bson.M, 0),
			Groups:     make([]models.MachineGroup, 0),
			Credential: username,
		}

		machine.Assignee.InProgress = false
		machine.Assignee.AssignedAt = time.Now().UTC()
		machine.Status.State = machinestate.NotInitialized.String()
		machine.Status.ModifiedAt = time.Now().UTC()

		machineIds[i] = machine.ObjectId

		if err := modelhelper.CreateMachine(machine); err != nil {
			return nil, err
		}
	}

	computeStackID := bson.NewObjectId()
	computeStack := &models.ComputeStack{
		Id:          computeStackID,
		BaseStackId: stackTemplateId,
		Machines:    machineIds,
	}

	if err := modelhelper.CreateComputeStack(computeStack); err != nil {
		return nil, err
	}

	return &User{
		MachineIDs:      machineIds,
		MachineLabels:   labels,
		StackID:         computeStackID.Hex(),
		StackTemplateID: stackTemplate.Id.Hex(),
		AccountID:       account.Id,
		CredID:          cred.Id.Hex(),
		CredDataID:      credData.Id.Hex(),
		PrivateKey:      privateKey,
		PublicKey:       publicKey,
		Identifiers:     []string{cred.Identifier},
	}, nil
}
예제 #22
0
// HandleCreator finds the creator of the channel, and tries to find its
// company name according to its email address
func (c *Controller) HandleCreator(channel *models.Channel) error {
	// we need to check environment, because we dont want to request to clearbit for our dev
	if channel.TypeConstant != models.Channel_TYPE_GROUP || c.config.Environment != "production" {
		return nil
	}

	creator, err := models.Cache.Account.ById(channel.CreatorId)
	if err != nil {
		return nil
	}
	user, err := modelhelper.GetUser(creator.Nick)
	if err != nil {
		return nil
	}
	// if user already has company, no need to fetch user's company info again.
	if user.CompanyId.Hex() != "" {
		return nil
	}
	// if user has no company data, then try to fetch info about company of user.
	userData, err := c.clearbit.Enrichment().Combined(user.Email)
	if err != nil {
		return err
	}

	if userData.Company == nil {
		return nil
	}

	if userData.Company.Name == nil {
		return nil
	}

	// if code line reach to here, it means that we got user's company data,
	// after that we are going to update user's data.
	var company *mongomodels.Company

	company, err = modelhelper.GetCompanyByNameOrSlug(*userData.Company.Name)
	if err != nil && err != mgo.ErrNotFound {
		return err
	}
	// if company is not found in db, then create new one
	// after creation, update user's company with company id
	if err == mgo.ErrNotFound {
		err := checkValuesForCompany(userData.Company)
		if err != nil {
			return nil
		}

		// parse company data of clearbit package into our company model struct
		companyData := parseClearbitCompany(userData.Company)

		// create company in db if it doesn't exist
		company, err = modelhelper.CreateCompany(companyData)
		if err != nil {
			return err
		}
	}

	// update the company info of user if company exist in mongo
	selector := bson.M{"username": user.Name}
	update := bson.M{"companyId": company.Id}
	if err := modelhelper.UpdateUser(selector, update); err != nil {
		return err
	}
	return nil
}
예제 #23
0
func TestPersist(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

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

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

		Convey("testing post message while all is well", func() {
			acc, err := socialapimodels.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			c := socialapimodels.CreateChannelWithTest(acc.Id)

			//cm := socialapimodels.CreateMessage(c.Id, acc.Id)
			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			m := &Mail{
				From:              mongoUser.Email,
				OriginalRecipient: fmt.Sprintf("*****@*****.**", c.Id),
				MailboxHash:       fmt.Sprintf("channelid.%d", c.Id),
				TextBody:          "Its an example of text message",
			}

			err = m.Persist()
			So(err, ShouldBeNil)
		})

		Convey("reply should have messageid", func() {
			acc, err := socialapimodels.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			c := socialapimodels.CreateChannelWithTest(acc.Id)
			socialapimodels.AddParticipantsWithTest(c.Id, acc.Id)

			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			m := &Mail{
				From:              mongoUser.Email,
				OriginalRecipient: fmt.Sprintf("*****@*****.**", c.Id),
				MailboxHash:       fmt.Sprintf("channelid.%d", c.Id),
				TextBody:          "Its an example of text message",
			}

			err = m.Persist()
			So(err, ShouldEqual, bongo.RecordNotFound)
		})

		Convey("testing reply message if all is well", func() {
			acc, err := socialapimodels.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			c := socialapimodels.CreateChannelWithTest(acc.Id)
			socialapimodels.AddParticipantsWithTest(c.Id, acc.Id)

			cm := socialapimodels.CreateMessage(c.Id, acc.Id, socialapimodels.ChannelMessage_TYPE_POST)
			So(cm, ShouldNotBeNil)

			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			m := &Mail{
				From:              mongoUser.Email,
				OriginalRecipient: fmt.Sprintf("*****@*****.**", c.Id),
				MailboxHash:       fmt.Sprintf("messageid.%d", cm.Id),
				TextBody:          "Its an example of text message",
				StrippedTextReply: "This one is reply message",
			}

			err = m.Persist()
			So(err, ShouldBeNil)
		})

		Convey("testing reply message, record not found if user is not a participant", func() {
			acc, err := socialapimodels.CreateAccountInBothDbs()
			So(err, ShouldBeNil)

			c := socialapimodels.CreateChannelWithTest(acc.Id)

			cm := socialapimodels.CreateMessage(c.Id, acc.Id, socialapimodels.ChannelMessage_TYPE_POST)
			So(cm, ShouldNotBeNil)

			mongoUser, err := modelhelper.GetUser(acc.Nick)
			So(err, ShouldBeNil)

			m := &Mail{
				From:              mongoUser.Email,
				OriginalRecipient: fmt.Sprintf("*****@*****.**", c.Id),
				MailboxHash:       fmt.Sprintf("messageid.%d", cm.Id),
				TextBody:          "Its an example of text message",
				StrippedTextReply: "This one is reply message",
			}

			err = m.persistPost(acc.Id)
			So(err, ShouldNotBeNil)
		})
	})
}
예제 #24
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())
	}
}
예제 #25
0
파일: mongo.go 프로젝트: koding/koding
func (db *mongoDatabase) fetchModels(f *Filter, perm *MongoPerm) (err error) {
	log := db.Log.New("fetchModels")

	if perm.AccModel == nil {
		log.Debug("fetching %q account", f.Username)

		perm.AccModel, err = modelhelper.GetAccount(f.Username)
		if err != nil {
			return models.ResError(err, "jAccount")
		}

		perm.CredGroups = append(perm.CredGroups, perm.AccModel.Id)
	}

	if perm.UserModel == nil {
		log.Debug("fetching %q user", f.Username)

		perm.UserModel, err = modelhelper.GetUser(f.Username)
		if err != nil {
			return models.ResError(err, "jUser")
		}
	}

	if f.Teamname != "" {
		if perm.TeamModel == nil {
			log.Debug("fetching %q team", f.Teamname)

			perm.TeamModel, err = modelhelper.GetGroup(f.Teamname)
			if err != nil {
				return models.ResError(err, "jGroup")
			}

			perm.CredGroups = append(perm.CredGroups, perm.TeamModel.Id)
		}

		if !perm.Member {
			belongs := modelhelper.Selector{
				"targetId": perm.AccModel.Id,
				"sourceId": perm.TeamModel.Id,
				"as":       "member",
			}

			log.Debug("testing relationship for %+v", belongs)

			if count, err := modelhelper.RelationshipCount(belongs); err != nil || count == 0 {
				if err == nil {
					err = fmt.Errorf("user %q does not belong to %q group", f.Username, f.Teamname)
				}

				return models.ResError(err, "jRelationship")
			}

			perm.Member = true
		}
	}

	if perm.CredModel == nil && f.Ident != "" {
		log.Debug("fetching %q credential", f.Ident)

		perm.CredModel, err = modelhelper.GetCredential(f.Ident)
		if err != nil {
			return models.ResError(err, "jCredential")
		}
	}

	return nil
}