diff --git a/lib/workos/directory_user.rb b/lib/workos/directory_user.rb index e51025c7..a168c1ee 100644 --- a/lib/workos/directory_user.rb +++ b/lib/workos/directory_user.rb @@ -8,7 +8,7 @@ class DirectoryUser < DeprecatedHashWrapper include HashProvider attr_accessor :id, :idp_id, :email, :emails, :first_name, :last_name, :job_title, :username, :state, - :groups, :role, :custom_attributes, :raw_attributes, :directory_id, :organization_id, + :groups, :role, :roles, :custom_attributes, :raw_attributes, :directory_id, :organization_id, :created_at, :updated_at # rubocop:disable Metrics/AbcSize @@ -37,6 +37,7 @@ def initialize(json) @state = hash[:state] @groups = hash[:groups] @role = hash[:role] + @roles = hash[:roles] @custom_attributes = hash[:custom_attributes] @raw_attributes = hash[:raw_attributes] @created_at = hash[:created_at] @@ -47,6 +48,13 @@ def initialize(json) # rubocop:enable Metrics/AbcSize def to_json(*) + base_attributes. + merge(authorization_attributes) + end + + private + + def base_attributes { id: id, directory_id: directory_id, @@ -60,7 +68,6 @@ def to_json(*) username: username, state: state, groups: groups, - role: role, custom_attributes: custom_attributes, raw_attributes: raw_attributes, created_at: created_at, @@ -68,6 +75,15 @@ def to_json(*) } end + def authorization_attributes + { + role: role, + roles: roles, + } + end + + public + # @deprecated Will be removed in a future major version. Use {#email} instead. def primary_email primary_email = (emails || []).find { |email| email[:primary] } diff --git a/lib/workos/profile.rb b/lib/workos/profile.rb index 3a02ac62..56c101e7 100644 --- a/lib/workos/profile.rb +++ b/lib/workos/profile.rb @@ -9,7 +9,7 @@ module WorkOS class Profile include HashProvider - attr_accessor :id, :email, :first_name, :last_name, :role, :groups, :organization_id, + attr_accessor :id, :email, :first_name, :last_name, :role, :roles, :groups, :organization_id, :connection_id, :connection_type, :idp_id, :custom_attributes, :raw_attributes # rubocop:disable Metrics/AbcSize @@ -21,6 +21,7 @@ def initialize(profile_json) @first_name = hash[:first_name] @last_name = hash[:last_name] @role = hash[:role] + @roles = hash[:roles] @groups = hash[:groups] @organization_id = hash[:organization_id] @connection_id = hash[:connection_id] @@ -42,6 +43,7 @@ def to_json(*) first_name: first_name, last_name: last_name, role: role, + roles: roles, groups: groups, organization_id: organization_id, connection_id: connection_id, diff --git a/spec/lib/workos/directory_user_spec.rb b/spec/lib/workos/directory_user_spec.rb index 013c2613..e0c02150 100644 --- a/spec/lib/workos/directory_user_spec.rb +++ b/spec/lib/workos/directory_user_spec.rb @@ -37,13 +37,23 @@ it 'returns no role' do 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.fakename@gmail.com"}],"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"}') expect(user.role).to eq(nil) + expect(user.roles).to eq(nil) end end - context 'with a role' do - it 'returns the role slug' do - 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.fakename@gmail.com"}],"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"}') + context 'with a single role' do + it 'returns the highest priority role slug and roles array' do + 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.fakename@gmail.com"}],"first_name":"Bob","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"role":{"slug":"member"},"roles":[{"slug":"member"}],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}') expect(user.role).to eq({ slug: 'member' }) + expect(user.roles).to eq([{ slug: 'member' }]) + end + end + + context 'with multiple roles' do + it 'returns the highest priority role slug and roles array' do + 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.fakename@gmail.com"}],"first_name":"Bob","last_name":"Gingerich","job_title":"Developer Success Engineer","state":"active","raw_attributes":{},"custom_attributes":{},"groups":[],"role":{"slug":"admin"},"roles":[{"slug":"member"}, {"slug":"admin"}],"created_at":"2022-05-13T17:45:31.732Z", "updated_at":"2022-07-13T17:45:42.618Z"}') + expect(user.role).to eq({ slug: 'admin' }) + expect(user.roles).to eq([{ slug: 'member' }, { slug: 'admin' }]) end end end diff --git a/spec/lib/workos/sso_spec.rb b/spec/lib/workos/sso_spec.rb index 6753e306..0af30aed 100644 --- a/spec/lib/workos/sso_spec.rb +++ b/spec/lib/workos/sso_spec.rb @@ -305,6 +305,9 @@ role: { slug: 'member', }, + roles: [{ + slug: 'member', + }], groups: nil, organization_id: 'org_01FG53X8636WSNW2WEKB2C31ZB', custom_attributes: {}, @@ -380,6 +383,9 @@ role: { slug: 'admin', }, + roles: [{ + slug: 'admin', + }], groups: %w[Admins Developers], organization_id: 'org_01FG53X8636WSNW2WEKB2C31ZB', custom_attributes: { diff --git a/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml b/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml index 9c8fe356..25717c4d 100644 --- a/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml +++ b/spec/support/fixtures/vcr_cassettes/directory_sync/get_user.yml @@ -74,7 +74,7 @@ http_interactions: - 72abbbf2b93e8ca5-EWR body: encoding: ASCII-8BIT - string: '{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","organization_id":"org_01FAZWCWR03DVWA83NCJYKKD54","idp_id":"6092c280a3f1e19ef6d8cef8","username":"bob.fakename@workos.com","emails":[{"primary":true,"value":"bob.fakename@workos.com"}],"first_name":"Bob","last_name":"Fakename","job_title":"Developer Success Engineer","state":"active","raw_attributes":{"id":"6092c280a3f1e19ef6d8cef8","name":"Bob + string: '{"object":"directory_user","id":"directory_user_01FAZYNPC8M0HRYTKFP2GNX852","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","organization_id":"org_01FAZWCWR03DVWA83NCJYKKD54","idp_id":"6092c280a3f1e19ef6d8cef8","username":"bob.fakename@workos.com","emails":[{"primary":true,"value":"bob.fakename@workos.com"}],"first_name":"Bob","last_name":"Fakename","job_title":"Developer Success Engineer","state":"active","role":{"slug":"member"},"roles":[{"slug":"member"}],"raw_attributes":{"id":"6092c280a3f1e19ef6d8cef8","name":"Bob Bob Fakename","teams":["5f696c8e9a63a60e965aaca8"],"spokeId":null,"lastName":"Fakename","created_at":"2021-05-05T16:06:24+0000","firstName":"Bob","updated_at":"2021-11-11T05:08:14+0000","workEmail":"bob.fakename@workos.com","department":"Infra","departmentId":"5f27ada9a5e9bc0001a0ae4a"},"custom_attributes":{},"created_at":"2021-07-19T17:57:57.268Z","updated_at":"2022-01-24T11:23:01.614Z","groups":[{"object":"directory_group","id":"directory_group_01FAZYNNQ4HQ6EBF29MPTH7VKB","idp_id":"5f696c8e9a63a60e965aaca8","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","organization_id":"org_01FAZWCWR03DVWA83NCJYKKD54","name":"Team - Platform","created_at":"2021-07-19T17:57:56.580Z","updated_at":"2022-01-24T11:23:01.333Z","raw_attributes":{"id":"5f696c8e9a63a60e965aaca8","name":"Platform","parent":null}},{"object":"directory_group","id":"directory_group_01FAZYNN1NZWMBRAXXDSTB5NFH","idp_id":"5f27ada9a5e9bc0001a0ae4a","directory_id":"directory_01FAZYMST676QMTFN1DDJZZX87","organization_id":"org_01FAZWCWR03DVWA83NCJYKKD54","name":"Department - Infra","role":{"slug":"member"},"created_at":"2021-07-19T17:57:55.893Z","updated_at":"2022-01-24T11:23:01.333Z","raw_attributes":{"id":"5f27ada9a5e9bc0001a0ae4a","name":"Infra","parent":"5f27ada9a5e9bc0001a0ae48"}}]}' diff --git a/spec/support/fixtures/vcr_cassettes/sso/profile.yml b/spec/support/fixtures/vcr_cassettes/sso/profile.yml index 65d6dec3..5fa50a65 100644 --- a/spec/support/fixtures/vcr_cassettes/sso/profile.yml +++ b/spec/support/fixtures/vcr_cassettes/sso/profile.yml @@ -67,7 +67,7 @@ http_interactions: body: encoding: UTF-8 string: - '{"object":"profile","id":"prof_01EEJTY9SZ1R350RB7B73SNBKF","organization_id":"org_01FG53X8636WSNW2WEKB2C31ZB","connection_id":"conn_01E83FVYZHY7DM4S9503JHV0R5","connection_type":"GoogleOAuth","idp_id":"116485463307139932699","email":"bob.loblaw@workos.com","first_name":"Bob","last_name":"Loblaw","role":{"slug":"member"},"custom_attributes":{},"raw_attributes":{"hd":"workos.com","id":"116485463307139932699","name":"Bob + '{"object":"profile","id":"prof_01EEJTY9SZ1R350RB7B73SNBKF","organization_id":"org_01FG53X8636WSNW2WEKB2C31ZB","connection_id":"conn_01E83FVYZHY7DM4S9503JHV0R5","connection_type":"GoogleOAuth","idp_id":"116485463307139932699","email":"bob.loblaw@workos.com","first_name":"Bob","last_name":"Loblaw","role":{"slug":"member"},"roles":[{"slug":"member"}],"custom_attributes":{},"raw_attributes":{"hd":"workos.com","id":"116485463307139932699","name":"Bob Loblaw","email":"bob.loblaw@workos.com","locale":"en","picture":"https://lh3.googleusercontent.com/a-/AOh14GyO2hLlgZvteDQ3Ldi3_-RteZLya0hWH7247Cam=s96-c","given_name":"Bob","family_name":"Loblaw","verified_email":true}}' http_version: recorded_at: Tue, 18 May 2021 22:55:21 GMT diff --git a/spec/support/profile.txt b/spec/support/profile.txt index 7e19a262..5e8df665 100644 --- a/spec/support/profile.txt +++ b/spec/support/profile.txt @@ -1 +1 @@ -{"profile":{"object":"profile","id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","organization_id":"org_01FG53X8636WSNW2WEKB2C31ZB","connection_id":"conn_01EMH8WAK20T42N2NBMNBCYHAG","connection_type":"OktaSAML","last_name":"Demo","role":{"slug": "admin"},"groups":["Admins","Developers"],"idp_id":"00u1klkowm8EGah2H357","custom_attributes":{"license": "professional"},"raw_attributes":{"id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","last_name":"Demo","groups":["Admins","Developers"],"idp_id":"00u1klkowm8EGah2H357","license": "professional"}},"access_token":"01DVX6QBS3EG6FHY2ESAA5Q65X"} +{"profile":{"object":"profile","id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","organization_id":"org_01FG53X8636WSNW2WEKB2C31ZB","connection_id":"conn_01EMH8WAK20T42N2NBMNBCYHAG","connection_type":"OktaSAML","last_name":"Demo","role":{"slug": "admin"},"roles":[{"slug": "admin"}],"groups":["Admins","Developers"],"idp_id":"00u1klkowm8EGah2H357","custom_attributes":{"license": "professional"},"raw_attributes":{"id":"prof_01DRA1XNSJDZ19A31F183ECQW5","email":"demo@workos-okta.com","first_name":"WorkOS","last_name":"Demo","groups":["Admins","Developers"],"idp_id":"00u1klkowm8EGah2H357","license": "professional"}},"access_token":"01DVX6QBS3EG6FHY2ESAA5Q65X"}