scimitar 1.3.1 → 1.3.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: 9faabfad9cae931ab19f765393d9f307fa5d44773f943d2286fbd92302c2e9e1
4
- data.tar.gz: 2bc23d4e3b123103efd0fa87375547dcdf9e3684ea272a1e4941c43e7845937b
3
+ metadata.gz: 382f2feb979c655de91c1d30bf1fa8bb5347059abe376839758a9b34992f8616
4
+ data.tar.gz: d1d8f8c32a92f4b879699a995b4e1746b7b778d782ab3101695e59891a107606
5
5
  SHA512:
6
- metadata.gz: bb74810f72d7b806b7e6aef1a02d363be1135dbf190e2ae0e88a727f94ec9b90e643a13883cd64951d4879fe542fb5936621ec96c44d0f192050f9f6453b58ef
7
- data.tar.gz: b8ea496f490696379236a971070f6e04188fbfcff27f0dd484e18c01416193c625173c72618e123cbc39b1521ef4e6137553396d981db6366861f98f172cee2c
6
+ metadata.gz: 87373dddf17fe6791e7464c228e688338267bf1a230cd2ab1d69372185ea3adcf165b969872e0e05556ba28b1e9e1581ddaac5639f89235bd7f19da081ff3e7f
7
+ data.tar.gz: ae79056e07500c1b195807a9a3f12755895f47a4383c7451208a2956b79ec02e600a8c915fa8a600cccce559c16b5c62f73e081ced2e09e8bee5da63910a2a1e
@@ -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 = '1.3.1'
6
+ VERSION = '1.3.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-10'
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[6.1]
2
+ def change
3
+ add_timestamps :mock_users
4
+ end
5
+ end
@@ -10,7 +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
13
+ ActiveRecord::Schema.define(version: 2023_01_09_012729) do
14
14
 
15
15
  # These are extensions that must be enabled in order to support this database
16
16
  enable_extension "plpgsql"
@@ -37,6 +37,8 @@ ActiveRecord::Schema.define(version: 2021_03_08_044214) do
37
37
  t.text "work_email_address"
38
38
  t.text "home_email_address"
39
39
  t.text "work_phone_number"
40
+ t.datetime "created_at", precision: 6, null: false
41
+ t.datetime "updated_at", precision: 6, null: false
40
42
  end
41
43
 
42
44
  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: 1.3.1
4
+ version: 1.3.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-10 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
@@ -307,4 +308,5 @@ test_files:
307
308
  - spec/apps/dummy/db/schema.rb
308
309
  - spec/apps/dummy/db/migrate/20210308020313_create_mock_groups.rb
309
310
  - spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb
311
+ - spec/apps/dummy/db/migrate/20230109012729_add_timestamps_to_mock_user.rb
310
312
  - spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb