Skip to content

Commit 14285a2

Browse files
authored
Add "role" to organization membership and directory sync user (#309)
1 parent 15c2449 commit 14285a2

File tree

13 files changed

+92
-32
lines changed

13 files changed

+92
-32
lines changed

lib/workos/directory_user.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class DirectoryUser < DeprecatedHashWrapper
88
include HashProvider
99

1010
attr_accessor :id, :idp_id, :emails, :first_name, :last_name, :job_title, :username, :state,
11-
:groups, :custom_attributes, :raw_attributes, :directory_id, :organization_id,
11+
:groups, :role, :custom_attributes, :raw_attributes, :directory_id, :organization_id,
1212
:created_at, :updated_at
1313

1414
# rubocop:disable Metrics/AbcSize
@@ -26,6 +26,7 @@ def initialize(json)
2626
@username = hash[:username]
2727
@state = hash[:state]
2828
@groups = hash[:groups]
29+
@role = hash[:role]
2930
@custom_attributes = hash[:custom_attributes]
3031
@raw_attributes = hash[:raw_attributes]
3132
@created_at = hash[:created_at]
@@ -48,6 +49,7 @@ def to_json(*)
4849
username: username,
4950
state: state,
5051
groups: groups,
52+
role: role,
5153
custom_attributes: custom_attributes,
5254
raw_attributes: raw_attributes,
5355
created_at: created_at,

lib/workos/organization_membership.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module WorkOS
77
class OrganizationMembership
88
include HashProvider
99

10-
attr_accessor :id, :user_id, :organization_id, :status, :created_at, :updated_at
10+
attr_accessor :id, :user_id, :organization_id, :status, :role, :created_at, :updated_at
1111

1212
def initialize(json)
1313
hash = JSON.parse(json, symbolize_names: true)
@@ -16,6 +16,7 @@ def initialize(json)
1616
@user_id = hash[:user_id]
1717
@organization_id = hash[:organization_id]
1818
@status = hash[:status]
19+
@role = hash[:role]
1920
@created_at = hash[:created_at]
2021
@updated_at = hash[:updated_at]
2122
end
@@ -26,6 +27,7 @@ def to_json(*)
2627
user_id: user_id,
2728
organization_id: organization_id,
2829
status: status,
30+
role: role,
2931
created_at: created_at,
3032
updated_at: updated_at,
3133
}

lib/workos/user_management.rb

+24-1
Original file line numberDiff line numberDiff line change
@@ -841,14 +841,37 @@ def list_organization_memberships(options = {})
841841
#
842842
# @param [String] user_id The ID of the User.
843843
# @param [String] organization_id The ID of the Organization to which the user belongs to.
844+
# @param [String] role_slug The slug of the role to grant to this membership. (Optional)
844845
#
845846
# @return [WorkOS::OrganizationMembership]
846-
def create_organization_membership(user_id:, organization_id:)
847+
def create_organization_membership(user_id:, organization_id:, role_slug: nil)
847848
request = post_request(
848849
path: '/user_management/organization_memberships',
849850
body: {
850851
user_id: user_id,
851852
organization_id: organization_id,
853+
role_slug: role_slug,
854+
},
855+
auth: true,
856+
)
857+
858+
response = execute_request(request: request)
859+
860+
WorkOS::OrganizationMembership.new(response.body)
861+
end
862+
863+
# Update an Organization Membership
864+
#
865+
# @param [String] organization_membership_id The ID of the Organization Membership.
866+
# @param [String] role_slug The slug of the role to grant to this membership.
867+
#
868+
# @return [WorkOS::OrganizationMembership]
869+
def update_organization_membership(organization_membership_id:, role_slug:)
870+
request = put_request(
871+
path: "/user_management/organization_memberships/#{id}",
872+
body: {
873+
organization_membership_id: organization_membership_id,
874+
role_slug: role_slug,
852875
},
853876
auth: true,
854877
)

spec/lib/workos/directory_sync_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,10 @@
462462
'directory_user_01FAZYNPC8M0HRYTKFP2GNX852',
463463
)
464464

465-
expect(user['first_name']).to eq('Logan')
465+
expect(user['first_name']).to eq('Bob')
466466
expect(user.directory_id).to eq('directory_01FAZYMST676QMTFN1DDJZZX87')
467467
expect(user.organization_id).to eq('org_01FAZWCWR03DVWA83NCJYKKD54')
468-
expect(user.first_name).to eq('Logan')
468+
expect(user.first_name).to eq('Bob')
469469
end
470470
end
471471
end

spec/lib/workos/directory_user_spec.rb

+22-6
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,47 @@
55
describe '.get_primary_email' do
66
context 'with one primary email' do
77
it 'returns the primary email' do
8-
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[{"primary":true,"value":"logan@workos.com"}, {"primary":false,"value":"logan@gmail.com"}],"first_name":"Logan","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}')
9-
expect(user.primary_email).to eq('logan@workos.com')
8+
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"bob.fakename@workos.com","emails":[{"primary":true,"value":"bob.fakename@workos.com"}, {"primary":false,"value":"Bob@gmail.com"}],"first_name":"Bob","last_name":"Fakename","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}')
9+
expect(user.primary_email).to eq('bob.fakename@workos.com')
1010
end
1111
end
1212

