scimitar 1.4.0 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/scimitar/application_controller.rb +2 -2
- data/app/models/scimitar/resources/mixin.rb +108 -3
- data/lib/scimitar/version.rb +2 -2
- data/spec/apps/dummy/app/models/mock_user.rb +9 -1
- data/spec/apps/dummy/config/initializers/scimitar.rb +37 -0
- data/spec/apps/dummy/config/routes.rb +1 -0
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +8 -0
- data/spec/apps/dummy/db/schema.rb +2 -0
- data/spec/controllers/scimitar/schemas_controller_spec.rb +2 -2
- data/spec/models/scimitar/resources/base_spec.rb +161 -66
- data/spec/models/scimitar/resources/mixin_spec.rb +673 -5
- data/spec/requests/active_record_backed_resources_controller_spec.rb +136 -0
- data/spec/requests/application_controller_spec.rb +10 -0
- metadata +2 -2
@@ -693,6 +693,142 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
693
693
|
result = JSON.parse(response.body)
|
694
694
|
expect(result['status']).to eql('404')
|
695
695
|
end
|
696
|
+
|
697
|
+
context 'when removing users from groups' do
|
698
|
+
before :each do
|
699
|
+
@g1.mock_users << @u1
|
700
|
+
@g1.mock_users << @u2
|
701
|
+
@g1.mock_users << @u3
|
702
|
+
|
703
|
+
# (Self-check) Verify group representation
|
704
|
+
#
|
705
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
706
|
+
|
707
|
+
expect(response.status).to eql(200)
|
708
|
+
result = JSON.parse(response.body)
|
709
|
+
|
710
|
+
expect(result['members'].map { |m| m['value'] }.sort()).to eql(MockUser.pluck(:primary_key).sort())
|
711
|
+
end
|
712
|
+
|
713
|
+
it 'can remove all users' do
|
714
|
+
expect {
|
715
|
+
expect {
|
716
|
+
patch "/Groups/#{@g1.id}", params: {
|
717
|
+
format: :scim,
|
718
|
+
Operations: [
|
719
|
+
{
|
720
|
+
op: 'remove',
|
721
|
+
path: 'members'
|
722
|
+
}
|
723
|
+
]
|
724
|
+
}
|
725
|
+
}.to_not change { MockUser.count }
|
726
|
+
}.to_not change { MockGroup.count }
|
727
|
+
|
728
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
729
|
+
|
730
|
+
expect(response.status).to eql(200)
|
731
|
+
result = JSON.parse(response.body)
|
732
|
+
|
733
|
+
expect(result['members']).to be_empty
|
734
|
+
expect(@g1.reload().mock_users).to be_empty
|
735
|
+
end
|
736
|
+
|
737
|
+
# Define via 'let':
|
738
|
+
#
|
739
|
+
# * Hash 'payload', to send via 'patch'
|
740
|
+
# * MockUser 'removed_user', which is the user that should be removed
|
741
|
+
#
|
742
|
+
shared_examples 'a user remover' do
|
743
|
+
it 'which removes the identified user' do
|
744
|
+
expect {
|
745
|
+
expect {
|
746
|
+
patch "/Groups/#{@g1.id}", params: payload()
|
747
|
+
}.to_not change { MockUser.count }
|
748
|
+
}.to_not change { MockGroup.count }
|
749
|
+
|
750
|
+
expected_remaining_user_ids = MockUser
|
751
|
+
.where.not(primary_key: removed_user().id)
|
752
|
+
.pluck(:primary_key)
|
753
|
+
.sort()
|
754
|
+
|
755
|
+
get "/Groups/#{@g1.id}", params: { format: :scim }
|
756
|
+
|
757
|
+
expect(response.status).to eql(200)
|
758
|
+
result = JSON.parse(response.body)
|
759
|
+
|
760
|
+
expect(result['members'].map { |m| m['value'] }.sort()).to eql(expected_remaining_user_ids)
|
761
|
+
expect(@g1.reload().mock_users.map(&:primary_key).sort()).to eql(expected_remaining_user_ids)
|
762
|
+
end
|
763
|
+
end
|
764
|
+
|
765
|
+
# https://tools.ietf.org/html/rfc7644#section-3.5.2.2
|
766
|
+
#
|
767
|
+
context 'and using an RFC-compliant payload' do
|
768
|
+
let(:removed_user) { @u2 }
|
769
|
+
let(:payload) do
|
770
|
+
{
|
771
|
+
format: :scim,
|
772
|
+
Operations: [
|
773
|
+
{
|
774
|
+
op: 'remove',
|
775
|
+
path: "members[value eq \"#{removed_user().primary_key}\"]",
|
776
|
+
}
|
777
|
+
]
|
778
|
+
}
|
779
|
+
end
|
780
|
+
|
781
|
+
it_behaves_like 'a user remover'
|
782
|
+
end # context 'and using an RFC-compliant payload' do
|
783
|
+
|
784
|
+
# https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
|
785
|
+
#
|
786
|
+
context 'and using a Microsoft variant payload' do
|
787
|
+
let(:removed_user) { @u2 }
|
788
|
+
let(:payload) do
|
789
|
+
{
|
790
|
+
format: :scim,
|
791
|
+
Operations: [
|
792
|
+
{
|
793
|
+
op: 'remove',
|
794
|
+
path: 'members',
|
795
|
+
value: [{
|
796
|
+
'$ref' => nil,
|
797
|
+
'value' => removed_user().primary_key
|
798
|
+
}]
|
799
|
+
}
|
800
|
+
]
|
801
|
+
}
|
802
|
+
end
|
803
|
+
|
804
|
+
it_behaves_like 'a user remover'
|
805
|
+
end # context 'and using a Microsoft variant payload' do
|
806
|
+
|
807
|
+
# https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
|
808
|
+
#
|
809
|
+
context 'and using a Salesforce variant payload' do
|
810
|
+
let(:removed_user) { @u2 }
|
811
|
+
let(:payload) do
|
812
|
+
{
|
813
|
+
format: :scim,
|
814
|
+
Operations: [
|
815
|
+
{
|
816
|
+
op: 'remove',
|
817
|
+
path: 'members',
|
818
|
+
value: {
|
819
|
+
'members' => [{
|
820
|
+
'$ref' => nil,
|
821
|
+
'value' => removed_user().primary_key
|
822
|
+
}]
|
823
|
+
}
|
824
|
+
}
|
825
|
+
]
|
826
|
+
}
|
827
|
+
end
|
828
|
+
|
829
|
+
it_behaves_like 'a user remover'
|
830
|
+
end # context 'and using a Salesforce variant payload' do
|
831
|
+
end # "context 'when removing users from groups' do"
|
696
832
|
end # "context '#update' do"
|
697
833
|
|
698
834
|
# ===========================================================================
|
@@ -39,6 +39,16 @@ RSpec.describe Scimitar::ApplicationController do
|
|
39
39
|
expect(parsed_body['request']['content_type']).to eql('application/scim+json')
|
40
40
|
end
|
41
41
|
|
42
|
+
it 'translates Content-Type with charset to Rails request format' do
|
43
|
+
get '/CustomRequestVerifiers', headers: { 'CONTENT_TYPE' => 'application/scim+json; charset=utf-8' }
|
44
|
+
|
45
|
+
expect(response).to have_http_status(:ok)
|
46
|
+
parsed_body = JSON.parse(response.body)
|
47
|
+
expect(parsed_body['request']['is_scim' ]).to eql(true)
|
48
|
+
expect(parsed_body['request']['format' ]).to eql('application/scim+json')
|
49
|
+
expect(parsed_body['request']['content_type']).to eql('application/scim+json; charset=utf-8')
|
50
|
+
end
|
51
|
+
|
42
52
|
it 'translates Rails request format to header' do
|
43
53
|
get '/CustomRequestVerifiers', params: { format: :scim }
|
44
54
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scimitar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RIPA Global
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-03-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|