// AddMembership adds an organization user to a given team with a specified role
//
// https://developer.github.com/v3/orgs/teams/#add-team-membership
182562
func (t *TeamsService) AddMembership(uri *Hyperlink, uriParams M, role string) (
	membership TeamMembership, result *Result) {
	url, err := ExpandWithDefault(uri, &TeamMembershipURL, uriParams)
	if err != nil {
		return TeamMembership{}, &Result{Err: err}
	}
	result = t.client.put(url, M{"role": role}, &membership)
	return
}
135784
func (s *Service) TeamMemberCreateOrUpdate(ctx context.Context, teamIdentity string, o TeamMemberCreateOrUpdateOpts) (*TeamMember, error) {
	var teamMember TeamMember
	return &teamMember, s.Put(ctx, &teamMember, fmt.Sprintf("/teams/%v/members", teamIdentity), o)
}
940988
func AddMembers(ctx context.Context, g *libkb.GlobalContext, teamname string, users []keybase1.UserRolePair) (res []AddMembersRes, err error) {
	tracer := g.CTimeTracer(ctx, "team.AddMembers", true)
	defer tracer.Finish()
	teamName, err := keybase1.TeamNameFromString(teamname)
	if err != nil {
		return nil, err
	}
	teamID, err := ResolveNameToID(ctx, g, teamName)
	if err != nil {
		return nil, err
	}

	err = RetryIfPossible(ctx, g, func(ctx context.Context, _ int) error {
		res = make([]AddMembersRes, len(users))
		team, err := GetForTeamManagementByTeamID(ctx, g, teamID, true /*needAdmin*/)
		if err != nil {
			return err
		}

		tx := CreateAddMemberTx(team)
		type sweepEntry struct {
			Assertion string
			UV        keybase1.UserVersion
		}
		var sweep []sweepEntry
		for i, user := range users {
			username, uv, invite, err := tx.AddMemberByAssertionOrEmail(ctx, user.AssertionOrEmail, user.Role)
			if err != nil {
				if _, ok := err.(AttemptedInviteSocialOwnerError); ok {
					return err
				}
				return NewAddMembersError(user.AssertionOrEmail, err)
			}
			var normalizedUsername libkb.NormalizedUsername
			if !username.IsNil() {
				normalizedUsername = username
			}
			res[i] = AddMembersRes{
				Invite:   invite,
				Username: normalizedUsername,
			}
			if !uv.IsNil() {
				sweep = append(sweep, sweepEntry{
					Assertion: user.AssertionOrEmail,
					UV:        uv,
				})
			}
		}

		// Try to mark completed any invites for the users' social assertions.
		// This can be a time-intensive process since it involves checking proofs.
		// It is limited to a few seconds and failure is non-fatal.
		timeoutCtx, timeoutCancel := context.WithTimeout(ctx, 2*time.Second)
		for _, x := range sweep {
			if err := tx.CompleteSocialInvitesFor(timeoutCtx, x.UV, x.Assertion); err != nil {
				g.Log.CWarningf(ctx, "Failed in CompleteSocialInvitesFor(%v, %v) -> %v", x.UV, x.Assertion, err)
			}
		}
		timeoutCancel()

		return tx.Post(libkb.NewMetaContext(ctx, g))
	})
	if err != nil {
		return nil, err
	}
	return res, nil
}
16103
func (s *Service) OrganizationMemberCreate(ctx context.Context, organizationIdentity string, o OrganizationMemberCreateOpts) (*OrganizationMember, error) {
	var organizationMember OrganizationMember
	return &organizationMember, s.Post(ctx, &organizationMember, fmt.Sprintf("/organizations/%v/members", organizationIdentity), o)
}
484634
func (m *Manager) UpdateMembership(globalid string, username string, oldrole string, newrole string) error {
	qry := bson.M{"globalid": globalid}
	pull := bson.M{
		"$pull": bson.M{oldrole: username},
	}
	push := bson.M{
		"$addToSet": bson.M{newrole: username},
	}
	err := m.collection.Update(qry, pull)
	if err != nil {
		return err
	}
	return m.collection.Update(qry, push)
}
116377
func (org *User) AddMember(uid int64) error {
	return AddOrgUser(org.ID, uid)
}
100761
func (c *Client) AddMember(name string, peerAddrs string) ([]Member, error) {
	// Parse the peer address, required to add the client URL later to the list
	// of endpoints for this client. Parsing as a first operation to make sure that
	// if this fails no member addition is performed on the etcd cluster.
	parsedPeerAddrs, err := url.Parse(peerAddrs)
	if err != nil {
		return nil, errors.Wrapf(err, "error parsing peer address %s", peerAddrs)
	}

	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   c.Endpoints,
		DialTimeout: 20 * time.Second,
		TLS:         c.TLS,
	})
	if err != nil {
		return nil, err
	}
	defer cli.Close()

	// Adds a new member to the cluster
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	resp, err := cli.MemberAdd(ctx, []string{peerAddrs})
	cancel()
	if err != nil {
		return nil, err
	}

	// Returns the updated list of etcd members
	ret := []Member{}
	for _, m := range resp.Members {
		// fixes the entry for the joining member (that doesn't have a name set in the initialCluster returned by etcd)
		if m.Name == "" {
			ret = append(ret, Member{Name: name, PeerURL: m.PeerURLs[0]})
		} else {
			ret = append(ret, Member{Name: m.Name, PeerURL: m.PeerURLs[0]})
		}
	}

	// Add the new member client address to the list of endpoints
	c.Endpoints = append(c.Endpoints, GetClientURLByIP(parsedPeerAddrs.Hostname()))

	return ret, nil
}
779295
func (t *TeamsService) RemoveMembership(uri *Hyperlink, uriParams M) (success bool, result *Result) {
	url, err := ExpandWithDefault(uri, &TeamMembershipURL, uriParams)
	if err != nil {
		return false, &Result{Err: err}
	}
	result = t.client.delete(url, nil, nil)
	success = (result.Response.StatusCode == 204)
	return
}
1260356
func (r *Client) AddActualOrgUser(userRole UserRole) (StatusMessage, error) {
	var (
		raw  []byte
		resp StatusMessage
		err  error
	)
	if raw, err = json.Marshal(userRole); err != nil {
		return StatusMessage{}, err
	}
	if raw, _, err = r.post("api/org/users", nil, raw); err != nil {
		return StatusMessage{}, err
	}
	if err = json.Unmarshal(raw, &resp); err != nil {
		return StatusMessage{}, err
	}
	return resp, nil
}
107727
func (m *memberSet) AddRemainingRecipients(ctx context.Context, g *libkb.GlobalContext, existing keybase1.TeamMembers) (err error) {

	defer g.CTrace(ctx, "memberSet#AddRemainingRecipients", func() error { return err })()

	// make a map of the None members
	noneMap := make(map[keybase1.UserVersion]bool)
	for _, n := range m.None {
		noneMap[n.version] = true
	}

	auv := existing.AllUserVersions()
	forceUserPoll := true
	if len(auv) > 50 {
		forceUserPoll = false
	}

	for _, uv := range auv {
		if noneMap[uv] {
			continue
		}
		if _, ok := m.recipients[uv]; ok {
			continue
		}
		if _, err := m.loadMember(ctx, g, uv, true, forceUserPoll); err != nil {
			if _, reset := err.(libkb.AccountResetError); reset {
				g.Log.CDebugf(ctx, "Skipping user who was reset: %s", uv.String())
				continue
			}
			return err
		}
	}

	return nil
}
976992
func (s *ListTeamMembersOutput) SetTeamMembers(v []*TeamMember) *ListTeamMembersOutput {
	s.TeamMembers = v
	return s
}
839858
func (c oauthClient) AddMemberToListViaUserID(userID uint, listID uint, muted bool) (wl.Membership, error) {
	if userID == 0 {
		return wl.Membership{}, errors.New("userID must be > 0")
	}

	if listID == 0 {
		return wl.Membership{}, errors.New("listID must be > 0")
	}

	url := fmt.Sprintf("%s/memberships", c.apiURL)
	body := []byte(
		fmt.Sprintf(
			`{"user_id":%d,"list_id":%d,"muted":%t}`,
			userID,
			listID,
			muted,
		),
	)

	req, err := c.newPostRequest(url, body)
	if err != nil {
		return wl.Membership{}, err
	}

	resp, err := c.do(req)
	if err != nil {
		return wl.Membership{}, err
	}

	if resp.StatusCode != http.StatusCreated {
		return wl.Membership{}, fmt.Errorf("Unexpected response code %d - expected %d", resp.StatusCode, http.StatusCreated)
	}

	membership := wl.Membership{}
	err = json.NewDecoder(resp.Body).Decode(&membership)
	if err != nil {
		return wl.Membership{}, err
	}

	return membership, nil
}
542106
func (s *Service) TeamMemberDelete(ctx context.Context, teamIdentity string, teamMemberIdentity string) (*TeamMember, error) {
	var teamMember TeamMember
	return &teamMember, s.Delete(ctx, &teamMember, fmt.Sprintf("/teams/%v/members/%v", teamIdentity, teamMemberIdentity))
}
35608
func (s *OrganizationsService) IsMember(ctx context.Context, org, user string) (bool, *Response, error) {
	u := fmt.Sprintf("orgs/%v/members/%v", org, user)
	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return false, nil, err
	}

	resp, err := s.client.Do(ctx, req, nil)
	member, err := parseBoolResponse(err)
	return member, resp, err
}
867772
func (m *Manager) SaveMember(organization *Organization, username string) error {
	return m.collection.Update(
		bson.M{"globalid": organization.Globalid},
		bson.M{"$addToSet": bson.M{"members": username}})
}
851881
func (s *TeamsService) GetTeamMembership(ctx context.Context, team int64, user string) (*Membership, *Response, error) {
	u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	req.Header.Set("Accept", mediaTypeNestedTeamsPreview)

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

	return t, resp, nil
}
992534
func NewMemberAddArg(MemberEmail string) *MemberAddArg {
	s := new(MemberAddArg)
	s.MemberEmail = MemberEmail
	s.SendWelcomeEmail = true
	s.Role = &AdminTier{Tagged: dropbox.Tagged{"member_only"}}
	return s
}