func (db *mongoDatabase) fetchTeams(perm *MongoPerm) (map[bson.ObjectId]*models.Group, error) { if perm.TeamModel != nil { return map[bson.ObjectId]*models.Group{ perm.TeamModel.Id: perm.TeamModel, }, nil } belongs := modelhelper.Selector{ "targetId": perm.AccModel.Id, "sourceName": "JGroup", "as": "member", } rels, err := modelhelper.GetAllRelationships(belongs) if err != nil { return nil, models.ResError(err, "jRelationship") } ids := make([]bson.ObjectId, len(rels)) for i := range rels { ids[i] = rels[i].SourceId } groups, err := modelhelper.GetGroupsByIds(ids...) if err != nil { return nil, models.ResError(err, "jGroup") } teams := make(map[bson.ObjectId]*models.Group, len(groups)) for i := range groups { teams[groups[i].Id] = groups[i] } return teams, nil }
// HandleGetKodingKites implements GetKites with additional Koding specific response // data. func HandleGetKodingKites(handleGetKites kite.HandlerFunc, environment string) kite.HandlerFunc { return func(req *kite.Request) (interface{}, error) { // getKitesResponse is an interface, not the actual GetKitesResult value. getKitesResponse, err := handleGetKites(req) if err != nil { req.LocalKite.Log.Error("GetKitesHandler returned an error: %s", err) return nil, err } getKitesResult, ok := getKitesResponse.(*protocol.GetKitesResult) if !ok { return nil, errors.New("GetKites returned unexpected protocol result") } // Get all machines for the given user. machines, err := modelhelper.GetMachineFieldsByUsername(req.Username, []string{ "queryString", "label", "groups", }) if err != nil { return nil, err } // A map of GroupId a slice of all KodingKiteWithToken that contain that group. kitesByGroupID := map[string][]*KodingKiteWithToken{} // Create our slice of unique group ids that we will use to query all the // groups that we need. uniqueGroups := []bson.ObjectId{} // Because we are using the Kite's queryString as a means to identify the machine, // we are sorting the machines by queryString so that we can easily look them up. machinesByQuery := getMachinesByQueryID(machines) // Create our KodingKitesResult which will be returned after being populated. result := &GetKodingKitesResult{ Kites: make([]*KodingKiteWithToken, len(getKitesResult.Kites)), } // Populate the koding kites for i, kiteWithToken := range getKitesResult.Kites { kite := &KodingKiteWithToken{ Kite: kiteWithToken.Kite, URL: kiteWithToken.URL, KeyID: kiteWithToken.KeyID, Token: kiteWithToken.Token, } // Populate the result kite regardless of if we can get Label/Team/etc // information about it. This is needed because many kites might not have // jMachine documents. result.Kites[i] = kite // JMachine.QueryString is composed of only the Kite.ID, so to form a // queryString that we can match to the stored queryString in Mongo, String // the Kite protocol with just the ID. Example: // // ///////b38da9f0-9acf-4c41-bdfe-6ef3c9b8de56 queryString := protocol.Kite{ID: kite.Kite.ID}.String() // With a valid queryString, get the koding specific information such as Label // or Team names and apply it to each KodingKiteWithToken if machine, ok := machinesByQuery[queryString]; ok { kite.MachineLabel = machine.Label for _, g := range machine.Groups { id := g.Id.Hex() // Get all of the kites (not including this one) which have // a reference to this kite, so we can append this kite to them. kites, ok := kitesByGroupID[id] // If the id is *not* in the kites map yet, it is unique. // Store the group id in the unique slice, so we can query for the groups. if !ok { uniqueGroups = append(uniqueGroups, g.Id) } // kites could be a nil map, but that's okay as append will resolve // that issue. // // Note that if a Machine somehow has two entries for the same group, // this will be appended twice, but should not cause a problem. kitesByGroupID[id] = append(kites, kite) } } } // Now that we have all of our group ids that we want to query, get our Groups // from that. groups, err := modelhelper.GetGroupsByIds(uniqueGroups...) if err != nil { return nil, err } // Now that we have the groups, go through our KodingKiteWithToken slice and // assign the team names. for _, group := range groups { id := group.Id.Hex() kites, ok := kitesByGroupID[id] // This shouldn't happen, so log a warning to aid in identifying a problem, // and continue. if !ok { req.LocalKite.Log.Warning( "Queried GroupId not present in KodingKitesWithToken by GroupId map. This is unexpected, and may represent a problem. [id:%s, ids:%s]", id, uniqueGroups, ) continue } // Append this groups team title to the KodingKiteWithToken Teams slice. for _, kite := range kites { kite.Teams = append(kite.Teams, group.Title) } } // if env is default, do not filter the unpaid team's content if environment == "default" { return result, nil } return filterResult(result, groups, kitesByGroupID), nil } }