scimitar 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scimitar/active_record_backed_resources_controller.rb +6 -27
  3. data/app/controllers/scimitar/application_controller.rb +9 -29
  4. data/app/models/scimitar/engine_configuration.rb +3 -7
  5. data/app/models/scimitar/error_response.rb +0 -12
  6. data/app/models/scimitar/errors.rb +1 -1
  7. data/app/models/scimitar/lists/query_parser.rb +4 -14
  8. data/app/models/scimitar/resources/base.rb +1 -1
  9. data/app/models/scimitar/resources/mixin.rb +2 -78
  10. data/app/models/scimitar/schema/address.rb +0 -1
  11. data/app/models/scimitar/schema/attribute.rb +1 -1
  12. data/app/models/scimitar/schema/base.rb +3 -1
  13. data/app/models/scimitar/schema/vdtp.rb +1 -1
  14. data/config/initializers/scimitar.rb +70 -86
  15. data/lib/scimitar/version.rb +2 -2
  16. data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
  17. data/spec/apps/dummy/app/models/mock_group.rb +1 -1
  18. data/spec/apps/dummy/app/models/mock_user.rb +7 -10
  19. data/spec/apps/dummy/config/application.rb +1 -0
  20. data/spec/apps/dummy/config/environments/test.rb +28 -5
  21. data/spec/apps/dummy/config/initializers/scimitar.rb +10 -8
  22. data/spec/apps/dummy/config/routes.rb +0 -4
  23. data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +2 -2
  24. data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
  25. data/spec/apps/dummy/db/schema.rb +4 -8
  26. data/spec/controllers/scimitar/application_controller_spec.rb +1 -70
  27. data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
  28. data/spec/models/scimitar/lists/query_parser_spec.rb +9 -9
  29. data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
  30. data/spec/models/scimitar/resources/mixin_spec.rb +40 -675
  31. data/spec/models/scimitar/resources/user_spec.rb +4 -4
  32. data/spec/models/scimitar/schema/attribute_spec.rb +3 -0
  33. data/spec/models/scimitar/schema/base_spec.rb +1 -1
  34. data/spec/models/scimitar/schema/user_spec.rb +0 -10
  35. data/spec/requests/active_record_backed_resources_controller_spec.rb +40 -309
  36. data/spec/requests/application_controller_spec.rb +3 -7
  37. metadata +7 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd0d129e52cd7cbe3fe52fec4c4033cd45f4d2071da5d495863b1f3f78685fd5
4
- data.tar.gz: 5531cdfc4786043513f9539c2fce43bfdebbec26a6e9964d93b13c6ea00710b0
3
+ metadata.gz: 95a2166cc921a400959f9d8d4398f6bf8ecb772f8d7a0a0a73950892e85d808a
4
+ data.tar.gz: cdf5aab3812f10f69c96304e738a150f4208850267527b66d36eeb99548d7b1f
5
5
  SHA512:
6
- metadata.gz: d1914b8fe68cdc6077369f22a03f7e688790f5b239738e18508e0aeaa68055ee1e197ebc4fe8b512903d07b926de64d64817b26c6ef9b9ace2594abc85f01e62
7
- data.tar.gz: de0d305d512d646f43e581b5116c2f316eaa2b9ddb0426f1b12522a668e2a7c811a5e9d6aee82e82fadb534b5e1a5cacca303701a7f7d1791de188d73b55740c
6
+ metadata.gz: f0925517599b107e44fd93db9be142aebe608892c2c5069c50d22b353c51238290710474b062a002fdb010be3d783c4dea3b314f72f47b4aca3c2385a8fc1377
7
+ data.tar.gz: eef6eebfc64bb2d4adabfca110f26e3a6c9e227f47387da6fb384925899ddf0ae260cf68176f24040a6bb356cf34f6576c920bd44264d4a1fee415aeadc237e6
@@ -21,8 +21,6 @@ module Scimitar
21
21
 
22
22
  rescue_from ActiveRecord::RecordNotFound, with: :handle_resource_not_found # See Scimitar::ApplicationController