1313
context 'with multiple primary emails' do
1414
it 'returns the first email marked as primary' do
15-
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[{"primary":true,"value":"logan@workos.com"}, {"primary":true,"value":"logan@gmail.com"}],"first_name":"Logan","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}')
16-
expect(user.primary_email).to eq('logan@workos.com')
15+
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"bob.fakename@workos.com","emails":[{"primary":true,"value":"bob.fakename@workos.com"}, {"primary":true,"value":"Bob@gmail.com"}],"first_name":"Bob","last_name":"Fakename","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}')
16+
expect(user.primary_email).to eq('bob.fakename@workos.com')
1717
end
1818
end
1919

2020
context 'with no primary emails' do
2121
it 'returns nil' do
22-
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[{"primary":false,"value":"logan@gmail.com"}],"first_name":"Logan","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z","updated_at":"2022-07-13T17:45:42.618Z"}')
22+
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"bob.fakename@workos.com","emails":[{"primary":false,"value":"Bob@gmail.com"}],"first_name":"Bob","last_name":"Fakename","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z","updated_at":"2022-07-13T17:45:42.618Z"}')
2323
expect(user.primary_email).to eq(nil)
2424
end
2525
end
2626

2727
context 'with an empty email array' do
2828
it 'returns nil' do
29-
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"logan@workos.com","emails":[],"first_name":"Logan","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z","updated_at":"2022-07-13T17:45:42.618Z"}')
29+
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"bob.fakename@workos.com","emails":[],"first_name":"Bob","last_name":"Fakename","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z","updated_at":"2022-07-13T17:45:42.618Z"}')
3030
expect(user.primary_email).to eq(nil)
3131
end
3232
end
3333
end
34+
35+
describe '.get_role' do
36+
context 'with no role' do
37+
it 'returns no role' do
38+
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"[email protected]","emails":[{"primary":true,"value":"[email protected]"}, {"primary":false,"value":"[email protected]"}],"first_name":"Bob","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}')
39+
expect(user.role).to eq(nil)
40+
end
41+
end
42+
43+
context 'with a role' do
44+
it 'returns the role slug' do
45+
user = WorkOS::DirectoryUser.new('{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","idp_id":"6092c280a3f1e19ef6d8cef8","username":"[email protected]","emails":[{"primary":true,"value":"[email protected]"}, {"primary":false,"value":"[email protected]"}],"first_name":"Bob","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"role":{"slug":"member"},"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}')
46+
expect(user.role).to eq({ slug: 'member' })
47+
end
48+
end
49+
end
3450
# rubocop:enable Layout/LineLength
3551
end

spec/lib/workos/user_management_spec.rb

+27-10
Original file line numberDiff line numberDiff line change
@@ -1039,19 +1039,36 @@
10391039

10401040
expect(organization_membership.organization_id).to eq('organization_01H5JQDV7R7ATEYZDEG0W5PRYS')
10411041
expect(organization_membership.user_id).to eq('user_01H5JQDV7R7ATEYZDEG0W5PRYS')
1042+
expect(organization_membership.role).to eq({ slug: 'member' })
10421043
end
10431044
end
1045+
end
10441046

1045-
context 'with an invalid payload' do
1046-
it 'returns an error' do
1047-
VCR.use_cassette 'user_management/create_organization_membership/invalid' do
1048-
expect do
1049-
described_class.create_organization_membership(user_id: '', organization_id: '')
1050-
end.to raise_error(
1051-
WorkOS::UnprocessableEntityError,
1052-
/user_id_string_required/,
1053-
)
1054-
end
1047+
context 'with an invalid payload' do
1048+
it 'returns an error' do
1049+
VCR.use_cassette 'user_management/create_organization_membership/invalid' do
1050+
expect do
1051+
described_class.create_organization_membership(user_id: '', organization_id: '')
1052+
end.to raise_error(
1053+
WorkOS::UnprocessableEntityError,
1054+
/user_id_string_required/,
1055+
)
1056+
end
1057+
end
1058+
end
1059+
1060+
context 'with a role slug' do
1061+
it 'creates an organization with the given role slug ' do
1062+
VCR.use_cassette 'user_management/create_organization_membership/valid' do
1063+
organization_membership = described_class.create_organization_membership(
1064+
user_id: 'user_01H5JQDV7R7ATEYZDEG0W5PRYS',
1065+
organization_id: 'org_01H5JQDV7R7ATEYZDEG0W5PRYS',
1066+
role_slug: 'member',
1067+
)
1068+
1069+
expect(organization_membership.organization_id).to eq('organization_01H5JQDV7R7ATEYZDEG0W5PRYS')
1070+
expect(organization_membership.user_id).to eq('user_01H5JQDV7R7ATEYZDEG0W5PRYS')
1071+
expect(organization_membership.role).to eq({ slug: 'member' })
10551072
end
10561073
end
10571074
end

spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)