scimitar 2.9.0 → 2.10.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '083949bb1e8b8d0afb8e62a87245a0f05189b05669e49eb8b5e3f8fa3af277e6'
4
- data.tar.gz: 46a3f0af432f0980280ed8cc8f5c0309bc36f30c15673f9da650f8225f0f406d
3
+ metadata.gz: f2e3306d8e05674efa4a53f63e833304623187a3191ecd6ef5685ac03a3ae8a7
4
+ data.tar.gz: 346c86fe3728208d6e4afb6a2d684a2b46de6326549d1b5d3b1e96622f220dd4
5
5
  SHA512:
6
- metadata.gz: 6d10c2377f023f1b3201148bd57813296b1746d64e738838410045a128a10c980ac675c3a7474b56848d2cfe97ab2421d07bfa1ada5512890bfa08bfa2556f82
7
- data.tar.gz: 5ff25a1f64a5bccf0ee2289223d31f8bc6b8636586bf09f1903e0b5824aed483d0dba60d9f7736bdc20c5c71ef6858ab38529eee6ff2e00aae20d0b18cb5d647
6
+ metadata.gz: 723b88d08085f32e36caca03eceeee22c6653fb9b8fcbe94aa7c35aa6ae37f1de59fef29201ea42a00b4ec01540c3d77375c5d55ea07be4cee1447cdb3cc5e9f
7
+ data.tar.gz: 00e7ced581373571d0f086a0df9f18334b7b73ae6078ecd095edbfd2b5d7f5c6181515074bbbd49be3c8819531dbad9affa782a7f5087dec7d51a371c79646ea
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 RIPA Global
3
+ Copyright (c) 2024 RIPA Global
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -321,7 +321,7 @@ end
321
321
 
322
322
  #### Other source types
323
323
 