23
23
 
24
- before_action :obtain_id_column_name_from_attribute_map
25
-
26
24
  # GET (list)
27
25
  #
28
26
  def index
@@ -39,13 +37,12 @@ module Scimitar
39
37
  pagination_info = scim_pagination_info(query.count())
40
38
 
41
39
  page_of_results = query
42
- .order(@id_column => :asc)
43
40
  .offset(pagination_info.offset)
44
41
  .limit(pagination_info.limit)
45
42
  .to_a()
46
43
 
47
44
  super(pagination_info, page_of_results) do | record |
48
- record_to_scim(record)
45
+ record.to_scim(location: url_for(action: :show, id: record.id))
49
46
  end
50
47
  end
51
48
 
@@ -54,7 +51,7 @@ module Scimitar
54
51
  def show
55
52
  super do |record_id|
56
53
  record = self.find_record(record_id)
57
- record_to_scim(record)
54
+ record.to_scim(location: url_for(action: :show, id: record_id))
58
55
  end
59
56
  end
60
57
 
@@ -66,7 +63,7 @@ module Scimitar
66
63
  record = self.storage_class().new
67
64
  record.from_scim!(scim_hash: scim_resource.as_json())
68
65
  self.save!(record)
69
- record_to_scim(record)
66
+ record.to_scim(location: url_for(action: :show, id: record.id))
70
67
  end
71
68
  end
72
69
  end
@@ -79,7 +76,7 @@ module Scimitar
79
76
  record = self.find_record(record_id)
80
77
  record.from_scim!(scim_hash: scim_resource.as_json())
81
78
  self.save!(record)
82
- record_to_scim(record)
79
+ record.to_scim(location: url_for(action: :show, id: record.id))
83
80
  end
84
81
  end
85
82
  end
@@ -92,7 +89,7 @@ module Scimitar
92
89
  record = self.find_record(record_id)
93
90
  record.from_scim_patch!(patch_hash: patch_hash)
94
91
  self.save!(record)
95
- record_to_scim(record)
92
+ record.to_scim(location: url_for(action: :show, id: record.id))
96
93
  end
97
94
  end
98
95
  end
@@ -140,14 +137,7 @@ module Scimitar
140
137
  # +record_id+:: Record ID (SCIM schema 'id' value - "our" ID).
141
138
  #
142
139
  def find_record(record_id)
143
- self.storage_scope().find_by!(@id_column => record_id)
144
- end
145
-
146
- # DRY up controller actions - pass a record; returns the SCIM
147
- # representation, with a "show" location specified via #url_for.
148
- #
149
- def record_to_scim(record)
150
- record.to_scim(location: url_for(action: :show, id: record.send(@id_column)))
140
+ self.storage_scope().find(record_id)
151
141
  end
152
142
 
153
143
  # Save a record, dealing with validation exceptions by raising SCIM
@@ -186,16 +176,5 @@ module Scimitar
186
176
  end
187
177
  end
188
178
 
189
- # Called via +before_action+ - stores in @id_column the name of whatever
190
- # model column is used to store the record ID, via
191
- # Scimitar::Resources::Mixin::scim_attributes_map.
192
- #
193
- # Default is <tt>:id</tt>.
194
- #
195
- def obtain_id_column_name_from_attribute_map
196
- attrs = storage_class().scim_attributes_map() || {}
197
- @id_column = attrs[:id] || :id
198
- end
199
-
200
179
  end
201
180
  end
@@ -25,12 +25,10 @@ module Scimitar
25
25
  #
26
26
  # ...to "globally" invoke this handler if you wish.
27
27
  #
28
+ # +_exception+:: Exception instance (currently unused).
28
29
  #
29
- # +exception+:: Exception instance, used for a configured error reporter
30
- # via #handle_scim_error (if present).
31
- #
32
- def handle_resource_not_found(exception)
33
- handle_scim_error(NotFoundError.new(params[:id]), exception)
30
+ def handle_resource_not_found(_exception)
31
+ handle_scim_error(NotFoundError.new(params[:id]))
34
32
  end
