Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce instance organization permissions list operation #176

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 23 additions & 22 deletions clerk/clerk.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
42 changes: 42 additions & 0 deletions clerk/instance_organization_permissions.go
Original file line number Diff line number Diff line change
@@ -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
}
75 changes: 75 additions & 0 deletions clerk/instance_organization_permissions_test.go
Original file line number Diff line number Diff line change
@@ -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
}`
28 changes: 8 additions & 20 deletions clerk/instance_organization_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,21 @@ 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 {
Data []InsOrgRole `json:"data"`
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"`
Expand Down
Loading