// OrganizationInvites returns list of invites for specified organization of
// the logged-in user.
//
// API reference: https://api.cloudflare.com/#organization-invites
977554
func (api *API) OrganizationInvites(organizationID string) ([]OrganizationInvite, ResultInfo, error) {
	var r organizationInvitesResponse
	uri := "/organizations/" + organizationID + "/invites"
	res, err := api.makeRequest("GET", uri, nil)
	if err != nil {
		return []OrganizationInvite{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
	}

	err = json.Unmarshal(res, &r)
	if err != nil {
		return []OrganizationInvite{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError)
	}

	return r.Result, r.ResultInfo, nil
}
1222431
func (s *Service) OrganizationFeatureList(ctx context.Context, organizationIdentity string, lr *ListRange) (OrganizationFeatureListResult, error) {
	var organizationFeature OrganizationFeatureListResult
	return organizationFeature, s.Get(ctx, &organizationFeature, fmt.Sprintf("/organizations/%v/features", organizationIdentity), nil, lr)
}
892076
func (c *Client) OrganizationAppListForOrganization(organizationIdentity string, lr *ListRange) ([]OrganizationApp, error) {
	req, err := c.NewRequest("GET", "/organizations/"+organizationIdentity+"/apps", nil, nil)
	if err != nil {
		return nil, err
	}

	if lr != nil {
		lr.SetHeader(req)
	}

	var organizationAppsRes []OrganizationApp
	return organizationAppsRes, c.DoReq(req, &organizationAppsRes)
}
833274
func NewInvitationManager(r *http.Request) *InvitationManager {
	session := db.GetDBSession(r)
	return &InvitationManager{
		session:    session,
		collection: getOrganizationRequestCollection(session),
	}
}
86425
func (c *Client) OrganizationAppList(lr *ListRange) ([]OrganizationApp, error) {
	req, err := c.NewRequest("GET", "/organizations/apps", nil, nil)
	if err != nil {
		return nil, err
	}

	if lr != nil {
		lr.SetHeader(req)
	}

	var organizationAppsRes []OrganizationApp
	return organizationAppsRes, c.DoReq(req, &organizationAppsRes)
}
59469
func (c *InvitationController) CreateInvite(ctx *app.CreateInviteInvitationContext) error {
	currentIdentity, err := c.app.UserService().LoadContextIdentityIfNotBanned(ctx)
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, err)
	}

	var redirectOnSuccess, redirectOnFailure string
	links := ctx.Payload.Links
	if links != nil {
		if links.OnSuccess != nil {
			redirectOnSuccess = *links.OnSuccess
		}
		if links.OnFailure != nil {
			redirectOnFailure = *links.OnFailure
		}
	}

	var invitations []invitation.Invitation

	for _, invitee := range ctx.Payload.Data {
		// Validate that an identifying parameter has been set
		if invitee.IdentityID == nil {
			return jsonapi.JSONErrorResponse(ctx, errors.NewBadParameterErrorFromString("user identifier", "", "no identifier provided"))
		}

		// If an identity ID has been provided for the user, convert it to a UUID here
		var identityID uuid.UUID
		if invitee.IdentityID != nil && *invitee.IdentityID != "" {
			identityID, err = uuid.FromString(*invitee.IdentityID)
		}

		// Create the Invitation object, and append it to our list of invitations
		invitations = append(invitations, invitation.Invitation{
			IdentityID:        &identityID,
			Roles:             invitee.Roles,
			Member:            *invitee.Member,
			RedirectOnSuccess: redirectOnSuccess,
			RedirectOnFailure: redirectOnFailure,
		})
	}

	err = c.app.InvitationService().Issue(ctx, currentIdentity.ID, ctx.InviteTo, invitations)

	if err != nil {
		log.Error(ctx, map[string]interface{}{
			"err": err,
		}, "failed to create invitations")

		return jsonapi.JSONErrorResponse(ctx, err)
	}

	log.Debug(ctx, map[string]interface{}{
		"issuing-user-id": *currentIdentity,
		"invite-to":       ctx.InviteTo,
	}, "invitations created")

	return ctx.Created()
}
982018
func (s *OrganizationsService) ListOrgMemberships(ctx context.Context, opt *ListOrgMembershipsOptions) ([]*Membership, *Response, error) {
	u := "user/memberships/orgs"
	u, err := addOptions(u, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, nil, err
	}

	var memberships []*Membership
	resp, err := s.client.Do(ctx, req, &memberships)
	if err != nil {
		return nil, resp, err
	}

	return memberships, resp, nil
}
1108155
func (api OrganizationsAPI) autoAcceptSubOrgInvite(invite *invitations.JoinOrganizationInvitation, mgr *organization.Manager) (bool, error) {
	globalid := invite.Organization

	// If this is an invite for a root organization we obviously aren't a member of a parent yet
	if !strings.Contains(globalid, ".") {
		return false, nil
	}

	// Check for username so we only auto accept already registered users
	// Not sure if this is needed but it doesn't hurt to check
	username := invite.User
	if username == "" {
		log.Debug("can't auto accept the invite because the username is not known")
		return false, nil
	}

	// Check if we happen to be a member or owner of a parent org
	orgs, err := mgr.AllByUser(username)
	if err != nil {
		return false, err
	}
	inParent := false
	for _, org := range orgs {
		// adding the  "." is required here.
		if strings.HasPrefix(globalid, org.Globalid+".") {
			inParent = true
			break
		}
	}

	if !inParent {
		return false, nil
	}

	// add the user
	org, err := mgr.GetByName(invite.Organization)
	if err != nil {
		return false, err
	}
	if invitations.RoleOwner == invite.Role {
		// Accepted Owner role
		if err := mgr.SaveOwner(org, username); err != nil {
			return false, err
		}
	} else {
		// Accepted member role
		if err := mgr.SaveMember(org, username); err != nil {
			return false, err
		}
	}
	// set the invite to status accpeted
	invite.Status = invitations.RequestAccepted
	log.Debug("Invitation auto accepted because the user is already an owner or member of a parent organization")
	return true, nil
}
186582
func (o *InvitationManager) HasPhoneInvite(globalid string, phonenumber string) (hasInvite bool, err error) {
	count, err := o.collection.Find(bson.M{"organization": globalid, "phonenumber": phonenumber}).Count()
	return count != 0, err
}
546274
func (api *API) ListOrganizations() ([]Organization, ResultInfo, error) {
	var r organizationResponse
	res, err := api.makeRequest("GET", "/user/organizations", nil)
	if err != nil {
		return []Organization{}, ResultInfo{}, errors.Wrap(err, errMakeRequestError)
	}

	err = json.Unmarshal(res, &r)
	if err != nil {
		return []Organization{}, ResultInfo{}, errors.Wrap(err, errUnmarshalError)
	}

	return r.Result, r.ResultInfo, nil
}
918799
func (t *Team) InviteMember(ctx context.Context, username string, role keybase1.TeamRole, resolvedUsername libkb.NormalizedUsername, uv keybase1.UserVersion) (keybase1.TeamAddMemberResult, error) {
	// if a user version was previously loaded, then there is a keybase user for username, but
	// without a PUK or without any keys.
	if uv.Uid.Exists() {
		return t.inviteKeybaseMember(ctx, uv, role, resolvedUsername)
	}

	// If a social, or email, or other type of invite, assert it's not an owner.
	if role.IsOrAbove(keybase1.TeamRole_OWNER) {
		return keybase1.TeamAddMemberResult{}, errors.New("You cannot invite an owner to a team.")
	}

	return t.inviteSBSMember(ctx, username, role)
}
846765
func (o *InvitationManager) HasInvite(globalid string, username string) (hasInvite bool, err error) {
	count, err := o.collection.Find(bson.M{"organization": globalid, "user": username}).Count()
	return count != 0, err
}
511592
func (s *Service) OrganizationInvitationRevoke(ctx context.Context, organizationIdentity string, organizationInvitationIdentity string) (*OrganizationInvitation, error) {
	var organizationInvitation OrganizationInvitation
	return &organizationInvitation, s.Delete(ctx, &organizationInvitation, fmt.Sprintf("/organizations/%v/invitations/%v", organizationIdentity, organizationInvitationIdentity))
}
922611
func (c *InvitationController) RescindInvite(ctx *app.RescindInviteInvitationContext) error {
	currentIdentity, err := c.app.UserService().LoadContextIdentityIfNotBanned(ctx)
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, err)
	}

	invitationID, err := uuid.FromString(ctx.InviteTo)
	if err != nil {
		log.Error(ctx, map[string]interface{}{
			"err":          err,
			"invitationID": invitationID,
		}, "failed to rescind invitation, invalid invitation id")

		return jsonapi.JSONErrorResponse(ctx, errors.NewNotFoundError("invitationID", invitationID.String()))
	}

	err = c.app.InvitationService().Rescind(ctx, currentIdentity.ID, invitationID)

	if err != nil {
		log.Error(ctx, map[string]interface{}{
			"err":          err,
			"invitationID": invitationID,
		}, "failed to rescind invitation")
		return jsonapi.JSONErrorResponse(ctx, err)
	}

	log.Debug(ctx, map[string]interface{}{
		"rescinding-user-id": *currentIdentity,
		"invitation-id":      ctx.InviteTo,
	}, "invitation rescind")

	return ctx.OK([]byte{})
}
25124
func (s *Service) OrganizationInvoiceList(ctx context.Context, organizationIdentity string, lr *ListRange) (OrganizationInvoiceListResult, error) {
	var organizationInvoice OrganizationInvoiceListResult
	return organizationInvoice, s.Get(ctx, &organizationInvoice, fmt.Sprintf("/organizations/%v/invoices", organizationIdentity), nil, lr)
}
1346539
func (s *OrgService) FindOrganizations(ctx context.Context, filter influxdb.OrganizationFilter, opt ...influxdb.FindOptions) ([]*influxdb.Organization, int, error) {
	// TODO: we'll likely want to push this operation into the database eventually since fetching the whole list of data
	// will likely be expensive.
	os, _, err := s.s.FindOrganizations(ctx, filter, opt...)
	if err != nil {
		return nil, 0, err
	}

	// This filters without allocating
	// https://github.com/golang/go/wiki/SliceTricks#filtering-without-allocating
	orgs := os[:0]
	for _, o := range os {
		err := authorizeReadOrg(ctx, o.ID)
		if err != nil && influxdb.ErrorCode(err) != influxdb.EUnauthorized {
			return nil, 0, err
		}

		if influxdb.ErrorCode(err) == influxdb.EUnauthorized {
			continue
		}

		orgs = append(orgs, o)
	}

	return orgs, len(orgs), nil
}
387504
func (c *Client) OrganizationAppTransferToOrganization(appIdentity string, owner string) (*OrganizationApp, error) {
	params := struct {
		Owner string `json:"owner"`
	}{
		Owner: owner,
	}
	var organizationAppRes OrganizationApp
	return &organizationAppRes, c.Patch(&organizationAppRes, "/organizations/apps/"+appIdentity, params)
}