diff --git a/clerk/clerk.go b/clerk/clerk.go index 91c5cdd1..19f0ef77 100644 --- a/clerk/clerk.go +++ b/clerk/clerk.go @@ -19,28 +19,29 @@ const version = "1.48.4" const ( ProdUrl = "https://api.clerk.dev/v1/" - ActorTokensUrl = "actor_tokens" - AllowlistsUrl = "allowlist_identifiers" - BlocklistsUrl = "blocklist_identifiers" - ClientsUrl = "clients" - ClientsVerifyUrl = ClientsUrl + "/verify" - DomainsURL = "domains" - EmailAddressesURL = "email_addresses" - EmailsUrl = "emails" - InvitationsURL = "invitations" - OrganizationsUrl = "organizations" - OrganizationRolesUrl = "organization_roles" - PhoneNumbersURL = "phone_numbers" - ProxyChecksURL = "proxy_checks" - RedirectURLsUrl = "redirect_urls" - SAMLConnectionsUrl = "saml_connections" - SessionsUrl = "sessions" - SMSUrl = "sms_messages" - TemplatesUrl = "templates" - UsersUrl = "users" - UsersCountUrl = UsersUrl + "/count" - WebhooksUrl = "webhooks" - JWTTemplatesUrl = "jwt_templates" + ActorTokensUrl = "actor_tokens" + AllowlistsUrl = "allowlist_identifiers" + BlocklistsUrl = "blocklist_identifiers" + ClientsUrl = "clients" + ClientsVerifyUrl = ClientsUrl + "/verify" + DomainsURL = "domains" + EmailAddressesURL = "email_addresses" + EmailsUrl = "emails" + InvitationsURL = "invitations" + OrganizationsUrl = "organizations" + OrganizationRolesUrl = "organization_roles" + OrganizationPermissionsUrl = "organization_permissions" + PhoneNumbersURL = "phone_numbers" + ProxyChecksURL = "proxy_checks" + RedirectURLsUrl = "redirect_urls" + SAMLConnectionsUrl = "saml_connections" + SessionsUrl = "sessions" + SMSUrl = "sms_messages" + TemplatesUrl = "templates" + UsersUrl = "users" + UsersCountUrl = UsersUrl + "/count" + WebhooksUrl = "webhooks" + JWTTemplatesUrl = "jwt_templates" ) var defaultHTTPClient = &http.Client{Timeout: time.Second * 5} diff --git a/clerk/instance_organization_permissions.go b/clerk/instance_organization_permissions.go new file mode 100644 index 00000000..dbf1acf0 --- /dev/null +++ b/clerk/instance_organization_permissions.go @@ -0,0 +1,42 @@ +package clerk + +import ( + "net/http" +) + +type OrganizationPermission struct { + Object string `json:"object"` + ID string `json:"id"` + Name string `json:"name"` + Key string `json:"key"` + Description string `json:"description"` + Type string `json:"type"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` +} + +type OrganizationPermissionsResponse struct { + Data []OrganizationPermission `json:"data"` + TotalCount int64 `json:"total_count"` +} + +type ListInstanceOrganizationPermissionsParams struct { + Limit *int `json:"limit,omitempty"` + Offset *int `json:"offset,omitempty"` +} + +func (s *InstanceService) ListOrganizationPermissions(params ListInstanceOrganizationPermissionsParams) (*OrganizationPermissionsResponse, error) { + req, _ := s.client.NewRequest(http.MethodGet, OrganizationPermissionsUrl) + + paginationParams := PaginationParams{Limit: params.Limit, Offset: params.Offset} + query := req.URL.Query() + addPaginationParams(query, paginationParams) + req.URL.RawQuery = query.Encode() + + response := &OrganizationPermissionsResponse{} + _, err := s.client.Do(req, response) + if err != nil { + return nil, err + } + return response, nil +} diff --git a/clerk/instance_organization_permissions_test.go b/clerk/instance_organization_permissions_test.go new file mode 100644 index 00000000..9fb87d99 --- /dev/null +++ b/clerk/instance_organization_permissions_test.go @@ -0,0 +1,75 @@ +package clerk + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestInstanceService_List_happyPathWithParameters(t *testing.T) { + client, mux, _, teardown := setup("token") + defer teardown() + + expectedResponse := fmt.Sprintf(`{ + "data": [%s], + "total_count": 1 + }`, dummyOrganizationPermissionsJson) + + mux.HandleFunc("/organization_permissions", func(w http.ResponseWriter, req *http.Request) { + testHttpMethod(t, req, http.MethodGet) + testHeader(t, req, "Authorization", "Bearer token") + + actualQuery := req.URL.Query() + expectedQuery := url.Values(map[string][]string{ + "limit": {"3"}, + "offset": {"2"}, + }) + assert.Equal(t, expectedQuery, actualQuery) + fmt.Fprint(w, expectedResponse) + }) + + want := &OrganizationPermissionsResponse{} + _ = json.Unmarshal([]byte(expectedResponse), want) + + got, _ := client.Instances().ListOrganizationPermissions(ListInstanceOrganizationPermissionsParams{ + Limit: intToPtr(3), + Offset: intToPtr(2), + }) + if len(got.Data) != len(want.Data) { + t.Errorf("Was expecting %d organization permissions to be returned, instead got %d", len(want.Data), len(got.Data)) + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("Response = %v, want %v", got, want) + } +} + +func TestInstanceService_List_invalidServer(t *testing.T) { + client, _ := NewClient("token") + + orgPermissions, err := client.Instances().ListOrganizationPermissions(ListInstanceOrganizationPermissionsParams{}) + if err == nil { + t.Errorf("Expected error to be returned") + } + if orgPermissions != nil { + t.Errorf("Was not expecting any organization permissions to be returned, instead got %v", orgPermissions) + } +} + +const dummyOrganizationPermissionID = "perm_1mebQggrD3xO5JfuHk7clQ94ysA" + +const dummyOrganizationPermissionsJson = `{ + "object": "permission", + "id": "perm_1mebQggrD3xO5JfuHk7clQ94ysA", + "name": "Manage organization", + "key": "org:sys_profile:manage", + "description": "Permission to manage an organization.", + "type": "system", + "created_at": 1610783813, + "updated_at": 1610783813 +}` diff --git a/clerk/instance_organization_roles.go b/clerk/instance_organization_roles.go index 98a44daa..e51b7667 100644 --- a/clerk/instance_organization_roles.go +++ b/clerk/instance_organization_roles.go @@ -7,14 +7,14 @@ import ( ) type InsOrgRole struct { - Object string `json:"object"` - ID string `json:"id"` - Name string `json:"name"` - Key string `json:"key"` - Description string `json:"description"` - Permissions []InsOrgPermission `json:"permissions"` - CreatedAt int64 `json:"created_at"` - UpdatedAt int64 `json:"updated_at"` + Object string `json:"object"` + ID string `json:"id"` + Name string `json:"name"` + Key string `json:"key"` + Description string `json:"description"` + Permissions []OrganizationPermission `json:"permissions"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` } type InsOrgRolesResponse struct { @@ -22,18 +22,6 @@ type InsOrgRolesResponse struct { TotalCount int64 `json:"total_count"` } -// TODO: move this to a separate file once custom permissions endpoints are done -type InsOrgPermission struct { - Object string `json:"object"` - ID string `json:"id"` - Name string `json:"name"` - Key string `json:"key"` - Description string `json:"description"` - Type string `json:"type"` - CreatedAt int64 `json:"created_at"` - UpdatedAt int64 `json:"updated_at"` -} - type CreateInsOrgRoleParams struct { Name string `json:"name"` Key string `json:"key"`