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 }
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 }
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()) } }
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 }
// 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 }
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 }
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 }
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) }) }) }
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) }
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) }) }) }
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) }) }) }
// 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 }
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 }
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, }) }
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 }
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") } }
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 }
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) }) }) }) }) }
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) }) }) }
// 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 }
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 }
// 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 }
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) }) }) }
// 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()) } }
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 }