35
33
 
36
34
  # This base controller uses:
@@ -40,22 +38,9 @@ module Scimitar
40
38
  # ...to "globally" invoke this handler for all Scimitar errors (including
41
39
  # subclasses).
42
40
  #
43
- # Mandatory parameters are:
44
- #
45
41
  # +error_response+:: Scimitar::ErrorResponse (or subclass) instance.
46
42
  #
47
- # Optional parameters are:
48
- #
49
- # *exception+:: If a Ruby exception was the reason this method is being
50
- # called, pass it here. Any configured exception reporting
51
- # mechanism will be invokved with the given parameter.
52
- # Otherwise, the +error_response+ value is reported.
53
- #
54
- def handle_scim_error(error_response, exception = error_response)
55
- unless Scimitar.engine_configuration.exception_reporter.nil?
56
- Scimitar.engine_configuration.exception_reporter.call(exception)
57
- end
58
-
43
+ def handle_scim_error(error_response)
59
44
  render json: error_response, status: error_response.status
60
45
  end
61
46
 
@@ -70,7 +55,7 @@ module Scimitar
70
55
  # +exception+:: Exception instance.
71
56
  #
72
57
  def handle_bad_json_error(exception)
73
- handle_scim_error(ErrorResponse.new(status: 400, detail: "Invalid JSON - #{exception.message}"), exception)
58
+ handle_scim_error(ErrorResponse.new(status: 400, detail: "Invalid JSON - #{exception.message}"))
74
59
  end
75
60
 
76
61
  # This base controller uses:
@@ -83,7 +68,7 @@ module Scimitar
83
68
  #
84
69
  def handle_unexpected_error(exception)
85
70
  Rails.logger.error("#{exception.message}\n#{exception.backtrace}")
86
- handle_scim_error(ErrorResponse.new(status: 500, detail: exception.message), exception)
71
+ handle_scim_error(ErrorResponse.new(status: 500, detail: exception.message))
87
72
  end
88
73
 
89
74
  # =========================================================================
@@ -97,17 +82,12 @@ module Scimitar
97
82
  # request and subclass processing.
98
83
  #
99
84
  def require_scim
100
- scim_mime_type = Mime::Type.lookup_by_extension(:scim).to_s
101
-
102
- if request.content_type.nil?
103
- request.format = :scim
104
- request.headers['CONTENT_TYPE'] = scim_mime_type
105
- elsif request.content_type&.downcase == scim_mime_type
85
+ if request.content_type&.downcase == Mime::Type.lookup_by_extension(:scim).to_s
106
86
  request.format = :scim
107
87
  elsif request.format == :scim
108
- request.headers['CONTENT_TYPE'] = scim_mime_type
88
+ request.headers['CONTENT_TYPE'] = Mime::Type.lookup_by_extension(:scim).to_s
109
89
  else
110
- handle_scim_error(ErrorResponse.new(status: 406, detail: "Only #{scim_mime_type} type is accepted."))
90
+ handle_scim_error(ErrorResponse.new(status: 406, detail: "Only #{Mime::Type.lookup_by_extension(:scim)} type is accepted."))
111
91
  end
112
92
  end
113
93
 
@@ -9,17 +9,13 @@ module Scimitar
9
9
 
10
10
  attr_accessor :basic_authenticator,
11
11
  :token_authenticator,
12
- :application_controller_mixin,
13
- :exception_reporter,
14
- :optional_value_fields_required
12
+ :application_controller_mixin
15
13
 
16
14
  def initialize(attributes = {})
17
15
 
18
- # Set defaults that may be overridden by the initializer.
16
+ # No defaults yet - reserved for future use.
19
17
  #
20
- defaults = {
21
- optional_value_fields_required: true
22
- }
18
+ defaults = {}
23
19
 
24
20
  super(defaults.merge(attributes))
25
21
  end
@@ -16,17 +16,5 @@ module Scimitar
16
16
  data['scimType'] = scimType if scimType
17
17
  data
18
18
  end