324
- If you do _not_ use ActiveRecord to store data, or if you have very esoteric read-write requirements, you can subclass [`Scimigar::ResourcesController`](https://www.rubydoc.info/gems/scimitar/Scimitar/ResourcesController) in a manner similar to this:
324
+ If you do _not_ use ActiveRecord to store data, or if you have very esoteric read-write requirements, you can subclass [`Scimitar::ResourcesController`](https://www.rubydoc.info/gems/scimitar/Scimitar/ResourcesController) in a manner similar to this:
325
325
 
326
326
  ```ruby
327
327
  class UsersController < Scimitar::ResourcesController
@@ -594,7 +594,7 @@ By default, Scimitar advertises (via things like [the `/Schemas` endpoint](https
594
594
 
595
595
  ```ruby
596
596
  Rails.application.config.to_prepare do
597
- Scimitar::Engine::set_default_resources([Scimitar::Resources::User])
597
+ Scimitar::Engine.set_default_resources([Scimitar::Resources::User])
598
598
  # ...other Scimitar configuration / initialisation code...
599
599
  end
600
600
  ```
@@ -9,10 +9,6 @@ module Scimitar
9
9
  before_action :add_mandatory_response_headers
10
10
  before_action :authenticate
11
11
 
12
- if Scimitar.engine_configuration.application_controller_mixin
13
- include Scimitar.engine_configuration.application_controller_mixin
14
- end
15
-
16
12
  # =========================================================================
17
13
  # PROTECTED INSTANCE METHODS
18
14
  # =========================================================================
@@ -47,7 +43,7 @@ module Scimitar
47
43
  #
48
44
  # *exception+:: If a Ruby exception was the reason this method is being
49
45
  # called, pass it here. Any configured exception reporting
50
- # mechanism will be invokved with the given parameter.
46
+ # mechanism will be invoked with the given parameter.
51
47
  # Otherwise, the +error_response+ value is reported.
52
48
  #
53
49
  def handle_scim_error(error_response, exception = error_response)
@@ -153,5 +149,8 @@ module Scimitar
153
149
  return result
154
150
  end
155
151
 
152
+ if Scimitar.engine_configuration.application_controller_mixin
153
+ include Scimitar.engine_configuration.application_controller_mixin
154
+ end
156
155
  end
157
156
  end
@@ -5,7 +5,13 @@ module Scimitar
5
5
  resource.resource_type(scim_resource_type_url(name: resource.resource_type_id))
6
6
  end
7
7
 
8
- render json: resource_types
8
+ render json: {
9
+ schemas: [
10
+ 'urn:ietf:params:scim:api:messages:2.0:ListResponse'
11
+ ],
12
+ totalResults: resource_types.size,
13
+ Resources: resource_types
14
+ }
9
15
  end
10
16
 
11
17
  def show
@@ -201,7 +201,7 @@ module Scimitar
201
201
  if mapped_multivalue_attribute.is_a?(Array)
202
202
 
203
203
  # A single-entry array with "list using" semantics, for a
204
- # collection of an artbirary number of same-class items - e.g.
204
+ # collection of an arbitrary number of same-class items - e.g.
205
205
  # Groups to which a User belongs.
206
206
  #
207
207
  # If this is an up-to-date mapping, there's a "class" entry that
@@ -342,14 +342,14 @@ module Scimitar
342
342
  skip_next_component = false
343
343
 
344
344
  components.each.with_index do | component, index |
345
- if skip_next_component == true
345
+ if skip_next_component
346
346
  skip_next_component = false
347
347
  next
348
348
  end
349
349
 
350
350
  downcased = component.downcase.strip
351
351
 
352
- if (expecting_attribute)
352
+ if expecting_attribute
353
353
  if downcased.match?(/[^\\]\[/) # Not backslash then literal '['
354
354
  attribute_prefix = component.match(/(.*?[^\\])\[/ )[1] # Everything before no-backslash-then-literal (unescaped) '['
355
355
  first_attribute_inside = component.match( /[^\\]\[(.*)/)[1] # Everything after no-backslash-then-literal (unescaped) '['
@@ -362,7 +362,7 @@ module Scimitar
362
362
  expecting_attribute = false
363
363
  expecting_operator = true
364
364
 
365
- elsif (expecting_operator)
365
+ elsif expecting_operator
366
366
  rewritten << component
367
367
  if BINARY_OPERATORS.include?(downcased)
368
368
  expecting_operator = false
@@ -374,7 +374,7 @@ module Scimitar
374
374
  raise 'Expected operator'
375
375
  end
376
376
 
377
- elsif (expecting_value)
377
+ elsif expecting_value
378
378
  matches = downcased.match(/([^\\])\](.*)/) # Contains no-backslash-then-literal (unescaped) ']'; also capture anything after
379
379
  unless matches.nil? # Contains no-backslash-then-literal (unescaped) ']'
380
380
  character_before_closing_bracket = matches[1]
@@ -395,7 +395,7 @@ module Scimitar
395
395
  # So - NOTE RECURSION AND EARLY EXIT POSSIBILITY HEREIN.
396
396
  #
397
397
  if (
398
- ! attribute_prefix.nil? &&
398
+ !attribute_prefix.nil? &&
399
399
  OPERATORS.key?(components[index + 1]&.downcase) &&
400
400
  characters_after_closing_bracket.match?(/^\.#{ATTRNAME}$/)
401
401
  )
@@ -437,7 +437,7 @@ module Scimitar
437
437
  if downcased.start_with?('"')
438
438
  expecting_closing_quote = true
439
439
  downcased = downcased[1..-1] # Strip off opening '"' to avoid false-positive on 'contains closing quote' check below
440
- elsif expecting_closing_quote == false # If not expecting a closing quote, then the component must be the entire no-spaces value
440
+ elsif !expecting_closing_quote # If not expecting a closing quote, then the component must be the entire no-spaces value
441
441
  expecting_value = false
442
442
  expecting_logic_word = true
443
443
  end
@@ -450,7 +450,7 @@ module Scimitar
450
450
  end
451
451
  end
452
452
 
453
- elsif (expecting_logic_word)
453
+ elsif expecting_logic_word
454
454
  if downcased == 'and' || downcased == 'or'
455
455
  rewritten << component
456
456
  next_downcased_component = components[index + 1].downcase.strip
@@ -586,11 +586,11 @@ module Scimitar
586
586
 
587
587
  # Recursively process an expression tree. Calls itself with nested tree
588
588
  # fragments. Each inner expression fragment calculates on the given
589
- # base scope, with aggregration at each level into a wider query using
589
+ # base scope, with aggregation at each level into a wider query using
590
590
  # AND or OR depending on the expression tree contents.
591
591
  #
592
592
  # +base_scope+:: Base scope (ActiveRecord::Relation, e.g. User.all
593
- # - neverchanges during recursion).
593
+ # - never changes during recursion).
594
594
  #
595
595
  # +expression_tree+:: Top-level expression tree or fragments inside if
596
596
  # self-calling recursively.
@@ -748,7 +748,7 @@ module Scimitar
748
748
 
749
749
  # Returns the mapped-to-your-domain column name(s) that a filter string
750
750
  # is operating upon, in an Array. If empty, the attribute is to be
751
- # ignored. Raises an exception if entirey unmapped (thus unsupported).
751
+ # ignored. Raises an exception if entirely unmapped (thus unsupported).
752
752
  #
753
753
  # Note plural - the return value is always an array any of which should
754
754
  # be used (implicit 'OR').
@@ -17,12 +17,10 @@ module Scimitar
17
17
 
18
18
  def as_json(options = {})
19
19
  without_extensions = super(except: 'schemaExtensions')
20
- if schemaExtensions.present?
21
- extensions = schemaExtensions.map{|extension| {"schema" => extension, "required" => false}}
22
- without_extensions.merge('schemaExtensions' => extensions)
23
- else
24
- without_extensions
25
- end
20
+ return without_extensions unless schemaExtensions.present? # NOTE EARLY EXIT
21
+
22
+ extensions = schemaExtensions.map{|extension| {"schema" => extension, "required" => false}}
23
+ without_extensions.merge('schemaExtensions' => extensions)
26
24
  end
27
25
 
28
26
  end
@@ -158,7 +158,7 @@ module Scimitar
158
158
  hash.with_indifferent_access.each_pair do |attr_name, attr_value|
159
159
  scim_attribute = self.class.complex_scim_attributes[attr_name].try(:first)
160
160
 
161
- if scim_attribute && scim_attribute.complexType
161
+ if scim_attribute&.complexType
162
162
  if scim_attribute.multiValued
163
163
  self.send("#{attr_name}=", attr_value&.map {|attr_for_each_item| complex_type_from_hash(scim_attribute, attr_for_each_item)})
164
164
  else
@@ -473,7 +473,7 @@ module Scimitar
473
473
  path_str = operation['path' ]
474
474
  value = operation['value']
475
475
 
476
- unless ['add', 'remove', 'replace'].include?(nature)
476
+ unless %w[add remove replace].include?(nature)
477
477
  raise Scimitar::InvalidSyntaxError.new("Unrecognised PATCH \"op\" value of \"#{nature}\"")
478
478
  end
479
479
 
@@ -613,7 +613,7 @@ module Scimitar
613
613
  built_dynamic_list = false
614
614
  mapped_array = attrs_map_or_leaf_value.map do |value|
615
615
  if ! value.is_a?(Hash)
616
- raise 'Bad attribute map: Array contains someting other than mapping Hash(es)'
616
+ raise 'Bad attribute map: Array contains something other than mapping Hash(es)'
617
617
 
618
618
  elsif value.key?(:match) # Static map
619
619
  static_hash = { value[:match] => value[:with] }
@@ -741,7 +741,7 @@ module Scimitar
741
741
  # +path+:: Array of SCIM attribute names giving a
742
742
  # path into the SCIM schema where
743
743
  # iteration has reached. Used to find the
744
- # schema attribute definiton and check
744
+ # schema attribute definition and check
745
745
  # mutability before writing.
746
746
  #
747
747
  def from_scim_backend!(
@@ -1088,7 +1088,7 @@ module Scimitar
1088
1088
  # associated collection or clearing a local model attribute
1089
1089
  # directly to "nil").
1090
1090
  #
1091
- if handled == false
1091
+ unless handled
1092
1092
  current_data_at_path[matched_index] = nil
1093
1093
  compact_after = true
1094
1094
  end
@@ -1290,7 +1290,7 @@ module Scimitar
1290
1290
  end
1291
1291
  end
1292
1292
 
1293
- if handled == false
1293
+ unless handled
1294
1294
  altering_hash[path_component] = []
1295
1295
  end
1296
1296
 
@@ -1445,7 +1445,7 @@ module Scimitar
1445
1445
  # { value: :work_email }
1446
1446
  #
1447
1447
  # If there was a SCIM entry with a type of something unrecognised,
1448
- # such as 'holday', then +nil+ would be returned since there is no
1448
+ # such as 'holiday', then +nil+ would be returned since there is no
1449
1449
  # matching attribute map entry.
1450
1450
  #
1451
1451
  # Note that the <tt>:with_attr_map</tt> array can contain dynamic
@@ -36,7 +36,7 @@ module Scimitar
36
36
  scim_attributes.map { |scim_attribute| scim_attribute.clone }
37
37
  end
38
38
 
39
- # Find a given attribute this schema, travelling down a path to any
39
+ # Find a given attribute of this schema, travelling down a path to any
40
40
  # sub-attributes within. Given that callers might be dealing with paths
41
41
  # into actual SCIM data, array indices for multi-value attributes are
42
42
  # allowed (as integers) and simply skipped - only the names are of
@@ -88,9 +88,9 @@ module Scimitar
88
88
  unrecognised_resources = resource_array - @standard_default_resources
89
89
 
90
90
  if unrecognised_resources.any?
91
- raise "Scimitar::Engine::set_default_resources: Only #{@standard_default_resources.map(&:name).join(', ')} are supported"
91
+ raise "Scimitar::Engine.set_default_resources: Only #{@standard_default_resources.map(&:name).join(', ')} are supported"
92
92
  elsif resource_array.empty?
93
- raise 'Scimitar::Engine::set_default_resources: At least one resource must be given'
93
+ raise 'Scimitar::Engine.set_default_resources: At least one resource must be given'
94
94
  end
95
95
 
96
96
  @default_resources = resource_array
@@ -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.9.0'
6
+ VERSION = '2.10.0'
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 = '2024-06-27'
11
+ DATE = '2024-10-22'
12
12
 
13
13
  end
@@ -9,11 +9,15 @@ RSpec.describe Scimitar::ResourceTypesController do
9
9
  it 'renders the resource type for user' do
10
10
  get :index, format: :scim
11
11
  response_hash = JSON.parse(response.body)
12
- expected_response = [ Scimitar::Resources::User.resource_type(scim_resource_type_url(name: 'User', test: 1)),
13
- Scimitar::Resources::Group.resource_type(scim_resource_type_url(name: 'Group', test: 1))
14
- ].to_json
12
+ expected_response = {
13
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],
14
+ totalResults: 2,
15
+ Resources: [
16
+ Scimitar::Resources::User.resource_type(scim_resource_type_url(name: 'User', test: 1)),
17
+ Scimitar::Resources::Group.resource_type(scim_resource_type_url(name: 'Group', test: 1))
18
+ ]
19
+ }.to_json
15
20
 
16
- response_hash = JSON.parse(response.body)
17
21
  expect(response_hash).to eql(JSON.parse(expected_response))
18
22
  end
19
23
 
@@ -555,7 +555,7 @@ RSpec.describe Scimitar::Resources::Mixin do
555
555
 
556
556
  expect do
557
557
  scim = instance.to_scim(location: 'https://test.com/static_map_test')
558
- end.to raise_error(RuntimeError) { |e| expect(e.message).to include('Array contains someting other than mapping Hash(es)') }
558
+ end.to raise_error(RuntimeError) { |e| expect(e.message).to include('Array contains something other than mapping Hash(es)') }
559
559
  end
560
560
 
561
561
  it 'complains about bad Hash entries in mapping Arrays' do
@@ -78,26 +78,26 @@ RSpec.describe Scimitar::Engine do
78
78
  end
79
79
 
80
80
  it 'notes changes to defaults' do
81
- Scimitar::Engine::set_default_resources([Scimitar::Resources::User])
81
+ Scimitar::Engine.set_default_resources([Scimitar::Resources::User])
82
82
  expect(Scimitar::Engine.resources()).to match_array([Scimitar::Resources::User])
83
83
  end
84
84
 
85
85
  it 'notes changes to defaults with custom resources added' do
86
- Scimitar::Engine::set_default_resources([Scimitar::Resources::User])
86
+ Scimitar::Engine.set_default_resources([Scimitar::Resources::User])
87
87
  Scimitar::Engine.add_custom_resource(@license_resource)
88
88
  expect(Scimitar::Engine.resources()).to match_array([Scimitar::Resources::User, @license_resource])
89
89
  end
90
90
 
91
91
  it 'rejects bad defaults' do
92
92
  expect {
93
- Scimitar::Engine::set_default_resources([@license_resource])
94
- }.to raise_error('Scimitar::Engine::set_default_resources: Only Scimitar::Resources::User, Scimitar::Resources::Group are supported')
93
+ Scimitar::Engine.set_default_resources([@license_resource])
94
+ }.to raise_error('Scimitar::Engine.set_default_resources: Only Scimitar::Resources::User, Scimitar::Resources::Group are supported')
95
95
  end
96
96
 
97
97
  it 'rejects empty defaults' do
98
98
  expect {
99
- Scimitar::Engine::set_default_resources([])
100
- }.to raise_error('Scimitar::Engine::set_default_resources: At least one resource must be given')
99
+ Scimitar::Engine.set_default_resources([])
100
+ }.to raise_error('Scimitar::Engine.set_default_resources: At least one resource must be given')
101
101
  end
102
102
  end # "context '::resources, :add_custom_resource, ::set_default_resources' do"
103
103
 
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.9.0
4
+ version: 2.10.0
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: 2024-06-27 00:00:00.000000000 Z
12
+ date: 2024-10-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -101,14 +101,14 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '6.1'
104
+ version: '7.0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '6.1'
111
+ version: '7.0'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: doggo
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -267,7 +267,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
267
267
  - !ruby/object:Gem::Version
268
268
  version: '0'
269
269
  requirements: []
270
- rubygems_version: 3.5.4
270
+ rubygems_version: 3.5.16
271
271
  signing_key:
272
272
  specification_version: 4
273
273
  summary: SCIM v2 for Rails