scimitar 2.1.1 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|