19
-
20
- # Originally Scimitar used attribute "detail" for exception text; it was
21
- # only for JSON responses at the time, but in hindsight was a bad choice.
22
- # It should have been "message" given inheritance from StandardError, which
23
- # then works properly with e.g. error reporting services.
24
- #
25
- # The "detail" attribute is still present, for backwards compatibility with
26
- # any client code that might be using this class.
27
- #
28
- def message
29
- self.detail
30
- end
31
19
  end
32
20
  end
@@ -1,6 +1,6 @@
1
1
  module Scimitar
2
2
  module Errors
3
- def add_errors_from_hash(errors_hash, prefix: nil)
3
+ def add_errors_from_hash(errors_hash:, prefix: nil)
4
4
  errors_hash.each_pair do |key, value|
5
5
  new_key = prefix.nil? ? key : "#{prefix}.#{key}".to_sym
6
6
  if value.is_a?(Array)
@@ -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.with_indifferent_case_insensitive_access()
81
+ @attribute_map = attribute_map
82
82
  end
83
83
 
84
84
  # Parse SCIM filter query into RPN stack
@@ -605,16 +605,6 @@ 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
-
618
608
  column_names.each.with_index do | column_name, index |
619
609
  arel_column = arel_table[column_name]
620
610
  arel_operation = case scim_operator
@@ -643,7 +633,7 @@ module Scimitar
643
633
  when 'pr'
644
634
  arel_table.grouping(arel_column.not_eq_all(['', nil]))
645
635
  else
646
- raise Scimitar::FilterError.new("Unsupported operator: '#{scim_operator}'")
636
+ raise Scimitar::FilterError
647
637
  end
648
638
 
649
639
  if index == 0
@@ -666,10 +656,10 @@ module Scimitar
666
656
  # +scim_attribute+:: SCIM attribute from a filter string.
667
657
  #
668
658
  def activerecord_columns(scim_attribute)
669
- raise Scimitar::FilterError.new("No scim_attribute provided") if scim_attribute.blank?
659
+ raise Scimitar::FilterError if scim_attribute.blank?
670
660
 
671
661
  mapped_attribute = self.attribute_map()[scim_attribute]
672
- raise Scimitar::FilterError.new("Unable to find domain attribute from SCIM attribute: '#{scim_attribute}'") if mapped_attribute.blank?
662
+ raise Scimitar::FilterError if mapped_attribute.blank?
673
663
 
674
664
  if mapped_attribute[:ignore]
675
665
  return []
@@ -138,7 +138,7 @@ module Scimitar
138
138
  end
139
139
 
140
140
  def as_json(options = {})
141
- self.meta = Meta.new unless self.meta && self.meta.is_a?(Meta)
141
+ self.meta = Meta.new unless self.meta
142
142
  meta.resourceType = self.class.resource_type_id
143
143
  original_hash = super(options).except('errors')
144
144
  original_hash.merge!('schemas' => self.class.schemas.map(&:id))
@@ -901,86 +901,10 @@ module Scimitar
901
901
  else
902
902
  altering_hash[path_component] = value
903
903
  end
904
-
905
904
  when 'replace'
906
- if path_component == 'root'
907
- altering_hash[path_component].merge!(value)
908
- else
909
- altering_hash[path_component] = value
910
- end
911
-
912
- # The array check handles payloads seen from e.g. Microsoft for
913
- # remove-user-from-group, where contrary to examples in the RFC
914
- # which would imply "payload removes all users", there is the
915
- # clear intent to remove just one.
916
- #
917
- # https://www.rfc-editor.org/rfc/rfc7644#section-3.5.2.2
918
- # https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
919
- #
920
- # Since remove-all in the face of remove-one is destructive, we
921
- # do a special check here to see if there's an array value for
922
- # the array path that the payload yielded. If so, we can match
923
- # each value against array items and remove just those items.
924
- #
925
- # There is an additional special case to handle a bad example
926
- # from Salesforce:
927
- #
928
- # https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
929
- #
905
+ altering_hash[path_component] = value
930
906
  when 'remove'
