github.com/clerkinc/clerk-sdk-go@v1.49.1/clerk/organizations.go (about)

     1  package clerk
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"mime/multipart"
     9  	"net/http"
    10  	"strconv"
    11  )
    12  
    13  type OrganizationsService service
    14  
    15  type Organization struct {
    16  	Object                string          `json:"object"`
    17  	ID                    string          `json:"id"`
    18  	Name                  string          `json:"name"`
    19  	Slug                  *string         `json:"slug"`
    20  	LogoURL               *string         `json:"logo_url"`
    21  	ImageURL              *string         `json:"image_url,omitempty"`
    22  	HasImage              bool            `json:"has_image"`
    23  	MembersCount          *int            `json:"members_count,omitempty"`
    24  	MaxAllowedMemberships int             `json:"max_allowed_memberships"`
    25  	AdminDeleteEnabled    bool            `json:"admin_delete_enabled"`
    26  	PublicMetadata        json.RawMessage `json:"public_metadata"`
    27  	PrivateMetadata       json.RawMessage `json:"private_metadata,omitempty"`
    28  	CreatedBy             string          `json:"created_by"`
    29  	CreatedAt             int64           `json:"created_at"`
    30  	UpdatedAt             int64           `json:"updated_at"`
    31  }
    32  
    33  type CreateOrganizationParams struct {
    34  	Name                  string          `json:"name"`
    35  	Slug                  *string         `json:"slug,omitempty"`
    36  	CreatedBy             string          `json:"created_by"`
    37  	MaxAllowedMemberships *int            `json:"max_allowed_memberships,omitempty"`
    38  	PublicMetadata        json.RawMessage `json:"public_metadata,omitempty"`
    39  	PrivateMetadata       json.RawMessage `json:"private_metadata,omitempty"`
    40  }
    41  
    42  func (s *OrganizationsService) Create(params CreateOrganizationParams) (*Organization, error) {
    43  	req, _ := s.client.NewRequest(http.MethodPost, OrganizationsUrl, &params)
    44  
    45  	var organization Organization
    46  	_, err := s.client.Do(req, &organization)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	return &organization, nil
    51  }
    52  
    53  type UpdateOrganizationParams struct {
    54  	Name                  *string         `json:"name,omitempty"`
    55  	Slug                  *string         `json:"slug,omitempty"`
    56  	MaxAllowedMemberships *int            `json:"max_allowed_memberships,omitempty"`
    57  	AdminDeleteEnabled    *bool           `json:"admin_delete_enabled,omitempty"`
    58  	PublicMetadata        json.RawMessage `json:"public_metadata,omitempty"`
    59  	PrivateMetadata       json.RawMessage `json:"private_metadata,omitempty"`
    60  }
    61  
    62  func (s *OrganizationsService) Update(organizationID string, params UpdateOrganizationParams) (*Organization, error) {
    63  	req, _ := s.client.NewRequest(http.MethodPatch, fmt.Sprintf("%s/%s", OrganizationsUrl, organizationID), &params)
    64  
    65  	var organization Organization
    66  	_, err := s.client.Do(req, &organization)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	return &organization, nil
    71  }
    72  
    73  type UpdateOrganizationLogoParams struct {
    74  	File           multipart.File
    75  	UploaderUserID string
    76  	Filename       *string
    77  }
    78  
    79  func (s *OrganizationsService) UpdateLogo(organizationID string, params UpdateOrganizationLogoParams) (*Organization, error) {
    80  	var buf bytes.Buffer
    81  	w := multipart.NewWriter(&buf)
    82  	uploaderUserID, err := w.CreateFormField("uploader_user_id")
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	uploaderUserID.Write([]byte(params.UploaderUserID))
    87  
    88  	filename := "file"
    89  	if params.Filename != nil {
    90  		filename = *params.Filename
    91  	}
    92  	file, err := w.CreateFormFile("file", filename)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	defer params.File.Close()
    97  	_, err = io.Copy(file, params.File)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	w.Close()
   102  
   103  	req, err := s.client.NewRequest(http.MethodPut, fmt.Sprintf("%s/%s/logo", OrganizationsUrl, organizationID))
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	req.Body = io.NopCloser(&buf)
   108  	req.Header.Set("content-type", w.FormDataContentType())
   109  
   110  	var organization Organization
   111  	_, err = s.client.Do(req, &organization)
   112  	return &organization, err
   113  }
   114  
   115  func (s *OrganizationsService) DeleteLogo(organizationID string) (*Organization, error) {
   116  	req, _ := s.client.NewRequest(http.MethodDelete, fmt.Sprintf("%s/%s/logo", OrganizationsUrl, organizationID))
   117  	var organization Organization
   118  	_, err := s.client.Do(req, &organization)
   119  	return &organization, err
   120  }
   121  
   122  type UpdateOrganizationMetadataParams struct {
   123  	PublicMetadata  json.RawMessage `json:"public_metadata,omitempty"`
   124  	PrivateMetadata json.RawMessage `json:"private_metadata,omitempty"`
   125  }
   126  
   127  func (s *OrganizationsService) UpdateMetadata(organizationID string, params UpdateOrganizationMetadataParams) (*Organization, error) {
   128  	req, _ := s.client.NewRequest(http.MethodPatch, fmt.Sprintf("%s/%s/metadata", OrganizationsUrl, organizationID), &params)
   129  
   130  	var organization Organization
   131  	_, err := s.client.Do(req, &organization)
   132  	return &organization, err
   133  }
   134  
   135  func (s *OrganizationsService) Delete(organizationID string) (*DeleteResponse, error) {
   136  	req, _ := s.client.NewRequest(http.MethodDelete, fmt.Sprintf("%s/%s", OrganizationsUrl, organizationID))
   137  
   138  	var deleteResponse DeleteResponse
   139  	_, err := s.client.Do(req, &deleteResponse)
   140  	if err != nil {
   141  		return nil, err
   142  	}
   143  	return &deleteResponse, nil
   144  }
   145  
   146  func (s *OrganizationsService) Read(organizationIDOrSlug string) (*Organization, error) {
   147  	req, err := s.client.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", OrganizationsUrl, organizationIDOrSlug))
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  
   152  	var organization Organization
   153  	_, err = s.client.Do(req, &organization)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  	return &organization, nil
   158  }
   159  
   160  type OrganizationsResponse struct {
   161  	Data       []Organization `json:"data"`
   162  	TotalCount int64          `json:"total_count"`
   163  }
   164  
   165  type ListAllOrganizationsParams struct {
   166  	Limit               *int
   167  	Offset              *int
   168  	IncludeMembersCount bool
   169  	Query               string
   170  	UserIDs             []string
   171  	OrderBy             *string
   172  }
   173  
   174  func (s *OrganizationsService) ListAll(params ListAllOrganizationsParams) (*OrganizationsResponse, error) {
   175  	req, _ := s.client.NewRequest(http.MethodGet, OrganizationsUrl)
   176  
   177  	query := req.URL.Query()
   178  	if params.Limit != nil {
   179  		query.Set("limit", strconv.Itoa(*params.Limit))
   180  	}
   181  	if params.Offset != nil {
   182  		query.Set("offset", strconv.Itoa(*params.Offset))
   183  	}
   184  	if params.IncludeMembersCount {
   185  		query.Set("include_members_count", strconv.FormatBool(params.IncludeMembersCount))
   186  	}
   187  	if params.Query != "" {
   188  		query.Add("query", params.Query)
   189  	}
   190  	if params.OrderBy != nil {
   191  		query.Add("order_by", *params.OrderBy)
   192  	}
   193  	for _, userID := range params.UserIDs {
   194  		query.Add("user_id", userID)
   195  	}
   196  	req.URL.RawQuery = query.Encode()
   197  
   198  	var organizationsResponse *OrganizationsResponse
   199  	_, err := s.client.Do(req, &organizationsResponse)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  	return organizationsResponse, nil
   204  }
   205  
   206  type OrganizationInvitation struct {
   207  	Object         string          `json:"object"`
   208  	ID             string          `json:"id"`
   209  	EmailAddress   string          `json:"email_address"`
   210  	OrganizationID string          `json:"organization_id"`
   211  	PublicMetadata json.RawMessage `json:"public_metadata"`
   212  	Role           string          `json:"role"`
   213  	Status         string          `json:"status"`
   214  	CreatedAt      int64           `json:"created_at"`
   215  	UpdatedAt      int64           `json:"updated_at"`
   216  }
   217  
   218  type CreateOrganizationInvitationParams struct {
   219  	EmailAddress   string          `json:"email_address"`
   220  	InviterUserID  string          `json:"inviter_user_id"`
   221  	OrganizationID string          `json:"organization_id"`
   222  	PublicMetadata json.RawMessage `json:"public_metadata,omitempty"`
   223  	RedirectURL    string          `json:"redirect_url,omitempty"`
   224  	Role           string          `json:"role"`
   225  }
   226  
   227  func (s *OrganizationsService) CreateInvitation(params CreateOrganizationInvitationParams) (*OrganizationInvitation, error) {
   228  	endpoint := fmt.Sprintf("%s/%s/%s", OrganizationsUrl, params.OrganizationID, InvitationsURL)
   229  	req, _ := s.client.NewRequest(http.MethodPost, endpoint, &params)
   230  	var organizationInvitation OrganizationInvitation
   231  	_, err := s.client.Do(req, &organizationInvitation)
   232  	return &organizationInvitation, err
   233  }
   234  
   235  type ListOrganizationMembershipsParams struct {
   236  	OrganizationID string
   237  	Limit          *int
   238  	Offset         *int
   239  	Roles          []string `json:"role"`
   240  	UserIDs        []string `json:"user_id"`
   241  	EmailAddresses []string `json:"email_address"`
   242  	PhoneNumbers   []string `json:"phone_number"`
   243  	Usernames      []string `json:"username"`
   244  	Web3Wallets    []string `json:"web3_wallet"`
   245  	OrderBy        *string  `json:"order_by"`
   246  	Query          *string  `json:"query"`
   247  }
   248  
   249  type ΟrganizationMembershipPublicUserData struct {
   250  	FirstName       *string `json:"first_name"`
   251  	LastName        *string `json:"last_name"`
   252  	ProfileImageURL string  `json:"profile_image_url"`
   253  	ImageURL        *string `json:"image_url,omitempty"`
   254  	HasImage        bool    `json:"has_image"`
   255  	Identifier      string  `json:"identifier"`
   256  	UserID          string  `json:"user_id"`
   257  }
   258  
   259  type OrganizationMembership struct {
   260  	Object          string          `json:"object"`
   261  	ID              string          `json:"id"`
   262  	PublicMetadata  json.RawMessage `json:"public_metadata"`
   263  	PrivateMetadata json.RawMessage `json:"private_metadata"`
   264  	Role            string          `json:"role"`
   265  	CreatedAt       int64           `json:"created_at"`
   266  	UpdatedAt       int64           `json:"updated_at"`
   267  
   268  	Organization   *Organization                         `json:"organization"`
   269  	PublicUserData *ΟrganizationMembershipPublicUserData `json:"public_user_data"`
   270  }
   271  
   272  type ListOrganizationMembershipsResponse struct {
   273  	Data       []OrganizationMembership `json:"data"`
   274  	TotalCount int64                    `json:"total_count"`
   275  }
   276  
   277  func (s *OrganizationsService) addMembersSearchParamsToRequest(r *http.Request, params ListOrganizationMembershipsParams) {
   278  	query := r.URL.Query()
   279  	for _, email := range params.EmailAddresses {
   280  		query.Add("email_address", email)
   281  	}
   282  
   283  	for _, phone := range params.PhoneNumbers {
   284  		query.Add("phone_number", phone)
   285  	}
   286  
   287  	for _, web3Wallet := range params.Web3Wallets {
   288  		query.Add("web3_wallet", web3Wallet)
   289  	}
   290  
   291  	for _, username := range params.Usernames {
   292  		query.Add("username", username)
   293  	}
   294  
   295  	for _, userID := range params.UserIDs {
   296  		query.Add("user_id", userID)
   297  	}
   298  
   299  	for _, role := range params.Roles {
   300  		query.Add("role", role)
   301  	}
   302  
   303  	if params.Query != nil {
   304  		query.Add("query", *params.Query)
   305  	}
   306  
   307  	if params.OrderBy != nil {
   308  		query.Add("order_by", *params.OrderBy)
   309  	}
   310  
   311  	r.URL.RawQuery = query.Encode()
   312  }
   313  
   314  func (s *OrganizationsService) ListMemberships(params ListOrganizationMembershipsParams) (*ListOrganizationMembershipsResponse, error) {
   315  	endpoint := fmt.Sprintf("%s/%s/memberships", OrganizationsUrl, params.OrganizationID)
   316  	req, _ := s.client.NewRequest(http.MethodGet, endpoint)
   317  
   318  	s.addMembersSearchParamsToRequest(req, ListOrganizationMembershipsParams{
   319  		EmailAddresses: params.EmailAddresses,
   320  		PhoneNumbers:   params.PhoneNumbers,
   321  		Web3Wallets:    params.Web3Wallets,
   322  		Usernames:      params.Usernames,
   323  		UserIDs:        params.UserIDs,
   324  		Roles:          params.Roles,
   325  		Query:          params.Query,
   326  		OrderBy:        params.OrderBy,
   327  	})
   328  
   329  	query := req.URL.Query()
   330  	if params.Limit != nil {
   331  		query.Set("limit", strconv.Itoa(*params.Limit))
   332  	}
   333  	if params.Offset != nil {
   334  		query.Set("offset", strconv.Itoa(*params.Offset))
   335  	}
   336  	req.URL.RawQuery = query.Encode()
   337  
   338  	var membershipsResponse *ListOrganizationMembershipsResponse
   339  	_, err := s.client.Do(req, &membershipsResponse)
   340  	if err != nil {
   341  		return nil, err
   342  	}
   343  	return membershipsResponse, nil
   344  }
   345  
   346  type CreateOrganizationMembershipParams struct {
   347  	UserID string `json:"user_id"`
   348  	Role   string `json:"role"`
   349  }
   350  
   351  func (s *OrganizationsService) CreateMembership(organizationID string, params CreateOrganizationMembershipParams) (*OrganizationMembership, error) {
   352  	req, _ := s.client.NewRequest(http.MethodPost, fmt.Sprintf("%s/%s/memberships", OrganizationsUrl, organizationID), &params)
   353  
   354  	var organizationMembership OrganizationMembership
   355  	_, err := s.client.Do(req, &organizationMembership)
   356  	if err != nil {
   357  		return nil, err
   358  	}
   359  	return &organizationMembership, nil
   360  }
   361  
   362  type UpdateOrganizationMembershipParams struct {
   363  	UserID string `json:"user_id"`
   364  	Role   string `json:"role"`
   365  }
   366  
   367  func (s *OrganizationsService) UpdateMembership(organizationID string, params UpdateOrganizationMembershipParams) (*OrganizationMembership, error) {
   368  	req, _ := s.client.NewRequest(http.MethodPatch, fmt.Sprintf("%s/%s/memberships/%s", OrganizationsUrl, organizationID, params.UserID), &params)
   369  
   370  	var organizationMembership OrganizationMembership
   371  	_, err := s.client.Do(req, &organizationMembership)
   372  	if err != nil {
   373  		return nil, err
   374  	}
   375  	return &organizationMembership, nil
   376  }
   377  
   378  func (s *OrganizationsService) DeleteMembership(organizationID, userID string) (*OrganizationMembership, error) {
   379  	req, _ := s.client.NewRequest(http.MethodDelete, fmt.Sprintf("%s/%s/memberships/%s", OrganizationsUrl, organizationID, userID))
   380  
   381  	var organizationMembership OrganizationMembership
   382  	_, err := s.client.Do(req, &organizationMembership)
   383  	if err != nil {
   384  		return nil, err
   385  	}
   386  	return &organizationMembership, nil
   387  }