Beispiel #1
0
func getAccountByNick(nick string) bool {
	if _, err := existingAccountByNick.Get(nick); err == nil {
		return true
	}

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

	acc, err := helper.GetAccount(nick)
	if err == mgo.ErrNotFound {
		deletedAccountByNick.Set(nick, struct{}{})
		return false
	}

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

	id := acc.Id.Hex()
	if acc.Type == "deleted" {
		deletedAccountByID.Set(id, struct{}{})
		deletedAccountByNick.Set(acc.Profile.Nickname, struct{}{})
		return false
	}

	existingAccountByID.Set(id, struct{}{})
	existingAccountByNick.Set(acc.Profile.Nickname, id)

	return true
}
Beispiel #2
0
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
}
Beispiel #3
0
// Migrate implements the Database interface.
func (db *mongoDatabase) Migrate(opts *MigrateOptions) error {
	stack := models.NewStackTemplate(opts.Provider, opts.Identifier)
	stack.Machines = make([]bson.M, len(opts.Machines))

	for i := range stack.Machines {
		stack.Machines[i] = bson.M(machineBuilder.Build(opts.Machines[i]))
	}

	account, err := modelhelper.GetAccount(opts.Username)
	if err != nil {
		return fmt.Errorf("account lookup failed for %q: %s", opts.Username, err)
	}

	sum := sha1.Sum([]byte(opts.Template))

	stack.Title = opts.StackName
	stack.OriginID = account.Id
	stack.Template.Details = bson.M{
		"lastUpdaterId": account.Id,
	}
	stack.Group = opts.GroupName
	stack.Template.Content = opts.Template
	stack.Template.Sum = hex.EncodeToString(sum[:])

	if s, err := yamlReencode(opts.Template); err == nil {
		stack.Template.RawContent = s
	}

	if err := modelhelper.CreateStackTemplate(stack); err != nil {
		return fmt.Errorf("failed to create stack template: %s", err)
	}

	change := bson.M{
		"$set": bson.M{
			"meta.migration.modifiedAt":      time.Now(),
			"meta.migration.status":          MigrationMigrated,
			"meta.migration.stackTemplateId": stack.Id,
		},
	}

	for _, id := range opts.MachineIDs {
		if e := modelhelper.UpdateMachine(id, change); e != nil {
			err = multierror.Append(err, fmt.Errorf("failed to update migration details for %q: %s", id.Hex(), err))
		}
	}

	// Failure updating jMachine migration metadata is not critical,
	// just log the error and continue.
	if err != nil {
		opts.Log.Error("%s", err)
	}

	return nil
}
Beispiel #4
0
// GetAccount gets the account which sent the message by email of user
func GetAccount(mailAddress string) (*mongomodels.Account, error) {
	user, err := modelhelper.FetchUserByEmail(mailAddress)
	if err != nil {
		return nil, ErrEmailIsNotFetched
	}

	// This GetAccount
	account, err := modelhelper.GetAccount(user.Name)
	if err != nil {
		return nil, ErrAccountIsNotFound
	}
	return account, nil
}
Beispiel #5
0
// makeSureAccount checks if incoming account is in postgres, if not creates it
// lazily and sets socialapi id of it in mongo
func makeSureAccount(groupName string, username string) (*models.Account, error) {
	// try to fetch account from postgres
	acc := models.NewAccount()
	err := acc.ByNick(username)
	if err == nil {
		return acc, nil
	}

	if err != bongo.RecordNotFound {
		return acc, err
	}

	// if account is not in postgres, try to create it

	// we need account first
	macc, err := modelhelper.GetAccount(username)
	if err != nil {
		return nil, err
	}

	acc = models.NewAccount() // account is nil, set it
	acc.OldId = macc.Id.Hex()
	acc.Nick = username
	if err := acc.Create(); err != nil {
		return nil, err
	}

	// set it to cache, in case we may need it
	if err := models.Cache.Account.SetToCache(acc); err != nil {
		return nil, err
	}

	// we just created the account in postgres, so update mongo with
	// socialApiId
	s := modelhelper.Selector{
		"profile.nickname": username,
	}
	o := modelhelper.Selector{"$set": modelhelper.Selector{
		"socialApiId": strconv.FormatInt(acc.Id, 10),
	}}
	if err := modelhelper.UpdateAccount(s, o); err != nil {
		return nil, err
	}

	return acc, nil
}
Beispiel #6
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,
	})
}
Beispiel #7
0
// TODO refactor this function to use postgres
func (p *ChannelRequest) obtainParticipantIds() ([]int64, error) {
	participantIds := make([]int64, len(p.Recipients))
	for i, participantName := range p.Recipients {
		// get account from mongo
		account, err := modelhelper.GetAccount(participantName)
		if err != nil {
			return nil, err
		}

		a := NewAccount()
		socialApiId, _ := account.GetSocialApiId()

		a.Id = socialApiId
		a.OldId = account.Id.Hex()
		a.Nick = account.Profile.Nickname
		// fetch or create social api id
		if a.Id == 0 {
			if err := a.FetchOrCreate(); err != nil {
				return nil, err
			}
		}
		participantIds[i] = a.Id
	}

	// append creator to the recipients
	participantIds = prependCreatorId(participantIds, p.AccountId)

	// author and atleast one recipient should be in the
	// recipient list
	if len(participantIds) < 1 {
		// user can send private message to themself
		return nil, ErrRecipientsNotDefined
	}

	return participantIds, nil
}
Beispiel #8
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
}
Beispiel #9
0
func (m *Migrate) Action(args []string) error {
	if err := m.Valid(); err != nil {
		return err
	}

	c, err := kloudClient()
	if err != nil {
		return err
	}
	defer c.Close()

	modelhelper.Initialize(*m.MongoURL)
	defer modelhelper.Close()

	account, err := modelhelper.GetAccount(*m.User)
	if err != nil {
		return err
	}

	if *m.Credential == "" {
		*m.Credential = bson.NewObjectId().Hex()

		cred := &models.Credential{
			Id:         bson.NewObjectId(),
			Provider:   "aws",
			Identifier: *m.Credential,
			OriginId:   account.Id,
		}

		credData := &models.CredentialData{
			Id:         bson.NewObjectId(),
			Identifier: *m.Credential,
			OriginId:   account.Id,
			Meta: bson.M{
				"access_key": *m.Key,
				"secret_key": *m.Secret,
				"region":     *m.Region,
			},
		}

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

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

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

	req := &MigrateRequest{
		Provider:    "aws",
		Machines:    m.Machines,
		Identifier:  *m.Credential,
		GroupName:   *m.Team,
		StackName:   "Migrated Stack",
		Impersonate: *m.User,
	}

	_, err = c.Tell("migrate", req)

	return err
}
Beispiel #10
0
// 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
}
Beispiel #11
0
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
}
Beispiel #12
0
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
}
Beispiel #13
0
func TestChannelUpdatedCalculateUnreadItemCount(t *testing.T) {
	r := runner.New("test")
	if err := r.Init(); err != nil {
		t.Fatalf("couldnt start bongo %s", err.Error())
	}
	defer r.Close()

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

	groupName := models.RandomGroupName()

	Convey("while testing get account", t, func() {
		Convey("if cookie is not set, should return nil", func() {
			a := getAccount(&http.Request{}, models.Channel_KODING_NAME)
			So(a, ShouldNotBeNil)
			So(a.Id, ShouldBeZeroValue)
		})

		Convey("if cookie value is not set, should return nil", func() {
			req, _ := http.NewRequest("GET", "/", nil)

			expire := time.Now().AddDate(0, 0, 1)
			cookie := http.Cookie{
				Name:    "clientId",
				Value:   "",
				Path:    "/",
				Domain:  "localhost",
				Expires: expire,
			}

			req.AddCookie(&cookie)

			a := getAccount(req, models.Channel_KODING_NAME)
			So(a, ShouldNotBeNil)
			So(a.Id, ShouldBeZeroValue)
		})

		Convey("if session doesnt have username, should return nil", func() {
			ses, err := modelhelper.CreateSessionForAccount("", groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			req, _ := http.NewRequest("GET", "/", nil)
			expire := time.Now().AddDate(0, 0, 1)
			cookie := http.Cookie{
				Name:    "clientId",
				Value:   ses.ClientId,
				Path:    "/",
				Domain:  "localhost",
				Expires: expire,
			}

			req.AddCookie(&cookie)

			a := getAccount(req, models.Channel_KODING_NAME)
			So(a, ShouldNotBeNil)
			So(a.Id, ShouldBeZeroValue)
		})

		Convey("if session is valid, should return account", func() {
			acc, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)
			So(acc, ShouldNotBeNil)

			ses, err := modelhelper.CreateSessionForAccount(acc.Nick, groupName)
			So(err, ShouldBeNil)
			So(ses, ShouldNotBeNil)

			req, _ := http.NewRequest("GET", "/", nil)
			expire := time.Now().AddDate(0, 0, 1)
			cookie := http.Cookie{
				Name:    "clientId",
				Value:   ses.ClientId,
				Path:    "/",
				Domain:  "localhost",
				Expires: expire,
			}

			req.AddCookie(&cookie)

			res := getAccount(req, models.Channel_KODING_NAME)
			So(res, ShouldNotBeNil)
			So(acc.Id, ShouldEqual, res.Id)
		})
	})

	Convey("while making sure account", t, func() {
		Convey("if account is not in postgres", func() {

			nick := models.RandomName()
			oldAcc := &kodingmodels.Account{
				Id: bson.NewObjectId(),
				Profile: kodingmodels.AccountProfile{
					Nickname: nick,
				},
			}
			err := modelhelper.CreateAccount(oldAcc)
			So(err, ShouldBeNil)

			oldUser := &kodingmodels.User{
				ObjectId:       bson.NewObjectId(),
				Password:       nick,
				Salt:           nick,
				Name:           nick,
				Email:          nick + "@koding.com",
				EmailFrequency: &kodingmodels.EmailFrequency{},
			}

			err = modelhelper.CreateUser(oldUser)
			So(err, ShouldBeNil)

			groupName := models.RandomGroupName()
			_, err = makeSureAccount(groupName, nick)
			So(err, ShouldBeNil)

			Convey("should create it in postgres", func() {
				a := models.NewAccount()
				err = a.ByNick(nick)
				So(err, ShouldBeNil)
				So(a.OldId, ShouldEqual, oldAcc.Id.Hex())

				Convey("should set socialAPI id in mongo", func() {
					oldAccFromDB, err := modelhelper.GetAccount(nick)
					So(err, ShouldBeNil)
					So(oldAccFromDB.SocialApiId, ShouldEqual, strconv.FormatInt(a.Id, 10))
				})
			})
		})

		Convey("if account is in postgres", func() {
			acc, err := models.CreateAccountInBothDbs()
			So(err, ShouldBeNil)
			So(acc, ShouldNotBeNil)

			groupName := models.RandomGroupName()

			_, err = makeSureAccount(groupName, acc.Nick)
			So(err, ShouldBeNil)

			Convey("should be in postgres", func() {
				a := models.NewAccount()
				err = a.ByNick(acc.Nick)
				So(err, ShouldBeNil)
				So(a.OldId, ShouldEqual, acc.OldId)

				Convey("should have socialAPI set", func() {
					oldAccFromDB, err := modelhelper.GetAccount(acc.Nick)
					So(err, ShouldBeNil)
					So(oldAccFromDB.SocialApiId, ShouldEqual, strconv.FormatInt(a.Id, 10))
				})
			})
		})
	})

	Convey("while making sure group membership", t, func() {
		Convey("if account is not not a member", func() {
			account := models.CreateAccountWithTest()
			requester := models.CreateAccountWithTest()
			groupChannel := models.CreateTypedPublicChannelWithTest(account.Id, models.Channel_TYPE_GROUP)

			err := makeSureMembership(groupChannel, requester.Id)
			So(err, ShouldBeNil)

			Convey("should add as participant", func() {
				status, err := groupChannel.IsParticipant(requester.Id)
				So(err, ShouldBeNil)
				So(status, ShouldBeTrue)

				Convey("if account is a member", func() {
					err := makeSureMembership(groupChannel, requester.Id)
					So(err, ShouldBeNil)

					Convey("should be a participant", func() {
						status, err := groupChannel.IsParticipant(requester.Id)
						So(err, ShouldBeNil)
						So(status, ShouldBeTrue)
					})
				})
			})

		})
	})
}