931
- if altering_hash[path_component].is_a?(Array) && value.present?
932
-
933
- # Handle bad Salesforce example. That might be simply a
934
- # documentation error, but just in case...
935
- #
936
- value = value.values.first if (
937
- path_component&.downcase == 'members' &&
938
- value.is_a?(Hash) &&
939
- value.keys.size == 1 &&
940
- value.keys.first&.downcase == 'members'
941
- )
942
-
943
- # The Microsoft example provides an array of values, but we
944
- # may as well cope with a value specified 'flat'. Promote
945
- # such a thing to an Array to simplify the following code.
946
- #
947
- value = [value] unless value.is_a?(Array)
948
-
949
- # For each value item, delete matching array entries. The
950
- # concept of "matching" is:
951
- #
952
- # * For simple non-Hash values (if possible) just delete on
953
- # an exact match
954
- #
955
- # * For Hash-based values, only delete if all 'patch' keys
956
- # are present in the resource and all values thus match.
957
- #
958
- # Special case to ignore '$ref' from the Microsoft payload.
959
- #
960
- # Note coercion to strings to account for SCIM vs the usual
961
- # tricky case of underlying implementations with (say)
962
- # integer primary keys, which all end up as strings anyway.
963
- #
964
- value.each do | value_item |
965
- altering_hash[path_component].delete_if do | item |
966
- if item.is_a?(Hash) && value_item.is_a?(Hash)
967
- matched_all = true
968
- value_item.each do | value_key, value_value |
969
- next if value_key == '$ref'
970
- if ! item.key?(value_key) || item[value_key]&.to_s != value_value&.to_s
971
- matched_all = false
972
- end
973
- end
974
- matched_all
975
- else
976
- item&.to_s == value_item&.to_s
977
- end
978
- end
979
- end
980
- else
981
- altering_hash.delete(path_component)
982
- end
983
-
907
+ altering_hash.delete(path_component)
984
908
  end
985
909
  end
986
910
  end
@@ -10,7 +10,6 @@ module Scimitar
10
10
  def self.scim_attributes
