scimitar 2.1.1 → 2.1.3
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/active_record_backed_resources_controller.rb +1 -0
- data/app/models/scimitar/lists/query_parser.rb +11 -1
- data/lib/scimitar/version.rb +2 -2
- data/spec/apps/dummy/app/models/mock_user.rb +8 -5
- data/spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb +5 -0
- data/spec/apps/dummy/db/schema.rb +3 -2
- data/spec/models/scimitar/lists/query_parser_spec.rb +1 -1
- data/spec/models/scimitar/schema/attribute_spec.rb +0 -3
- data/spec/requests/active_record_backed_resources_controller_spec.rb +88 -4
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68d1c5d2f9f2b72a4582a04d6430b6fd7fd62ffc3fcdfe39422f2159acdcd3e1
|
4
|
+
data.tar.gz: 23a4d69326377dc1e68d3e1ff09d17a3adbc0e922bee7be6289acec2c4d790e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98e7ececc69633a18c3e4f1b946f586959177223317a050edf8e1e8a916727f18f01e6cfb1103ff31a65c890708e6c85c41d42478636c9a4924efa99817b4a98
|
7
|
+
data.tar.gz: 9674932b834c16f8176340bfa826ebac4d06e6aade8c561c484f1031877f6803ef732210b43ed0613972fe44aeb98707a429a1f5a87388909c1a0694cdfe9f98
|
@@ -78,7 +78,7 @@ module Scimitar
|
|
78
78
|
# method's return value here.
|
79
79
|
#
|
80
80
|
def initialize(attribute_map)
|
81
|
-
@attribute_map = attribute_map
|
81
|
+
@attribute_map = attribute_map.with_indifferent_case_insensitive_access()
|
82
82
|
end
|
83
83
|
|
84
84
|
# Parse SCIM filter query into RPN stack
|
@@ -605,6 +605,16 @@ module Scimitar
|
|
605
605
|
|
606
606
|
raise Scimitar::FilterError unless all_supported
|
607
607
|
|
608
|
+
unless case_sensitive
|
609
|
+
lc_scim_attribute = scim_attribute.downcase()
|
610
|
+
|
611
|
+
case_sensitive = (
|
612
|
+
lc_scim_attribute == 'id' ||
|
613
|
+
lc_scim_attribute == 'externalid' ||
|
614
|
+
lc_scim_attribute.start_with?('meta.')
|
615
|
+
)
|
616
|
+
end
|
617
|
+
|
608
618
|
column_names.each.with_index do | column_name, index |
|
609
619
|
arel_column = arel_table[column_name]
|
610
620
|
arel_operation = case scim_operator
|
data/lib/scimitar/version.rb
CHANGED
@@ -3,11 +3,11 @@ module Scimitar
|
|
3
3
|
# Gem version. If this changes, be sure to re-run "bundle install" or
|
4
4
|
# "bundle update".
|
5
5
|
#
|
6
|
-
VERSION = '2.1.
|
6
|
+
VERSION = '2.1.3'
|
7
7
|
|
8
8
|
# Date for VERSION. If this changes, be sure to re-run "bundle install"
|
9
9
|
# or "bundle update".
|
10
10
|
#
|
11
|
-
DATE = '
|
11
|
+
DATE = '2023-01-09'
|
12
12
|
|
13
13
|
end
|
@@ -92,11 +92,14 @@ class MockUser < ActiveRecord::Base
|
|
92
92
|
|
93
93
|
def self.scim_queryable_attributes
|
94
94
|
return {
|
95
|
-
'
|
96
|
-
'
|
97
|
-
'
|
98
|
-
'
|
99
|
-
'
|
95
|
+
'id' => { column: :id },
|
96
|
+
'externalId' => { column: :scim_uid },
|
97
|
+
'meta.lastModified' => { column: :updated_at },
|
98
|
+
'name.givenName' => { column: :first_name },
|
99
|
+
'name.familyName' => { column: :last_name },
|
100
|
+
'emails' => { columns: [ :work_email_address, :home_email_address ] },
|
101
|
+
'emails.value' => { columns: [ :work_email_address, :home_email_address ] },
|
102
|
+
'emails.type' => { ignore: true } # We can't filter on that; it'll just search all e-mails
|
100
103
|
}
|
101
104
|
end
|
102
105
|
|
@@ -10,8 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
14
|
-
|
13
|
+
ActiveRecord::Schema[7.0].define(version: 2023_01_09_012729) do
|
15
14
|
# These are extensions that must be enabled in order to support this database
|
16
15
|
enable_extension "plpgsql"
|
17
16
|
|
@@ -37,6 +36,8 @@ ActiveRecord::Schema.define(version: 2021_03_08_044214) do
|
|
37
36
|
t.text "work_email_address"
|
38
37
|
t.text "home_email_address"
|
39
38
|
t.text "work_phone_number"
|
39
|
+
t.datetime "created_at", null: false
|
40
|
+
t.datetime "updated_at", null: false
|
40
41
|
end
|
41
42
|
|
42
43
|
end
|
@@ -590,7 +590,7 @@ RSpec.describe Scimitar::Lists::QueryParser do
|
|
590
590
|
end
|
591
591
|
|
592
592
|
it 'complains if there is no column mapping available' do
|
593
|
-
expect { @instance.send(:activerecord_columns, '
|
593
|
+
expect { @instance.send(:activerecord_columns, 'userName') }.to raise_error(Scimitar::FilterError)
|
594
594
|
end
|
595
595
|
|
596
596
|
it 'complains about malformed declarations' do
|
@@ -21,10 +21,8 @@ RSpec.describe Scimitar::Schema::Attribute do
|
|
21
21
|
expect(name.type).to eql('complex')
|
22
22
|
expect(name.subAttributes).to eql(Scimitar::Schema::Name.scim_attributes)
|
23
23
|
end
|
24
|
-
|
25
24
|
end
|
26
25
|
|
27
|
-
|
28
26
|
context '#valid?' do
|
29
27
|
it 'is invalid if attribute is required but value is blank' do
|
30
28
|
attribute = described_class.new(name: 'userName', type: 'string', required: true)
|
@@ -76,5 +74,4 @@ RSpec.describe Scimitar::Schema::Attribute do
|
|
76
74
|
expect(described_class.new(name: 'startDate', type: 'dateTime').valid?('gaga')).to be(false)
|
77
75
|
end
|
78
76
|
end
|
79
|
-
|
80
77
|
end
|
@@ -1,12 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'time'
|
2
3
|
|
3
4
|
RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
4
5
|
before :each do
|
5
6
|
allow_any_instance_of(Scimitar::ApplicationController).to receive(:authenticated?).and_return(true)
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
@
|
8
|
+
lmt = Time.parse("2023-01-09 14:25:00 +1300")
|
9
|
+
|
10
|
+
@u1 = MockUser.create(username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com', scim_uid: '001', created_at: lmt, updated_at: lmt + 1)
|
11
|
+
@u2 = MockUser.create(username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com', scim_uid: '002', created_at: lmt, updated_at: lmt + 2)
|
12
|
+
@u3 = MockUser.create(username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com', scim_uid: '003', created_at: lmt, updated_at: lmt + 3)
|
10
13
|
end
|
11
14
|
|
12
15
|
# ===========================================================================
|
@@ -48,7 +51,7 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
48
51
|
it 'applies a filter, with case-insensitive value comparison' do
|
49
52
|
get '/Users', params: {
|
50
53
|
format: :scim,
|
51
|
-
filter: 'name.givenName eq "
|
54
|
+
filter: 'name.givenName eq "FOO" and name.familyName pr and emails ne "home_1@test.com"'
|
52
55
|
}
|
53
56
|
|
54
57
|
expect(response.status).to eql(200)
|
@@ -64,6 +67,87 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
64
67
|
expect(usernames).to match_array(['2'])
|
65
68
|
end
|
66
69
|
|
70
|
+
it 'applies a filter, with case-insensitive attribute matching (GitHub issue #37)' do
|
71
|
+
get '/Users', params: {
|
72
|
+
format: :scim,
|
73
|
+
filter: 'name.GIVENNAME eq "Foo" and name.Familyname pr and emails ne "home_1@test.com"'
|
74
|
+
}
|
75
|
+
|
76
|
+
expect(response.status).to eql(200)
|
77
|
+
result = JSON.parse(response.body)
|
78
|
+
|
79
|
+
expect(result['totalResults']).to eql(1)
|
80
|
+
expect(result['Resources'].size).to eql(1)
|
81
|
+
|
82
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
83
|
+
expect(ids).to match_array([@u2.id.to_s])
|
84
|
+
|
85
|
+
usernames = result['Resources'].map { |resource| resource['userName'] }
|
86
|
+
expect(usernames).to match_array(['2'])
|
87
|
+
end
|
88
|
+
|
89
|
+
# Strange attribute capitalisation in tests here builds on test coverage
|
90
|
+
# for now-fixed GitHub issue #37.
|
91
|
+
#
|
92
|
+
context '"meta" / IDs (GitHub issue #36)' do
|
93
|
+
it 'applies a filter on primary keys, using direct comparison (rather than e.g. case-insensitive operators)' do
|
94
|
+
get '/Users', params: {
|
95
|
+
format: :scim,
|
96
|
+
filter: "id eq \"#{@u3.id}\""
|
97
|
+
}
|
98
|
+
|
99
|
+
expect(response.status).to eql(200)
|
100
|
+
result = JSON.parse(response.body)
|
101
|
+
|
102
|
+
expect(result['totalResults']).to eql(1)
|
103
|
+
expect(result['Resources'].size).to eql(1)
|
104
|
+
|
105
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
106
|
+
expect(ids).to match_array([@u3.id.to_s])
|
107
|
+
|
108
|
+
usernames = result['Resources'].map { |resource| resource['userName'] }
|
109
|
+
expect(usernames).to match_array(['3'])
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'applies a filter on external IDs, using direct comparison' do
|
113
|
+
get '/Users', params: {
|
114
|
+
format: :scim,
|
115
|
+
filter: "externalID eq \"#{@u2.scim_uid}\""
|
116
|
+
}
|
117
|
+
|
118
|
+
expect(response.status).to eql(200)
|
119
|
+
result = JSON.parse(response.body)
|
120
|
+
|
121
|
+
expect(result['totalResults']).to eql(1)
|
122
|
+
expect(result['Resources'].size).to eql(1)
|
123
|
+
|
124
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
125
|
+
expect(ids).to match_array([@u2.id.to_s])
|
126
|
+
|
127
|
+
usernames = result['Resources'].map { |resource| resource['userName'] }
|
128
|
+
expect(usernames).to match_array(['2'])
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'applies a filter on "meta" entries, using direct comparison' do
|
132
|
+
get '/Users', params: {
|
133
|
+
format: :scim,
|
134
|
+
filter: "Meta.LastModified eq \"#{@u3.updated_at}\""
|
135
|
+
}
|
136
|
+
|
137
|
+
expect(response.status).to eql(200)
|
138
|
+
result = JSON.parse(response.body)
|
139
|
+
|
140
|
+
expect(result['totalResults']).to eql(1)
|
141
|
+
expect(result['Resources'].size).to eql(1)
|
142
|
+
|
143
|
+
ids = result['Resources'].map { |resource| resource['id'] }
|
144
|
+
expect(ids).to match_array([@u3.id.to_s])
|
145
|
+
|
146
|
+
usernames = result['Resources'].map { |resource| resource['userName'] }
|
147
|
+
expect(usernames).to match_array(['3'])
|
148
|
+
end
|
149
|
+
end # "context '"meta" / IDs (GitHub issue #36)' do"
|
150
|
+
|
67
151
|
it 'obeys a page size' do
|
68
152
|
get '/Users', params: {
|
69
153
|
format: :scim,
|
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: 2.1.
|
4
|
+
version: 2.1.3
|
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:
|
12
|
+
date: 2023-01-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -211,6 +211,7 @@ files:
|
|
211
211
|
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|
212
212
|
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
213
213
|
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
214
|
+
- spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
|
214
215
|
- spec/apps/dummy/db/schema.rb
|
215
216
|
- spec/controllers/scimitar/application_controller_spec.rb
|
216
217
|
- spec/controllers/scimitar/resource_types_controller_spec.rb
|
@@ -282,6 +283,7 @@ test_files:
|
|
282
283
|
- spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb
|
283
284
|
- spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
|
284
285
|
- spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
|
286
|
+
- spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
|
285
287
|
- spec/apps/dummy/db/schema.rb
|
286
288
|
- spec/controllers/scimitar/application_controller_spec.rb
|
287
289
|
- spec/controllers/scimitar/resource_types_controller_spec.rb
|