// Most of the checks are in the teams package.
// This just covers this one presentation thing:
//
// > keybase team change-name aviato.usa.marketing aviato.america.sales
// Error! You must first rename `aviato.usa` to `aviato.america`.
15439
func (v *CmdTeamRename) helpRenameWrongLevel() (err error) {
	if v.PrevName.Depth() != v.NewName.Depth() {
		return nil
	}
	if v.PrevName.Depth() < 3 {
		return nil
	}
	// Scan the parts of both names looking for the first difference.
	// Skip the root and the end. Because the root is not this case,
	// and the end is not a problem.
	// If it is in the middle then tell the user what to do.
	for i := 1; i < len(v.PrevName.Parts)-1; i++ {
		prevPart := v.PrevName.Parts[i]
		newPart := v.NewName.Parts[i]
		if !prevPart.Eq(newPart) {
			a1 := keybase1.TeamName{Parts: v.PrevName.Parts[:i+1]}
			a2 := keybase1.TeamName{Parts: v.NewName.Parts[:i+1]}
			return fmt.Errorf("You must first rename `%v` to `%v`", a1, a2)
		}
	}
	return nil
}
62827
func NewTeam(t *Team) error {
	if len(t.Name) == 0 {
		return errors.New("empty team name")
	} else if t.OrgID == 0 {
		return errors.New("OrgID is not assigned")
	}

	if err := IsUsableTeamName(t.Name); err != nil {
		return err
	}

	has, err := x.Id(t.OrgID).Get(new(User))
	if err != nil {
		return err
	} else if !has {
		return ErrOrgNotExist
	}

	t.LowerName = strings.ToLower(t.Name)
	has, err = x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).Get(new(Team))
	if err != nil {
		return err
	} else if has {
		return ErrTeamAlreadyExist{t.OrgID, t.LowerName}
	}

	sess := x.NewSession()
	defer sess.Close()
	if err = sess.Begin(); err != nil {
		return err
	}

	if _, err = sess.Insert(t); err != nil {
		sess.Rollback()
		return err
	}

	// Update organization number of teams.
	if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?", t.OrgID); err != nil {
		sess.Rollback()
		return err
	}
	return sess.Commit()
}
1031232
func NewTeamFolderRenameArg(TeamFolderId string, Name string) *TeamFolderRenameArg {
	s := new(TeamFolderRenameArg)
	s.TeamFolderId = TeamFolderId
	s.Name = Name
	return s
}
1308257
func (fs *KBFSOpsStandard) TeamNameChanged(
	ctx context.Context, tid keybase1.TeamID) {
	timeTrackerDone := fs.longOperationDebugDumper.Begin(ctx)
	defer timeTrackerDone()

	fs.log.CDebugf(ctx, "Got TeamNameChanged for %s", tid)
	fbo := fs.findTeamByID(ctx, tid)
	if fbo != nil {
		go fbo.TeamNameChanged(ctx, tid)
	}
}
610091
func (t *teamSigchainPlayer) sanityCheckMembers(members SCTeamMembers, options sanityCheckMembersOptions) (chainRoleUpdates, error) {
	type assignment struct {
		m    SCTeamMember
		role keybase1.TeamRole
	}
	var all []assignment

	if options.requireOwners {
		if members.Owners == nil {
			return nil, fmt.Errorf("team has no owner list")
		}
		if len(*members.Owners) < 1 {
			return nil, fmt.Errorf("team has no owners")
		}
	}
	if options.disallowOwners {
		if members.Owners != nil && len(*members.Owners) > 0 {
			return nil, fmt.Errorf("team has owners")
		}
	}
	if !options.allowRemovals {
		if members.None != nil && len(*members.None) != 0 {
			return nil, fmt.Errorf("team has removals in link")
		}
	}

	// Map from roles to users.
	res := make(map[keybase1.TeamRole][]keybase1.UserVersion)

	if members.Owners != nil && len(*members.Owners) > 0 {
		res[keybase1.TeamRole_OWNER] = nil
		for _, m := range *members.Owners {
			all = append(all, assignment{m, keybase1.TeamRole_OWNER})
		}
	}
	if members.Admins != nil && len(*members.Admins) > 0 {
		if options.onlyOwnersOrReaders {
			return nil, NewImplicitTeamOperationError("encountered add admin")
		}
		res[keybase1.TeamRole_ADMIN] = nil
		for _, m := range *members.Admins {
			all = append(all, assignment{m, keybase1.TeamRole_ADMIN})
		}
	}
	if members.Writers != nil && len(*members.Writers) > 0 {
		if options.onlyOwnersOrReaders {
			return nil, NewImplicitTeamOperationError("encountered add writer")
		}
		res[keybase1.TeamRole_WRITER] = nil
		for _, m := range *members.Writers {
			all = append(all, assignment{m, keybase1.TeamRole_WRITER})
		}
	}
	if members.Readers != nil && len(*members.Readers) > 0 {
		res[keybase1.TeamRole_READER] = nil
		for _, m := range *members.Readers {
			all = append(all, assignment{m, keybase1.TeamRole_READER})
		}
	}
	if members.None != nil && len(*members.None) > 0 {
		res[keybase1.TeamRole_NONE] = nil
		for _, m := range *members.None {
			all = append(all, assignment{m, keybase1.TeamRole_NONE})
		}
	}

	// Set of users who have already been seen.
	seen := make(map[keybase1.UserVersion]bool)

	for _, pair := range all {
		uv := keybase1.UserVersion(pair.m)

		if seen[uv] {
			return nil, fmt.Errorf("duplicate UID in members: %s", uv.Uid)
		}

		res[pair.role] = append(res[pair.role], uv)

		seen[uv] = true
	}

	return res, nil
}
938963
func (k *KeybaseServiceBase) TeamChangedByID(ctx context.Context,
	arg keybase1.TeamChangedByIDArg) error {
	k.log.CDebugf(ctx, "Flushing cache for team %s "+
		"(membershipChange=%t, keyRotated=%t, renamed=%t)",
		arg.TeamID, arg.Changes.MembershipChanged,
		arg.Changes.KeyRotated, arg.Changes.Renamed)
	k.setCachedTeamInfo(arg.TeamID, idutil.TeamInfo{})

	if arg.Changes.Renamed {
		k.config.KBFSOps().TeamNameChanged(ctx, arg.TeamID)
	}
	return nil
}
1143675
func (k *KeybaseServiceBase) CreateTeamTLF(
	ctx context.Context, teamID keybase1.TeamID, tlfID tlf.ID) (err error) {
	return k.kbfsClient.CreateTLF(ctx, keybase1.CreateTLFArg{
		TeamID: teamID,
		TlfID:  keybase1.TLFID(tlfID.String()),
	})
}
462587
func (l *TeamLoader) addKBFSCryptKeys(ctx context.Context, state *keybase1.TeamData,
	upgrades []keybase1.TeamGetLegacyTLFUpgrade) error {
	m := make(map[keybase1.TeamApplication][]keybase1.CryptKey)
	for _, upgrade := range upgrades {
		key, err := ApplicationKeyAtGeneration(libkb.NewMetaContext(ctx, l.G()), state, upgrade.AppType,
			keybase1.PerTeamKeyGeneration(upgrade.TeamGeneration))
		if err != nil {
			return err
		}

		chainInfo, ok := state.Chain.TlfLegacyUpgrade[upgrade.AppType]
		if !ok {
			return errors.New("legacy tlf upgrade payload present without chain link")
		}
		if chainInfo.TeamGeneration != upgrade.TeamGeneration {
			return fmt.Errorf("legacy tlf upgrade team generation mismatch: %d != %d",
				chainInfo.TeamGeneration, upgrade.TeamGeneration)
		}

		cryptKeys, err := l.unboxKBFSCryptKeys(ctx, key, chainInfo.KeysetHash, upgrade.EncryptedKeyset)
		if err != nil {
			return err
		}
		if chainInfo.LegacyGeneration != cryptKeys[len(cryptKeys)-1].KeyGeneration {
			return fmt.Errorf("legacy tlf upgrade legacy generation mismatch: %d != %d",
				chainInfo.LegacyGeneration, cryptKeys[len(cryptKeys)-1].KeyGeneration)
		}

		m[upgrade.AppType] = cryptKeys
	}
	state.TlfCryptKeys = m
	return nil
}
335261
func ResolveIDToNameForceRefresh(ctx context.Context, g *libkb.GlobalContext, id keybase1.TeamID) (name keybase1.TeamName, err error) {
	return resolveIDToName(ctx, g, id, true)
}
185873
func (hs *HTTPServer) UpdateTeam(c *m.ReqContext, cmd m.UpdateTeamCommand) Response {
	cmd.OrgId = c.OrgId
	cmd.Id = c.ParamsInt64(":teamId")

	if err := teamguardian.CanAdmin(hs.Bus, cmd.OrgId, cmd.Id, c.SignedInUser); err != nil {
		return Error(403, "Not allowed to update team", err)
	}

	if err := hs.Bus.Dispatch(&cmd); err != nil {
		if err == m.ErrTeamNameTaken {
			return Error(400, "Team name taken", err)
		}
		return Error(500, "Failed to update Team", err)
	}

	return Success("Team updated")
}
191536
func ResolveNameToID(ctx context.Context, g *libkb.GlobalContext, name keybase1.TeamName) (id keybase1.TeamID, err error) {
	return resolveNameToID(ctx, g, name, false)
}
665041
func ResolveNameToIDForceRefresh(ctx context.Context, g *libkb.GlobalContext, name keybase1.TeamName) (id keybase1.TeamID, err error) {
	return resolveNameToID(ctx, g, name, true)
}
124423
func (k *KBPKIClient) CreateTeamTLF(
	ctx context.Context, teamID keybase1.TeamID, tlfID tlf.ID) error {
	return k.serviceOwner.KeybaseService().CreateTeamTLF(ctx, teamID, tlfID)
}
955006
func (s *AdminService) UpdateTeamLDAPMapping(ctx context.Context, team int64, mapping *TeamLDAPMapping) (*TeamLDAPMapping, *Response, error) {
	u := fmt.Sprintf("admin/ldap/teams/%v/mapping", team)
	req, err := s.client.NewRequest("PATCH", u, mapping)
	if err != nil {
		return nil, nil, err
	}

	m := new(TeamLDAPMapping)
	resp, err := s.client.Do(ctx, req, m)
	if err != nil {
		return nil, resp, err
	}

	return m, resp, nil
}
51585
func LookupImplicitTeam(ctx context.Context, g *libkb.GlobalContext, displayName string, public bool, opts ImplicitTeamOptions) (
	team *Team, teamName keybase1.TeamName, impTeamName keybase1.ImplicitTeamDisplayName, err error) {
	team, teamName, impTeamName, _, err = LookupImplicitTeamAndConflicts(ctx, g, displayName, public, opts)
	return team, teamName, impTeamName, err
}
1022857
func (l *localLoadedTeams) getTeamForMember(ctx context.Context, member keybase1.MemberInfo,
	needAdmin bool) (team *Team, uv keybase1.UserVersion, err error) {
	teamID := member.TeamID
	team = l.teams[teamID]
	if team == nil {
		// Team was not there in local cache - this is the first time
		// localLoadedTeams is asked for this team. Try with no
		// forceRepoll first.
		team, err = Load(ctx, l.G(), keybase1.LoadTeamArg{
			ID:               teamID,
			NeedAdmin:        needAdmin,
			Public:           teamID.IsPublic(),
			ForceRepoll:      false,
			RefreshUIDMapper: true,
		})
		if err != nil {
			return nil, uv, err
		}
		l.teams[teamID] = team
	}

	memberUV, err := verifyMemberRoleInTeam(ctx, member.UserID, member.Role, team)
	if err != nil {
		team, err = Load(ctx, l.G(), keybase1.LoadTeamArg{
			ID:          teamID,
			NeedAdmin:   needAdmin,
			Public:      teamID.IsPublic(),
			ForceRepoll: true,
		})
		if err != nil {
			return nil, uv, err
		}
		l.teams[teamID] = team

		memberUV, err = verifyMemberRoleInTeam(ctx, member.UserID, member.Role, team)
		if err != nil {
			return nil, uv, fmt.Errorf("server was wrong about role in team : %v", err)
		}
	}

	return team, memberUV, nil
}
137106
func (l *TeamLoader) checkParentChildOperations(ctx context.Context,
	me keybase1.UserVersion, loadingTeamID keybase1.TeamID, parentID *keybase1.TeamID, readSubteamID keybase1.TeamID,
	parentChildOperations []*parentChildOperation, proofSet *proofSetT) error {

	if len(parentChildOperations) == 0 {
		return nil
	}
	if parentID == nil {
		return fmt.Errorf("cannot check parent-child operations with no parent")
	}

	var needParentSeqnos []keybase1.Seqno
	for _, pco := range parentChildOperations {
		needParentSeqnos = append(needParentSeqnos, pco.parentSeqno)
	}

	parent, err := l.load2(ctx, load2ArgT{
		teamID: *parentID,

		reason: "checkParentChildOperations-parent",

		needAdmin:                             false,
		needKeyGeneration:                     0,
		needApplicationsAtGenerations:         nil,
		needApplicationsAtGenerationsWithKBFS: nil,
		wantMembers:                           nil,
		wantMembersRole:                       keybase1.TeamRole_NONE,
		forceFullReload:                       false,
		forceRepoll:                           false,
		staleOK:                               true, // stale is fine, as long as get those seqnos.

		needSeqnos:    needParentSeqnos,
		readSubteamID: &readSubteamID,

		me: me,
	})
	if err != nil {
		return fmt.Errorf("error loading parent: %v", err)
	}

	parentChain := TeamSigChainState{inner: parent.team.Chain}

	for _, pco := range parentChildOperations {
		err = l.checkOneParentChildOperation(ctx, pco, loadingTeamID, &parentChain)
		if err != nil {
			return err
		}
	}

	// Give a more up-to-date linkmap to the ordering checker for the parent.
	// Without this it could fail if the parent is new.
	// Because the team linkmap in the proof objects is stale.
	proofSet.SetTeamLinkMap(ctx, parentChain.inner.Id, parentChain.inner.LinkIDs)

	return nil
}