11
11
  @scim_attributes ||= [
12
12
  Attribute.new(name: 'type', type: 'string'),
13
- Attribute.new(name: 'primary', type: 'boolean'),
14
13
  Attribute.new(name: 'formatted', type: 'string'),
15
14
  Attribute.new(name: 'streetAddress', type: 'string'),
16
15
  Attribute.new(name: 'locality', type: 'string'),
@@ -88,7 +88,7 @@ module Scimitar
88
88
  end
89
89
  value.class.schema.valid?(value)
90
90
  return true if value.errors.empty?
91
- add_errors_from_hash(value.errors.to_hash, prefix: self.name)
91
+ add_errors_from_hash(errors_hash: value.errors.to_hash, prefix: self.name)
92
92
  false
93
93
  end
94
94
 
@@ -26,7 +26,9 @@ module Scimitar
26
26
  #
27
27
  def self.valid?(resource)
28
28
  cloned_scim_attributes.each do |scim_attribute|
29
- resource.add_errors_from_hash(scim_attribute.errors.to_hash) unless scim_attribute.valid?(resource.send(scim_attribute.name))
29
+ unless scim_attribute.valid?(resource.send(scim_attribute.name))
30
+ resource.add_errors_from_hash(errors_hash: scim_attribute.errors.to_hash)
31
+ end
30
32
  end
31
33
  end
32
34
 
@@ -7,7 +7,7 @@ module Scimitar
7
7
  class Vdtp < Base
8
8
  def self.scim_attributes
9
9
  @scim_attributes ||= [
10
- Attribute.new(name: 'value', type: 'string', required: Scimitar.engine_configuration.optional_value_fields_required),
10
+ Attribute.new(name: 'value', type: 'string', required: true),
11
11
  Attribute.new(name: 'display', type: 'string', mutability: 'readOnly'),
12
12
  Attribute.new(name: 'type', type: 'string'),
13
13
  Attribute.new(name: 'primary', type: 'boolean'),
@@ -2,101 +2,85 @@
2
2
  #
3
3
  # For supporting information and rationale, please see README.md.
4
4
 
5
- # =============================================================================
6
- # SERVICE PROVIDER CONFIGURATION
7
- # =============================================================================
8
- #
9
- # This is a Ruby abstraction over a SCIM entity that declares the capabilities
10
- # supported by a particular implementation.
11
- #
12
- # Typically this is used to declare parts of the standard unsupported, if you
13
- # don't need them and don't want to provide subclass support.
14
- #
15
- Scimitar.service_provider_configuration = Scimitar::ServiceProviderConfiguration.new({
5
+ Rails.application.config.to_prepare do # (required for >= Rails 7 / Zeitwerk)
16
6
 
17
- # See https://tools.ietf.org/html/rfc7643#section-8.5 for properties.
7
+ # ===========================================================================
8
+ # SERVICE PROVIDER CONFIGURATION
9
+ # ===========================================================================
18
10
  #
19
- # See Gem source file 'app/models/scimitar/service_provider_configuration.rb'
20
- # for defaults. Define Hash keys here that override defaults; e.g. to declare
21
- # that filters are not supported so that calling clients shouldn't use them:
11
+ # This is a Ruby abstraction over a SCIM entity that declares the
12
+ # capabilities supported by a particular implementation.
22
13
  #
23
- # filter: Scimitar::Supported.unsupported
14
+ # Typically this is used to declare parts of the standard unsupported, if you
15
+ # don't need them and don't want to provide subclass support.
16
+ #
17
+ Scimitar.service_provider_configuration = Scimitar::ServiceProviderConfiguration.new({
24
18
 
25
- })
19
+ # See https://tools.ietf.org/html/rfc7643#section-8.5 for properties.
20
+ #
21
+ # See Gem file 'app/models/scimitar/service_provider_configuration.rb'
22
+ # for defaults. Define Hash keys here that override defaults; e.g. to
23
+ # declare that filters are not supported so that calling clients shouldn't
24
+ # use them:
25
+ #
26
+ # filter: Scimitar::Supported.unsupported
26
27
 
27
- # =============================================================================
28
- # ENGINE CONFIGURATION
29
- # =============================================================================
30
- #
31
- # This is where you provide callbacks for things like authorisation or mixins
32
- # that get included into all Scimitar-derived controllers (for things like
33
- # before-actions that apply to all Scimitar controller-based routes).
34
- #
35
- Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
28
+ })
36
29
 
37
- # If you have filters you want to run for any Scimitar action/route, you can
38
- # define them here. For example, you might use a before-action to set up some
39
- # multi-tenancy related state, or skip Rails CSRF token verification/
40
- #
41
- # For example:
42
- #
43
- # application_controller_mixin: Module.new do
44
- # def self.included(base)
45
- # base.class_eval do
30
+ # ===========================================================================
31
+ # ENGINE CONFIGURATION
32
+ # ===========================================================================
46
33
  #
47
- # # Anything here is written just as you'd write it at the top of
48
- # # one of your controller classes, but it gets included in all
49
- # # Scimitar classes too.
34
+ # This is where you provide callbacks for things like authorisation or mixins
35
+ # that get included into all Scimitar-derived controllers (for things like
36
+ # before-actions that apply to all Scimitar controller-based routes).
50
37
  #
51
- # skip_before_action :verify_authenticity_token
52
- # prepend_before_action :setup_some_kind_of_multi_tenancy_data
53
- # end
54
- # end
55
- # end, # ...other configuration entries might follow...
38
+ Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
56
39
 
57
- # If you want to support username/password authentication:
58
- #
59
- # basic_authenticator: Proc.new do | username, password |
60
- # # Check username/password and return 'true' if valid, else 'false'.
61
- # end, # ...other configuration entries might follow...
62
- #
63
- # The 'username' and 'password' parameters come from Rails:
64
- #
65
- # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
66
- # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html#method-i-authenticate_with_http_basic
40
+ # If you have filters you want to run for any Scimitar action/route, you
41
+ # can define them here. For example, you might use a before-action to set
42
+ # up some multi-tenancy related state, or skip Rails CSRF token
43
+ # verification. For example:
44
+ #
45
+ # application_controller_mixin: Module.new do
46
+ # def self.included(base)
47
+ # base.class_eval do
48
+ #
49
+ # # Anything here is written just as you'd write it at the top of
50
+ # # one of your controller classes, but it gets included in all
51
+ # # Scimitar classes too.
52
+ #
53
+ # skip_before_action :verify_authenticity_token
54
+ # prepend_before_action :setup_some_kind_of_multi_tenancy_data
55
+ # end
56
+ # end
57
+ # end, # ...other configuration entries might follow...
67
58
 
68
- # If you want to support HTTP bearer token (OAuth-style) authentication:
69
- #
70
- # token_authenticator: Proc.new do | token, options |
71
- # # Check token and return 'true' if valid, else 'false'.
72
- # end, # ...other configuration entries might follow...
73
- #
74
- # The 'token' and 'options' parameters come from Rails:
75
- #
76
- # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
77
- # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html#method-i-authenticate_with_http_token
78
- #
79
- # Note that both basic and token authentication can be declared, with the
80
- # parameters in the inbound HTTP request determining which is invoked.
59
+ # If you want to support username/password authentication:
60
+ #
61
+ # basic_authenticator: Proc.new do | username, password |
62
+ # # Check username/password and return 'true' if valid, else 'false'.
63
+ # end, # ...other configuration entries might follow...
64
+ #
65
+ # The 'username' and 'password' parameters come from Rails:
66
+ #
67
+ # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
68
+ # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html#method-i-authenticate_with_http_basic
81
69
 
82
- # Scimitar rescues certain error cases and exceptions, in order to return a
83
- # JSON response to the API caller. If you want exceptions to also be
84
- # reported to a third party system such as sentry.io or raygun.com, you can
85
- # configure a Proc to do so. It is passed a Ruby exception subclass object.
86
- # For example, a minimal sentry.io reporter might do this:
87
- #
88
- # exception_reporter: Proc.new do | exception |
89
- # Sentry.capture_exception(exception)
90
- # end
91
- #
92
- # You will still need to configure your reporting system according to its
93
- # documentation (e.g. via a Rails "config/initializers/<foo>.rb" file).
70
+ # If you want to support HTTP bearer token (OAuth-style) authentication:
71
+ #
72
+ # token_authenticator: Proc.new do | token, options |
73
+ # # Check token and return 'true' if valid, else 'false'.
74
+ # end, # ...other configuration entries might follow...
75
+ #
76
+ # The 'token' and 'options' parameters come from Rails:
77
+ #
78
+ # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
79
+ # https://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html#method-i-authenticate_with_http_token
80
+ #
81
+ # Note that both basic and token authentication can be declared, with the
82
+ # parameters in the inbound HTTP request determining which is invoked.
94
83
 
95
- # Scimilar treats "VDTP" (Value, Display, Type, Primary) attribute values,
96
- # used for e.g. e-mail addresses or phone numbers, as required by default.
97
- # If you encounter a service which calls these with e.g. "null" value data,
98
- # you can configure all values to be optional. You'll need to deal with
99
- # whatever that means for you receiving system in your model code.
100
- #
101
- # optional_value_fields_required: false
102
- })
84
+ })
85
+
86
+ end
@@ -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.5.0'
6
+ VERSION = '2.0.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 = '2023-01-27'
11
+ DATE = '2022-03-04'
12
12
 
13
13
  end
@@ -1,4 +1,4 @@
1
- class MockGroupsController < Scimitar::ActiveRecordBackedResourcesController
1
+ class MockUsersController < Scimitar::ActiveRecordBackedResourcesController
2
2
 
3
3
  protected
4
4
 
@@ -58,7 +58,7 @@ class MockGroup < ActiveRecord::Base
58
58
 
59
59
  case type.downcase
60
60
  when 'user'
61
- MockUser.find_by_primary_key(id)
61
+ MockUser.find_by_id(id)
62
62
  when 'group'
63
63
  MockGroup.find_by_id(id)
64
64
  else