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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2418199bee8396f36fd0588b82f111b019d28b095d8830c82c808cc67323f220
4
- data.tar.gz: 0b3fcf08adbbc8d9385e245f4e55b3ca2e30c7a8ce254d9417e4a4ab3a662dcf
3
+ metadata.gz: 68d1c5d2f9f2b72a4582a04d6430b6fd7fd62ffc3fcdfe39422f2159acdcd3e1
4
+ data.tar.gz: 23a4d69326377dc1e68d3e1ff09d17a3adbc0e922bee7be6289acec2c4d790e4
5
5
  SHA512:
6
- metadata.gz: 3c52d9e9d70525d25e5c3cc9ee627a41e2de7946b53829525506716cb502076aa42fa2c6fa253edbee990799fe8bf6b1ae089325f6aeb8015f3a3f5b14eff5eb
7
- data.tar.gz: 41cfeb646bd77b2f0a53ccac2c5f94cbc1ca02261adc169ad21b3a96a7edc2cdcdcd75f4f0ef1e0e5ae387f8f4c3bd7c67382258515bd4612911bb5c15f85260
6
+ metadata.gz: 98e7ececc69633a18c3e4f1b946f586959177223317a050edf8e1e8a916727f18f01e6cfb1103ff31a65c890708e6c85c41d42478636c9a4924efa99817b4a98
7
+ data.tar.gz: 9674932b834c16f8176340bfa826ebac4d06e6aade8c561c484f1031877f6803ef732210b43ed0613972fe44aeb98707a429a1f5a87388909c1a0694cdfe9f98
@@ -37,6 +37,7 @@ module Scimitar
37
37
  pagination_info = scim_pagination_info(query.count())
38
38
 
39
39
  page_of_results = query
40
+ .order(id: :asc)
40
41
  .offset(pagination_info.offset)
41
42
  .limit(pagination_info.limit)
42
43
  .to_a()
@@ -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
@@ -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.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 = '2022-11-04'
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
- 'name.givenName' => { column: :first_name },
96
- 'name.familyName' => { column: :last_name },
97
- 'emails' => { columns: [ :work_email_address, :home_email_address ] },
98
- 'emails.value' => { columns: [ :work_email_address, :home_email_address ] },
99
- 'emails.type' => { ignore: true } # We can't filter on that; it'll just search all e-mails
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
 
@@ -0,0 +1,5 @@
1
+ class AddTimestampsToMockUser < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_timestamps :mock_users
4
+ end
5
+ end
@@ -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: 2021_03_08_044214) do
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, 'externalId') }.to raise_error(Scimitar::FilterError)
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
- @u1 = MockUser.create(username: '1', first_name: 'Foo', last_name: 'Ark', home_email_address: 'home_1@test.com')
8
- @u2 = MockUser.create(username: '2', first_name: 'Foo', last_name: 'Bar', home_email_address: 'home_2@test.com')
9
- @u3 = MockUser.create(username: '3', first_name: 'Foo', home_email_address: 'home_3@test.com')
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 "Foo" and name.familyName pr and emails ne "home_1@TEST.COM"'
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.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: 2022-11-04 00:00:00.000000000 Z
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