diff --git a/lib/workos.rb b/lib/workos.rb index ae959d5c..37b8d83b 100644 --- a/lib/workos.rb +++ b/lib/workos.rb @@ -71,6 +71,7 @@ def self.key autoload :Profile, 'workos/profile' autoload :ProfileAndToken, 'workos/profile_and_token' autoload :RefreshAuthenticationResponse, 'workos/refresh_authentication_response' + autoload :Role, 'workos/role' autoload :Session, 'workos/session' autoload :SSO, 'workos/sso' autoload :Types, 'workos/types' diff --git a/lib/workos/organizations.rb b/lib/workos/organizations.rb index bedf28ef..d8ecb5c5 100644 --- a/lib/workos/organizations.rb +++ b/lib/workos/organizations.rb @@ -180,6 +180,32 @@ def delete_organization(id:) response.is_a? Net::HTTPSuccess end + # Retrieve a list of roles for the given organization. + # + # @param [String] organizationId The ID of the organization to fetch roles for. + def list_organization_roles(organization_id:) + response = execute_request( + request: get_request( + path: "/organizations/#{organization_id}/roles", + auth: true, + ), + ) + + parsed_response = JSON.parse(response.body) + + roles = parsed_response['data'].map do |role| + WorkOS::Role.new(role.to_json) + end + + WorkOS::Types::ListStruct.new( + data: roles, + list_metadata: { + after: nil, + before: nil, + }, + ) + end + private def check_and_raise_organization_error(response:) diff --git a/lib/workos/role.rb b/lib/workos/role.rb new file mode 100644 index 00000000..5838cb41 --- /dev/null +++ b/lib/workos/role.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module WorkOS + # The Role class provides a lightweight wrapper around + # a WorkOS Role resource. This class is not meant to be instantiated + # in user space, and is instantiated internally but exposed. + class Role + include HashProvider + + attr_accessor :id, :name, :slug, :description, :type, :created_at, :updated_at + + def initialize(json) + hash = JSON.parse(json, symbolize_names: true) + + @id = hash[:id] + @name = hash[:name] + @slug = hash[:slug] + @description = hash[:description] + @type = hash[:type] + @created_at = hash[:created_at] + @updated_at = hash[:updated_at] + end + + def to_json(*) + { + id: id, + name: name, + slug: slug, + description: description, + type: type, + created_at: created_at, + updated_at: updated_at, + } + end + end +end diff --git a/spec/lib/workos/organizations_spec.rb b/spec/lib/workos/organizations_spec.rb index bf9deb91..30be9337 100644 --- a/spec/lib/workos/organizations_spec.rb +++ b/spec/lib/workos/organizations_spec.rb @@ -323,4 +323,22 @@ end end end + + describe '.list_organization_roles' do + context 'with no options' do + it 'returns roles for organization' do + expected_metadata = { + after: nil, + before: nil, + } + + VCR.use_cassette 'organization/list_organization_roles' do + roles = described_class.list_organization_roles(organization_id: 'org_01JEXP6Z3X7HE4CB6WQSH9ZAFE') + + expect(roles.data.size).to eq(7) + expect(roles.list_metadata).to eq(expected_metadata) + end + end + end + end end diff --git a/spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml b/spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml new file mode 100644 index 00000000..c07d5690 --- /dev/null +++ b/spec/support/fixtures/vcr_cassettes/organization/list_organization_roles.yml @@ -0,0 +1,82 @@ +--- +http_interactions: + - request: + method: get + uri: https://api.workos.com/organizations/org_01JEXP6Z3X7HE4CB6WQSH9ZAFE/roles + body: + encoding: US-ASCII + string: "" + headers: + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - WorkOS; ruby/3.3.6; arm64-darwin23; v5.9.0 + Authorization: + - Bearer + response: + status: + code: 200 + message: OK + headers: + Date: + - Mon, 23 Dec 2024 20:23:07 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Cf-Ray: + - 8f6b114e5e60c96a-IAD + Cf-Cache-Status: + - DYNAMIC + Etag: + - W/"6b6-bZ2pS5djCBrbcATBSFlbZ90PHB8" + Strict-Transport-Security: + - max-age=15552000; includeSubDomains + Vary: + - Origin, Accept-Encoding + Access-Control-Allow-Credentials: + - "true" + Content-Security-Policy: + - "default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' + https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src + 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests" + Expect-Ct: + - max-age=0 + Referrer-Policy: + - no-referrer + X-Content-Type-Options: + - nosniff + X-Dns-Prefetch-Control: + - "off" + X-Download-Options: + - noopen + X-Frame-Options: + - SAMEORIGIN + X-Permitted-Cross-Domain-Policies: + - none + X-Request-Id: + - a8db37d7-9244-4e2a-b183-b5e2a67d8104 + X-Xss-Protection: + - "0" + Server: + - cloudflare + body: + encoding: ASCII-8BIT + string: + '{"object":"list","data":[{"object":"role","id":"role_01HS1C7GRJE08PBR3M6Y0ZYGDZ","description":"Write + access to every resource available","name":"Admin","slug":"admin","type":"EnvironmentRole","created_at":"2024-03-15T15:38:29.521Z","updated_at":"2024-11-14T17:08:00.556Z"},{"object":"role","id":"role_01JA8GJZRDSZEB9289DQXJ3N9Z","description":"","name":"Billing + Manager","slug":"billing","type":"EnvironmentRole","created_at":"2024-10-15T16:36:11.653Z","updated_at":"2024-12-19T21:27:01.286Z"},{"object":"role","id":"role_01HSBH4R6RX0V86S3R590NNZW2","description":"Developer + role","name":"Developer","slug":"developer","type":"EnvironmentRole","created_at":"2024-03-19T14:16:46.038Z","updated_at":"2024-03-19T14:16:46.038Z"},{"object":"role","id":"role_01HS4GDWJ8T6NQPTX2D0R5KBHN","description":"Edit + and view access to non-critical resources","name":"Editor","slug":"editor","type":"EnvironmentRole","created_at":"2024-03-16T20:49:35.815Z","updated_at":"2024-03-16T20:52:19.410Z"},{"object":"role","id":"role_01HRFZE22WS2MGX6EWAG2JX6NW","description":"The + default user role","name":"Member","slug":"member","type":"EnvironmentRole","created_at":"2024-03-08T21:27:47.034Z","updated_at":"2024-08-14T00:27:46.265Z"},{"object":"role","id":"role_01JEYJ2Z5MYG0TZYTDF02MW11N","description":"Manage + billing for organization.","name":"Billing manager","slug":"org-billing-manager","type":"OrganizationRole","created_at":"2024-12-12T23:08:28.712Z","updated_at":"2024-12-12T23:08:28.712Z"},{"object":"role","id":"role_01JF0B7MQ9X414WQRAQMQYE1GS","description":"","name":"Platform + Manager","slug":"org-platform-manager","type":"OrganizationRole","created_at":"2024-12-13T15:47:10.692Z","updated_at":"2024-12-13T15:47:10.692Z"}]}' + http_version: + recorded_at: Mon, 23 Dec 2024 20:23:07 GMT +recorded_with: VCR 5.0.0