scimitar 1.8.1 → 2.0.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 +4 -4
 - data/app/controllers/scimitar/active_record_backed_resources_controller.rb +20 -94
 - data/app/controllers/scimitar/application_controller.rb +13 -41
 - data/app/controllers/scimitar/schemas_controller.rb +0 -5
 - data/app/models/scimitar/complex_types/address.rb +6 -0
 - data/app/models/scimitar/engine_configuration.rb +5 -13
 - data/app/models/scimitar/error_response.rb +0 -12
 - data/app/models/scimitar/lists/query_parser.rb +10 -25
 - data/app/models/scimitar/resource_invalid_error.rb +1 -1
 - data/app/models/scimitar/resources/base.rb +4 -14
 - data/app/models/scimitar/resources/mixin.rb +13 -140
 - data/app/models/scimitar/schema/address.rb +0 -1
 - data/app/models/scimitar/schema/attribute.rb +5 -14
 - data/app/models/scimitar/schema/base.rb +1 -1
 - data/app/models/scimitar/schema/vdtp.rb +1 -1
 - data/app/models/scimitar/service_provider_configuration.rb +3 -14
 - data/config/initializers/scimitar.rb +3 -28
 - data/lib/scimitar/version.rb +2 -2
 - data/lib/scimitar.rb +2 -7
 - data/spec/apps/dummy/app/controllers/mock_groups_controller.rb +1 -1
 - data/spec/apps/dummy/app/models/mock_group.rb +1 -1
 - data/spec/apps/dummy/app/models/mock_user.rb +8 -36
 - data/spec/apps/dummy/config/application.rb +1 -0
 - data/spec/apps/dummy/config/environments/test.rb +28 -5
 - data/spec/apps/dummy/config/initializers/scimitar.rb +10 -61
 - data/spec/apps/dummy/config/routes.rb +7 -28
 - data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -10
 - data/spec/apps/dummy/db/migrate/20210308044214_create_join_table_mock_groups_mock_users.rb +3 -8
 - data/spec/apps/dummy/db/schema.rb +4 -11
 - data/spec/controllers/scimitar/application_controller_spec.rb +3 -126
 - data/spec/controllers/scimitar/resource_types_controller_spec.rb +2 -2
 - data/spec/controllers/scimitar/schemas_controller_spec.rb +2 -10
 - data/spec/models/scimitar/complex_types/address_spec.rb +4 -3
 - data/spec/models/scimitar/complex_types/email_spec.rb +2 -0
 - data/spec/models/scimitar/lists/query_parser_spec.rb +9 -76
 - data/spec/models/scimitar/resources/base_spec.rb +70 -208
 - data/spec/models/scimitar/resources/base_validation_spec.rb +2 -27
 - data/spec/models/scimitar/resources/mixin_spec.rb +43 -790
 - data/spec/models/scimitar/schema/attribute_spec.rb +3 -22
 - data/spec/models/scimitar/schema/base_spec.rb +1 -1
 - data/spec/models/scimitar/schema/user_spec.rb +0 -10
 - data/spec/requests/active_record_backed_resources_controller_spec.rb +66 -709
 - data/spec/requests/application_controller_spec.rb +3 -16
 - data/spec/spec_helper.rb +0 -8
 - metadata +14 -25
 - data/LICENSE.txt +0 -21
 - data/README.md +0 -710
 - data/lib/scimitar/support/utilities.rb +0 -51
 - data/spec/apps/dummy/app/controllers/custom_create_mock_users_controller.rb +0 -25
 - data/spec/apps/dummy/app/controllers/custom_replace_mock_users_controller.rb +0 -25
 - data/spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb +0 -24
 - data/spec/apps/dummy/app/controllers/custom_update_mock_users_controller.rb +0 -25
 
| 
         @@ -220,8 +220,13 @@ module Scimitar 
     | 
|
| 
       220 
220 
     | 
    
         
             
                # allow for different client searching "styles", given ambiguities in RFC
         
     | 
| 
       221 
221 
     | 
    
         
             
                # 7644 filter examples).
         
     | 
| 
       222 
222 
     | 
    
         
             
                #
         
     | 
| 
       223 
     | 
    
         
            -
                # Each value is a  
     | 
| 
       224 
     | 
    
         
            -
                #  
     | 
| 
      
 223 
     | 
    
         
            +
                # Each value is a Hash with Symbol keys ':column', naming just one simple
         
     | 
| 
      
 224 
     | 
    
         
            +
                # column for a mapping; ':columns', with an Array of column names that you
         
     | 
| 
      
 225 
     | 
    
         
            +
                # want to map using 'OR' for a single search on the corresponding SCIM
         
     | 
| 
      
 226 
     | 
    
         
            +
                # attribute; or ':ignore' with value 'true', which means that a fitler on
         
     | 
| 
      
 227 
     | 
    
         
            +
                # the matching attribute is ignored rather than resulting in an "invalid
         
     | 
| 
      
 228 
     | 
    
         
            +
                # filter" exception - beware possibilities for surprised clients getting a
         
     | 
| 
      
 229 
     | 
    
         
            +
                # broader result set than expected. Example:
         
     | 
| 
       225 
230 
     | 
    
         
             
                #
         
     | 
| 
       226 
231 
     | 
    
         
             
                #     def self.scim_queryable_attributes
         
     | 
| 
       227 
232 
     | 
    
         
             
                #       return {
         
     | 
| 
         @@ -229,27 +234,10 @@ module Scimitar 
     | 
|
| 
       229 
234 
     | 
    
         
             
                #         'name.familyName' => { column: :last_name  },
         
     | 
| 
       230 
235 
     | 
    
         
             
                #         'emails'          => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
       231 
236 
     | 
    
         
             
                #         'emails.value'    => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
       232 
     | 
    
         
            -
                #         'emails.type'     => { ignore: true } 
     | 
| 
       233 
     | 
    
         
            -
                #         'groups.value'    => { column: Group.arel_table[:id] }
         
     | 
| 
      
 237 
     | 
    
         
            +
                #         'emails.type'     => { ignore: true }
         
     | 
| 
       234 
238 
     | 
    
         
             
                #       }
         
     | 
| 
       235 
239 
     | 
    
         
             
                #     end
         
     | 
| 
       236 
240 
     | 
    
         
             
                #
         
     | 
| 
       237 
     | 
    
         
            -
                # Column references can be either a Symbol representing a column within
         
     | 
| 
       238 
     | 
    
         
            -
                # the resource model table, or an <tt>Arel::Attribute</tt> instance via
         
     | 
| 
       239 
     | 
    
         
            -
                # e.g. <tt>MyModel.arel_table[:my_column]</tt>.
         
     | 
| 
       240 
     | 
    
         
            -
                #
         
     | 
| 
       241 
     | 
    
         
            -
                # === Queryable SCIM attribute options
         
     | 
| 
       242 
     | 
    
         
            -
                #
         
     | 
| 
       243 
     | 
    
         
            -
                # +:column+::  Just one simple column for a mapping.
         
     | 
| 
       244 
     | 
    
         
            -
                #
         
     | 
| 
       245 
     | 
    
         
            -
                # +:columns+:: An Array of columns that you want to map using 'OR' for a
         
     | 
| 
       246 
     | 
    
         
            -
                #              single search of the corresponding entity.
         
     | 
| 
       247 
     | 
    
         
            -
                #
         
     | 
| 
       248 
     | 
    
         
            -
                # +:ignore+::  When set to +true+, the matching attribute is ignored rather
         
     | 
| 
       249 
     | 
    
         
            -
                #              than resulting in an "invalid filter" exception. Beware
         
     | 
| 
       250 
     | 
    
         
            -
                #              possibilities for surprised clients getting a broader result
         
     | 
| 
       251 
     | 
    
         
            -
                #              set than expected, since a constraint may have been ignored.
         
     | 
| 
       252 
     | 
    
         
            -
                #
         
     | 
| 
       253 
241 
     | 
    
         
             
                # Filtering is currently limited and searching within e.g. arrays of data
         
     | 
| 
       254 
242 
     | 
    
         
             
                # is not supported; only simple top-level keys can be mapped.
         
     | 
| 
       255 
243 
     | 
    
         
             
                #
         
     | 
| 
         @@ -418,11 +406,8 @@ module Scimitar 
     | 
|
| 
       418 
406 
     | 
    
         
             
                    def from_scim_patch!(patch_hash:)
         
     | 
| 
       419 
407 
     | 
    
         
             
                      frozen_ci_patch_hash = patch_hash.with_indifferent_case_insensitive_access().freeze()
         
     | 
| 
       420 
408 
     | 
    
         
             
                      ci_scim_hash         = self.to_scim(location: '(unused)').as_json().with_indifferent_case_insensitive_access()
         
     | 
| 
       421 
     | 
    
         
            -
                      operations           = frozen_ci_patch_hash['operations']
         
     | 
| 
       422 
     | 
    
         
            -
             
     | 
| 
       423 
     | 
    
         
            -
                      raise Scimitar::InvalidSyntaxError.new("Missing PATCH \"operations\"") unless operations
         
     | 
| 
       424 
409 
     | 
    
         | 
| 
       425 
     | 
    
         
            -
                      operations.each do |operation|
         
     | 
| 
      
 410 
     | 
    
         
            +
                      frozen_ci_patch_hash['operations'].each do |operation|
         
     | 
| 
       426 
411 
     | 
    
         
             
                        nature   = operation['op'   ]&.downcase
         
     | 
| 
       427 
412 
     | 
    
         
             
                        path_str = operation['path' ]
         
     | 
| 
       428 
413 
     | 
    
         
             
                        value    = operation['value']
         
     | 
| 
         @@ -458,30 +443,9 @@ module Scimitar 
     | 
|
| 
       458 
443 
     | 
    
         
             
                          ci_scim_hash = { 'root' => ci_scim_hash }.with_indifferent_case_insensitive_access()
         
     | 
| 
       459 
444 
     | 
    
         
             
                        end
         
     | 
| 
       460 
445 
     | 
    
         | 
| 
       461 
     | 
    
         
            -
                        # Handle extension schema. Contributed by @bettysteger and
         
     | 
| 
       462 
     | 
    
         
            -
                        # @MorrisFreeman via:
         
     | 
| 
       463 
     | 
    
         
            -
                        #
         
     | 
| 
       464 
     | 
    
         
            -
                        #   https://github.com/RIPAGlobal/scimitar/issues/48
         
     | 
| 
       465 
     | 
    
         
            -
                        #   https://github.com/RIPAGlobal/scimitar/pull/49
         
     | 
| 
       466 
     | 
    
         
            -
                        #
         
     | 
| 
       467 
     | 
    
         
            -
                        # Note the ":" separating the schema ID (URN) from the attribute.
         
     | 
| 
       468 
     | 
    
         
            -
                        # The nature of JSON rendering / other payloads might lead you to
         
     | 
| 
       469 
     | 
    
         
            -
                        # expect a "." as with any complex types, but that's not the case;
         
     | 
| 
       470 
     | 
    
         
            -
                        # see https://tools.ietf.org/html/rfc7644#section-3.10, or
         
     | 
| 
       471 
     | 
    
         
            -
                        # https://tools.ietf.org/html/rfc7644#section-3.5.2 of which in
         
     | 
| 
       472 
     | 
    
         
            -
                        # particular, https://tools.ietf.org/html/rfc7644#page-35.
         
     | 
| 
       473 
     | 
    
         
            -
                        #
         
     | 
| 
       474 
     | 
    
         
            -
                        paths = []
         
     | 
| 
       475 
     | 
    
         
            -
                        self.class.scim_resource_type.extended_schemas.each do |schema|
         
     | 
| 
       476 
     | 
    
         
            -
                          path_str.downcase.split(schema.id.downcase + ':').drop(1).each do |path|
         
     | 
| 
       477 
     | 
    
         
            -
                            paths += [schema.id] + path.split('.')
         
     | 
| 
       478 
     | 
    
         
            -
                          end
         
     | 
| 
       479 
     | 
    
         
            -
                        end
         
     | 
| 
       480 
     | 
    
         
            -
                        paths = path_str.split('.') if paths.empty?
         
     | 
| 
       481 
     | 
    
         
            -
             
     | 
| 
       482 
446 
     | 
    
         
             
                        self.from_patch_backend!(
         
     | 
| 
       483 
447 
     | 
    
         
             
                          nature:        nature,
         
     | 
| 
       484 
     | 
    
         
            -
                          path:           
     | 
| 
      
 448 
     | 
    
         
            +
                          path:          (path_str || '').split('.'),
         
     | 
| 
       485 
449 
     | 
    
         
             
                          value:         value,
         
     | 
| 
       486 
450 
     | 
    
         
             
                          altering_hash: ci_scim_hash
         
     | 
| 
       487 
451 
     | 
    
         
             
                        )
         
     | 
| 
         @@ -652,19 +616,7 @@ module Scimitar 
     | 
|
| 
       652 
616 
     | 
    
         
             
                            attrs_map_or_leaf_value.each do | scim_attribute, sub_attrs_map_or_leaf_value |
         
     | 
| 
       653 
617 
     | 
    
         
             
                              next if scim_attribute&.to_s&.downcase == 'id' && path.empty?
         
     | 
| 
       654 
618 
     | 
    
         | 
| 
       655 
     | 
    
         
            -
                               
     | 
| 
       656 
     | 
    
         
            -
                              # @MorrisFreeman via:
         
     | 
| 
       657 
     | 
    
         
            -
                              #
         
     | 
| 
       658 
     | 
    
         
            -
                              #   https://github.com/RIPAGlobal/scimitar/issues/48
         
     | 
| 
       659 
     | 
    
         
            -
                              #   https://github.com/RIPAGlobal/scimitar/pull/49
         
     | 
| 
       660 
     | 
    
         
            -
                              #
         
     | 
| 
       661 
     | 
    
         
            -
                              attribute_tree = []
         
     | 
| 
       662 
     | 
    
         
            -
                              resource_class.extended_schemas.each do |schema|
         
     | 
| 
       663 
     | 
    
         
            -
                                attribute_tree << schema.id and break if schema.scim_attributes.any? { |attribute| attribute.name == scim_attribute.to_s }
         
     | 
| 
       664 
     | 
    
         
            -
                              end
         
     | 
| 
       665 
     | 
    
         
            -
                              attribute_tree << scim_attribute.to_s
         
     | 
| 
       666 
     | 
    
         
            -
             
     | 
| 
       667 
     | 
    
         
            -
                              sub_scim_hash_or_leaf_value = scim_hash_or_leaf_value&.dig(*attribute_tree)
         
     | 
| 
      
 619 
     | 
    
         
            +
                              sub_scim_hash_or_leaf_value = scim_hash_or_leaf_value&.dig(scim_attribute.to_s)
         
     | 
| 
       668 
620 
     | 
    
         | 
| 
       669 
621 
     | 
    
         
             
                              self.from_scim_backend!(
         
     | 
| 
       670 
622 
     | 
    
         
             
                                attrs_map_or_leaf_value: sub_attrs_map_or_leaf_value,
         
     | 
| 
         @@ -949,89 +901,10 @@ module Scimitar 
     | 
|
| 
       949 
901 
     | 
    
         
             
                              else
         
     | 
| 
       950 
902 
     | 
    
         
             
                                altering_hash[path_component] = value
         
     | 
| 
       951 
903 
     | 
    
         
             
                              end
         
     | 
| 
       952 
     | 
    
         
            -
             
     | 
| 
       953 
904 
     | 
    
         
             
                            when 'replace'
         
     | 
| 
       954 
     | 
    
         
            -
                               
     | 
| 
       955 
     | 
    
         
            -
                                dot_pathed_value = value.inject({}) do |hash, (k, v)|
         
     | 
| 
       956 
     | 
    
         
            -
                                  hash.deep_merge!(::Scimitar::Support::Utilities.dot_path(k.split('.'), v))
         
     | 
| 
       957 
     | 
    
         
            -
                                end
         
     | 
| 
       958 
     | 
    
         
            -
                                altering_hash[path_component].deep_merge!(dot_pathed_value)
         
     | 
| 
       959 
     | 
    
         
            -
                              else
         
     | 
| 
       960 
     | 
    
         
            -
                                altering_hash[path_component] = value
         
     | 
| 
       961 
     | 
    
         
            -
                              end
         
     | 
| 
       962 
     | 
    
         
            -
             
     | 
| 
       963 
     | 
    
         
            -
                            # The array check handles payloads seen from e.g. Microsoft for
         
     | 
| 
       964 
     | 
    
         
            -
                            # remove-user-from-group, where contrary to examples in the RFC
         
     | 
| 
       965 
     | 
    
         
            -
                            # which would imply "payload removes all users", there is the
         
     | 
| 
       966 
     | 
    
         
            -
                            # clear intent to remove just one.
         
     | 
| 
       967 
     | 
    
         
            -
                            #
         
     | 
| 
       968 
     | 
    
         
            -
                            # https://tools.ietf.org/html/rfc7644#section-3.5.2.2
         
     | 
| 
       969 
     | 
    
         
            -
                            # https://learn.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#update-group-remove-members
         
     | 
| 
       970 
     | 
    
         
            -
                            #
         
     | 
| 
       971 
     | 
    
         
            -
                            # Since remove-all in the face of remove-one is destructive, we
         
     | 
| 
       972 
     | 
    
         
            -
                            # do a special check here to see if there's an array value for
         
     | 
| 
       973 
     | 
    
         
            -
                            # the array path that the payload yielded. If so, we can match
         
     | 
| 
       974 
     | 
    
         
            -
                            # each value against array items and remove just those items.
         
     | 
| 
       975 
     | 
    
         
            -
                            #
         
     | 
| 
       976 
     | 
    
         
            -
                            # There is an additional special case to handle a bad example
         
     | 
| 
       977 
     | 
    
         
            -
                            # from Salesforce:
         
     | 
| 
       978 
     | 
    
         
            -
                            #
         
     | 
| 
       979 
     | 
    
         
            -
                            #   https://help.salesforce.com/s/articleView?id=sf.identity_scim_manage_groups.htm&type=5
         
     | 
| 
       980 
     | 
    
         
            -
                            #
         
     | 
| 
      
 905 
     | 
    
         
            +
                              altering_hash[path_component] = value
         
     | 
| 
       981 
906 
     | 
    
         
             
                            when 'remove'
         
     | 
| 
       982 
     | 
    
         
            -
                               
     | 
| 
       983 
     | 
    
         
            -
             
     | 
| 
       984 
     | 
    
         
            -
                                # Handle bad Salesforce example. That might be simply a
         
     | 
| 
       985 
     | 
    
         
            -
                                # documentation error, but just in case...
         
     | 
| 
       986 
     | 
    
         
            -
                                #
         
     | 
| 
       987 
     | 
    
         
            -
                                value = value.values.first if (
         
     | 
| 
       988 
     | 
    
         
            -
                                  path_component&.downcase == 'members' &&
         
     | 
| 
       989 
     | 
    
         
            -
                                  value.is_a?(Hash)                     &&
         
     | 
| 
       990 
     | 
    
         
            -
                                  value.keys.size == 1                  &&
         
     | 
| 
       991 
     | 
    
         
            -
                                  value.keys.first&.downcase == 'members'
         
     | 
| 
       992 
     | 
    
         
            -
                                )
         
     | 
| 
       993 
     | 
    
         
            -
             
     | 
| 
       994 
     | 
    
         
            -
                                # The Microsoft example provides an array of values, but we
         
     | 
| 
       995 
     | 
    
         
            -
                                # may as well cope with a value specified 'flat'. Promote
         
     | 
| 
       996 
     | 
    
         
            -
                                # such a thing to an Array to simplify the following code.
         
     | 
| 
       997 
     | 
    
         
            -
                                #
         
     | 
| 
       998 
     | 
    
         
            -
                                value = [value] unless value.is_a?(Array)
         
     | 
| 
       999 
     | 
    
         
            -
             
     | 
| 
       1000 
     | 
    
         
            -
                                # For each value item, delete matching array entries. The
         
     | 
| 
       1001 
     | 
    
         
            -
                                # concept of "matching" is:
         
     | 
| 
       1002 
     | 
    
         
            -
                                #
         
     | 
| 
       1003 
     | 
    
         
            -
                                # * For simple non-Hash values (if possible) just delete on
         
     | 
| 
       1004 
     | 
    
         
            -
                                #   an exact match
         
     | 
| 
       1005 
     | 
    
         
            -
                                #
         
     | 
| 
       1006 
     | 
    
         
            -
                                # * For Hash-based values, only delete if all 'patch' keys
         
     | 
| 
       1007 
     | 
    
         
            -
                                #   are present in the resource and all values thus match.
         
     | 
| 
       1008 
     | 
    
         
            -
                                #
         
     | 
| 
       1009 
     | 
    
         
            -
                                # Special case to ignore '$ref' from the Microsoft payload.
         
     | 
| 
       1010 
     | 
    
         
            -
                                #
         
     | 
| 
       1011 
     | 
    
         
            -
                                # Note coercion to strings to account for SCIM vs the usual
         
     | 
| 
       1012 
     | 
    
         
            -
                                # tricky case of underlying implementations with (say)
         
     | 
| 
       1013 
     | 
    
         
            -
                                # integer primary keys, which all end up as strings anyway.
         
     | 
| 
       1014 
     | 
    
         
            -
                                #
         
     | 
| 
       1015 
     | 
    
         
            -
                                value.each do | value_item |
         
     | 
| 
       1016 
     | 
    
         
            -
                                  altering_hash[path_component].delete_if do | item |
         
     | 
| 
       1017 
     | 
    
         
            -
                                    if item.is_a?(Hash) && value_item.is_a?(Hash)
         
     | 
| 
       1018 
     | 
    
         
            -
                                      matched_all = true
         
     | 
| 
       1019 
     | 
    
         
            -
                                      value_item.each do | value_key, value_value |
         
     | 
| 
       1020 
     | 
    
         
            -
                                        next if value_key == '$ref'
         
     | 
| 
       1021 
     | 
    
         
            -
                                        if ! item.key?(value_key) || item[value_key]&.to_s != value_value&.to_s
         
     | 
| 
       1022 
     | 
    
         
            -
                                          matched_all = false
         
     | 
| 
       1023 
     | 
    
         
            -
                                        end
         
     | 
| 
       1024 
     | 
    
         
            -
                                      end
         
     | 
| 
       1025 
     | 
    
         
            -
                                      matched_all
         
     | 
| 
       1026 
     | 
    
         
            -
                                    else
         
     | 
| 
       1027 
     | 
    
         
            -
                                      item&.to_s == value_item&.to_s
         
     | 
| 
       1028 
     | 
    
         
            -
                                    end
         
     | 
| 
       1029 
     | 
    
         
            -
                                  end
         
     | 
| 
       1030 
     | 
    
         
            -
                                end
         
     | 
| 
       1031 
     | 
    
         
            -
                              else
         
     | 
| 
       1032 
     | 
    
         
            -
                                altering_hash.delete(path_component)
         
     | 
| 
       1033 
     | 
    
         
            -
                              end
         
     | 
| 
       1034 
     | 
    
         
            -
             
     | 
| 
      
 907 
     | 
    
         
            +
                              altering_hash.delete(path_component)
         
     | 
| 
       1035 
908 
     | 
    
         
             
                          end
         
     | 
| 
       1036 
909 
     | 
    
         
             
                        end
         
     | 
| 
       1037 
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'),
         
     | 
| 
         @@ -93,23 +93,14 @@ module Scimitar 
     | 
|
| 
       93 
93 
     | 
    
         
             
                  end
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
       95 
95 
     | 
    
         
             
                  def valid_simple_type?(value)
         
     | 
| 
       96 
     | 
    
         
            -
                     
     | 
| 
       97 
     | 
    
         
            -
                       
     | 
| 
       98 
     | 
    
         
            -
                       
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
                      errors.add(self.name, "has the wrong type. It has to be a(n) #{self.type}.") unless valid
         
     | 
| 
       102 
     | 
    
         
            -
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                    valid = (type == 'string' && value.is_a?(String)) ||
         
     | 
| 
      
 97 
     | 
    
         
            +
                      (type == 'boolean' && (value.is_a?(TrueClass) || value.is_a?(FalseClass))) ||
         
     | 
| 
      
 98 
     | 
    
         
            +
                      (type == 'integer' && (value.is_a?(Integer))) ||
         
     | 
| 
      
 99 
     | 
    
         
            +
                      (type == 'dateTime' && valid_date_time?(value))
         
     | 
| 
      
 100 
     | 
    
         
            +
                    errors.add(self.name, "has the wrong type. It has to be a(n) #{self.type}.") unless valid
         
     | 
| 
       103 
101 
     | 
    
         
             
                    valid
         
     | 
| 
       104 
102 
     | 
    
         
             
                  end
         
     | 
| 
       105 
103 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
                  def simple_type?(value)
         
     | 
| 
       107 
     | 
    
         
            -
                    (type == 'string' && value.is_a?(String)) ||
         
     | 
| 
       108 
     | 
    
         
            -
                    (type == 'boolean' && (value.is_a?(TrueClass) || value.is_a?(FalseClass))) ||
         
     | 
| 
       109 
     | 
    
         
            -
                    (type == 'integer' && (value.is_a?(Integer))) ||
         
     | 
| 
       110 
     | 
    
         
            -
                    (type == 'dateTime' && valid_date_time?(value))
         
     | 
| 
       111 
     | 
    
         
            -
                  end
         
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
104 
     | 
    
         
             
                  def valid_date_time?(value)
         
     | 
| 
       114 
105 
     | 
    
         
             
                    !!Time.iso8601(value)
         
     | 
| 
       115 
106 
     | 
    
         
             
                  rescue ArgumentError
         
     | 
| 
         @@ -13,7 +13,7 @@ module Scimitar 
     | 
|
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  # Converts the schema to its json representation that will be returned by /SCHEMAS end-point of a SCIM service provider.
         
     | 
| 
       15 
15 
     | 
    
         
             
                  def as_json(options = {})
         
     | 
| 
       16 
     | 
    
         
            -
                    @meta.location  
     | 
| 
      
 16 
     | 
    
         
            +
                    @meta.location = Scimitar::Engine.routes.url_helpers.scim_schemas_path(name: id)
         
     | 
| 
       17 
17 
     | 
    
         
             
                    original = super
         
     | 
| 
       18 
18 
     | 
    
         
             
                    original.merge('attributes' => original.delete('scim_attributes'))
         
     | 
| 
       19 
19 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -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:  
     | 
| 
      
 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'),
         
     | 
| 
         @@ -9,22 +9,11 @@ module Scimitar 
     | 
|
| 
       9 
9 
     | 
    
         
             
              class ServiceProviderConfiguration
         
     | 
| 
       10 
10 
     | 
    
         
             
                include ActiveModel::Model
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                attr_accessor 
     | 
| 
       13 
     | 
    
         
            -
                  : 
     | 
| 
       14 
     | 
    
         
            -
                  : 
     | 
| 
       15 
     | 
    
         
            -
                  :bulk,
         
     | 
| 
       16 
     | 
    
         
            -
                  :filter,
         
     | 
| 
       17 
     | 
    
         
            -
                  :changePassword,
         
     | 
| 
       18 
     | 
    
         
            -
                  :sort,
         
     | 
| 
       19 
     | 
    
         
            -
                  :etag,
         
     | 
| 
       20 
     | 
    
         
            -
                  :authenticationSchemes,
         
     | 
| 
       21 
     | 
    
         
            -
                  :schemas,
         
     | 
| 
       22 
     | 
    
         
            -
                  :meta,
         
     | 
| 
       23 
     | 
    
         
            -
                )
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor :patch, :bulk, :filter, :changePassword,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  :sort, :etag, :authenticationSchemes,
         
     | 
| 
      
 14 
     | 
    
         
            +
                  :schemas, :meta
         
     | 
| 
       24 
15 
     | 
    
         | 
| 
       25 
16 
     | 
    
         
             
                def initialize(attributes = {})
         
     | 
| 
       26 
     | 
    
         
            -
                  @uses_defaults = attributes.empty?
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
17 
     | 
    
         
             
                  defaults = {
         
     | 
| 
       29 
18 
     | 
    
         
             
                    bulk:           Supportable.unsupported,
         
     | 
| 
       30 
19 
     | 
    
         
             
                    changePassword: Supportable.unsupported,
         
     | 
| 
         @@ -38,10 +38,9 @@ Rails.application.config.to_prepare do # (required for >= Rails 7 / Zeitwerk) 
     | 
|
| 
       38 
38 
     | 
    
         
             
              Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                # If you have filters you want to run for any Scimitar action/route, you
         
     | 
| 
       41 
     | 
    
         
            -
                # can define them here.  
     | 
| 
       42 
     | 
    
         
            -
                #  
     | 
| 
       43 
     | 
    
         
            -
                #  
     | 
| 
       44 
     | 
    
         
            -
                # customise how Scimitar generates URLs:
         
     | 
| 
      
 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:
         
     | 
| 
       45 
44 
     | 
    
         
             
                #
         
     | 
| 
       46 
45 
     | 
    
         
             
                #     application_controller_mixin: Module.new do
         
     | 
| 
       47 
46 
     | 
    
         
             
                #       def self.included(base)
         
     | 
| 
         @@ -55,10 +54,6 @@ Rails.application.config.to_prepare do # (required for >= Rails 7 / Zeitwerk) 
     | 
|
| 
       55 
54 
     | 
    
         
             
                #           prepend_before_action :setup_some_kind_of_multi_tenancy_data
         
     | 
| 
       56 
55 
     | 
    
         
             
                #         end
         
     | 
| 
       57 
56 
     | 
    
         
             
                #       end
         
     | 
| 
       58 
     | 
    
         
            -
                #
         
     | 
| 
       59 
     | 
    
         
            -
                #       def scim_schemas_url(options)
         
     | 
| 
       60 
     | 
    
         
            -
                #         super(custom_param: 'value', **options)
         
     | 
| 
       61 
     | 
    
         
            -
                #       end
         
     | 
| 
       62 
57 
     | 
    
         
             
                #     end, # ...other configuration entries might follow...
         
     | 
| 
       63 
58 
     | 
    
         | 
| 
       64 
59 
     | 
    
         
             
                # If you want to support username/password authentication:
         
     | 
| 
         @@ -86,26 +81,6 @@ Rails.application.config.to_prepare do # (required for >= Rails 7 / Zeitwerk) 
     | 
|
| 
       86 
81 
     | 
    
         
             
                # Note that both basic and token authentication can be declared, with the
         
     | 
| 
       87 
82 
     | 
    
         
             
                # parameters in the inbound HTTP request determining which is invoked.
         
     | 
| 
       88 
83 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                # Scimitar rescues certain error cases and exceptions, in order to return a
         
     | 
| 
       90 
     | 
    
         
            -
                # JSON response to the API caller. If you want exceptions to also be
         
     | 
| 
       91 
     | 
    
         
            -
                # reported to a third party system such as sentry.io or raygun.com, you can
         
     | 
| 
       92 
     | 
    
         
            -
                # configure a Proc to do so. It is passed a Ruby exception subclass object.
         
     | 
| 
       93 
     | 
    
         
            -
                # For example, a minimal sentry.io reporter might do this:
         
     | 
| 
       94 
     | 
    
         
            -
                #
         
     | 
| 
       95 
     | 
    
         
            -
                #     exception_reporter: Proc.new do | exception |
         
     | 
| 
       96 
     | 
    
         
            -
                #       Sentry.capture_exception(exception)
         
     | 
| 
       97 
     | 
    
         
            -
                #     end
         
     | 
| 
       98 
     | 
    
         
            -
                #
         
     | 
| 
       99 
     | 
    
         
            -
                # You will still need to configure your reporting system according to its
         
     | 
| 
       100 
     | 
    
         
            -
                # documentation (e.g. via a Rails "config/initializers/<foo>.rb" file).
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
                # Scimilar treats "VDTP" (Value, Display, Type, Primary) attribute values,
         
     | 
| 
       103 
     | 
    
         
            -
                # used for e.g. e-mail addresses or phone numbers, as required by default.
         
     | 
| 
       104 
     | 
    
         
            -
                # If you encounter a service which calls these with e.g. "null" value data,
         
     | 
| 
       105 
     | 
    
         
            -
                # you can configure all values to be optional. You'll need to deal with
         
     | 
| 
       106 
     | 
    
         
            -
                # whatever that means for you receiving system in your model code.
         
     | 
| 
       107 
     | 
    
         
            -
                #
         
     | 
| 
       108 
     | 
    
         
            -
                #     optional_value_fields_required: false
         
     | 
| 
       109 
84 
     | 
    
         
             
              })
         
     | 
| 
       110 
85 
     | 
    
         | 
| 
       111 
86 
     | 
    
         
             
            end
         
     | 
    
        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 = ' 
     | 
| 
      
 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 = ' 
     | 
| 
      
 11 
     | 
    
         
            +
              DATE = '2022-03-04'
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            end
         
     | 
    
        data/lib/scimitar.rb
    CHANGED
    
    | 
         @@ -1,13 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'scimitar/version'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'scimitar/support/hash_with_indifferent_case_insensitive_access'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'scimitar/support/utilities'
         
     | 
| 
       4 
3 
     | 
    
         
             
            require 'scimitar/engine'
         
     | 
| 
       5 
4 
     | 
    
         | 
| 
       6 
5 
     | 
    
         
             
            module Scimitar
         
     | 
| 
       7 
6 
     | 
    
         
             
              def self.service_provider_configuration=(custom_configuration)
         
     | 
| 
       8 
     | 
    
         
            -
                 
     | 
| 
       9 
     | 
    
         
            -
                  @service_provider_configuration = custom_configuration
         
     | 
| 
       10 
     | 
    
         
            -
                end
         
     | 
| 
      
 7 
     | 
    
         
            +
                @service_provider_configuration = custom_configuration
         
     | 
| 
       11 
8 
     | 
    
         
             
              end
         
     | 
| 
       12 
9 
     | 
    
         | 
| 
       13 
10 
     | 
    
         
             
              def self.service_provider_configuration(location:)
         
     | 
| 
         @@ -17,9 +14,7 @@ module Scimitar 
     | 
|
| 
       17 
14 
     | 
    
         
             
              end
         
     | 
| 
       18 
15 
     | 
    
         | 
| 
       19 
16 
     | 
    
         
             
              def self.engine_configuration=(custom_configuration)
         
     | 
| 
       20 
     | 
    
         
            -
                 
     | 
| 
       21 
     | 
    
         
            -
                  @engine_configuration = custom_configuration
         
     | 
| 
       22 
     | 
    
         
            -
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
                @engine_configuration = custom_configuration
         
     | 
| 
       23 
18 
     | 
    
         
             
              end
         
     | 
| 
       24 
19 
     | 
    
         | 
| 
       25 
20 
     | 
    
         
             
              def self.engine_configuration
         
     | 
| 
         @@ -1,24 +1,18 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class MockUser < ActiveRecord::Base
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
              self.primary_key = :primary_key
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
3 
     | 
    
         
             
              # ===========================================================================
         
     | 
| 
       6 
4 
     | 
    
         
             
              # TEST ATTRIBUTES - see db/migrate/20210304014602_create_mock_users.rb etc.
         
     | 
| 
       7 
5 
     | 
    
         
             
              # ===========================================================================
         
     | 
| 
       8 
6 
     | 
    
         | 
| 
       9 
7 
     | 
    
         
             
              READWRITE_ATTRS = %w{
         
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
      
 8 
     | 
    
         
            +
                id
         
     | 
| 
       11 
9 
     | 
    
         
             
                scim_uid
         
     | 
| 
       12 
10 
     | 
    
         
             
                username
         
     | 
| 
       13 
     | 
    
         
            -
                password
         
     | 
| 
       14 
11 
     | 
    
         
             
                first_name
         
     | 
| 
       15 
12 
     | 
    
         
             
                last_name
         
     | 
| 
       16 
13 
     | 
    
         
             
                work_email_address
         
     | 
| 
       17 
14 
     | 
    
         
             
                home_email_address
         
     | 
| 
       18 
15 
     | 
    
         
             
                work_phone_number
         
     | 
| 
       19 
     | 
    
         
            -
                organization
         
     | 
| 
       20 
     | 
    
         
            -
                department
         
     | 
| 
       21 
     | 
    
         
            -
                mock_groups
         
     | 
| 
       22 
16 
     | 
    
         
             
              }
         
     | 
| 
       23 
17 
     | 
    
         | 
| 
       24 
18 
     | 
    
         
             
              has_and_belongs_to_many :mock_groups
         
     | 
| 
         @@ -44,10 +38,9 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       44 
38 
     | 
    
         | 
| 
       45 
39 
     | 
    
         
             
              def self.scim_attributes_map
         
     | 
| 
       46 
40 
     | 
    
         
             
                return {
         
     | 
| 
       47 
     | 
    
         
            -
                  id:         : 
     | 
| 
      
 41 
     | 
    
         
            +
                  id:         :id,
         
     | 
| 
       48 
42 
     | 
    
         
             
                  externalId: :scim_uid,
         
     | 
| 
       49 
43 
     | 
    
         
             
                  userName:   :username,
         
     | 
| 
       50 
     | 
    
         
            -
                  password:   :password,
         
     | 
| 
       51 
44 
     | 
    
         
             
                  name:       {
         
     | 
| 
       52 
45 
     | 
    
         
             
                    givenName:  :first_name,
         
     | 
| 
       53 
46 
     | 
    
         
             
                    familyName: :last_name
         
     | 
| 
         @@ -89,23 +82,7 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       89 
82 
     | 
    
         
             
                      }
         
     | 
| 
       90 
83 
     | 
    
         
             
                    }
         
     | 
| 
       91 
84 
     | 
    
         
             
                  ],
         
     | 
| 
       92 
     | 
    
         
            -
                  active: :is_active 
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
                  # Custom extension schema - see configuration in
         
     | 
| 
       95 
     | 
    
         
            -
                  # "spec/apps/dummy/config/initializers/scimitar.rb".
         
     | 
| 
       96 
     | 
    
         
            -
                  #
         
     | 
| 
       97 
     | 
    
         
            -
                  organization: :organization,
         
     | 
| 
       98 
     | 
    
         
            -
                  department:   :department,
         
     | 
| 
       99 
     | 
    
         
            -
                  userGroups: [
         
     | 
| 
       100 
     | 
    
         
            -
                    {
         
     | 
| 
       101 
     | 
    
         
            -
                      list:      :mock_groups,
         
     | 
| 
       102 
     | 
    
         
            -
                      find_with: ->(value) { MockGroup.find(value["value"]) },
         
     | 
| 
       103 
     | 
    
         
            -
                      using: {
         
     | 
| 
       104 
     | 
    
         
            -
                        value:   :id,
         
     | 
| 
       105 
     | 
    
         
            -
                        display: :display_name
         
     | 
| 
       106 
     | 
    
         
            -
                      }
         
     | 
| 
       107 
     | 
    
         
            -
                    }
         
     | 
| 
       108 
     | 
    
         
            -
                  ]
         
     | 
| 
      
 85 
     | 
    
         
            +
                  active: :is_active
         
     | 
| 
       109 
86 
     | 
    
         
             
                }
         
     | 
| 
       110 
87 
     | 
    
         
             
              end
         
     | 
| 
       111 
88 
     | 
    
         | 
| 
         @@ -115,16 +92,11 @@ class MockUser < ActiveRecord::Base 
     | 
|
| 
       115 
92 
     | 
    
         | 
| 
       116 
93 
     | 
    
         
             
              def self.scim_queryable_attributes
         
     | 
| 
       117 
94 
     | 
    
         
             
                return {
         
     | 
| 
       118 
     | 
    
         
            -
                  ' 
     | 
| 
       119 
     | 
    
         
            -
                  ' 
     | 
| 
       120 
     | 
    
         
            -
                  ' 
     | 
| 
       121 
     | 
    
         
            -
                  ' 
     | 
| 
       122 
     | 
    
         
            -
                  ' 
     | 
| 
       123 
     | 
    
         
            -
                  'groups'            => { column: MockGroup.arel_table[:id] },
         
     | 
| 
       124 
     | 
    
         
            -
                  'groups.value'      => { column: MockGroup.arel_table[:id] },
         
     | 
| 
       125 
     | 
    
         
            -
                  'emails'            => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
       126 
     | 
    
         
            -
                  'emails.value'      => { columns: [ :work_email_address, :home_email_address ] },
         
     | 
| 
       127 
     | 
    
         
            -
                  'emails.type'       => { ignore: true } # We can't filter on that; it'll just search all e-mails
         
     | 
| 
      
 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
         
     | 
| 
       128 
100 
     | 
    
         
             
                }
         
     | 
| 
       129 
101 
     | 
    
         
             
              end
         
     | 
| 
       130 
102 
     | 
    
         | 
| 
         @@ -1,15 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/core_ext/integer/time'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            Rails.application.configure do
         
     | 
| 
       2 
4 
     | 
    
         
             
              config.cache_classes = true
         
     | 
| 
       3 
5 
     | 
    
         
             
              config.eager_load = false
         
     | 
| 
       4 
     | 
    
         
            -
              config.serve_static_files = true
         
     | 
| 
       5 
     | 
    
         
            -
              config.static_cache_control = 'public, max-age=3600'
         
     | 
| 
       6 
     | 
    
         
            -
              config.consider_all_requests_local = true
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
               
     | 
| 
      
 7 
     | 
    
         
            +
              # Configure public file server for tests with Cache-Control for performance.
         
     | 
| 
      
 8 
     | 
    
         
            +
              config.public_file_server.enabled = true
         
     | 
| 
      
 9 
     | 
    
         
            +
              config.public_file_server.headers = {
         
     | 
| 
      
 10 
     | 
    
         
            +
                'Cache-Control' => "public, max-age=#{1.hour.to_i}"
         
     | 
| 
      
 11 
     | 
    
         
            +
              }
         
     | 
| 
       9 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
              # Show full error reports and disable caching.
         
     | 
| 
      
 14 
     | 
    
         
            +
              config.consider_all_requests_local       = true
         
     | 
| 
       10 
15 
     | 
    
         
             
              config.action_controller.perform_caching = false
         
     | 
| 
      
 16 
     | 
    
         
            +
              config.cache_store = :null_store
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              # Raise exceptions instead of rendering exception templates.
         
     | 
| 
      
 19 
     | 
    
         
            +
              config.action_dispatch.show_exceptions = false
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              # Disable request forgery protection in test environment.
         
     | 
| 
       11 
22 
     | 
    
         
             
              config.action_controller.allow_forgery_protection = false
         
     | 
| 
       12 
23 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
               
     | 
| 
      
 24 
     | 
    
         
            +
              # Print deprecation notices to the stderr.
         
     | 
| 
       14 
25 
     | 
    
         
             
              config.active_support.deprecation = :stderr
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              # Raise exceptions for disallowed deprecations.
         
     | 
| 
      
 28 
     | 
    
         
            +
              config.active_support.disallowed_deprecation = :raise
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              # Tell Active Support which deprecation messages to disallow.
         
     | 
| 
      
 31 
     | 
    
         
            +
              config.active_support.disallowed_deprecation_warnings = []
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              # Raises error for missing translations.
         
     | 
| 
      
 34 
     | 
    
         
            +
              config.i18n.raise_on_missing_translations = true
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              # Annotate rendered view with file names.
         
     | 
| 
      
 37 
     | 
    
         
            +
              # config.action_view.annotate_rendered_view_with_filenames = true
         
     | 
| 
       15 
38 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,67 +1,16 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Test app configuration.
         
     | 
| 
       2 
2 
     | 
    
         
             
            #
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
            # Further, https://github.com/RIPAGlobal/scimitar/pull/54 fixed warning
         
     | 
| 
       13 
     | 
    
         
            -
            # messages in a way that worked on Rails 6+ but, for V1 Scimitar, it would
         
     | 
| 
       14 
     | 
    
         
            -
            # break existing working setups that didn't use the +to_prepare+ wrapper. Their
         
     | 
| 
       15 
     | 
    
         
            -
            # application configuration would be written *first* but then *overwritten* by
         
     | 
| 
       16 
     | 
    
         
            -
            # the default +to_prepare+ block in Scimitar itself, since that runs later. The
         
     | 
| 
       17 
     | 
    
         
            -
            # file below does *not* use +to_prepare+ in order to test the workaround that
         
     | 
| 
       18 
     | 
    
         
            -
            # was produced; it should work on all Ruby versions as-is.
         
     | 
| 
       19 
     | 
    
         
            -
            #
         
     | 
| 
       20 
     | 
    
         
            -
            Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
              application_controller_mixin: Module.new do
         
     | 
| 
       23 
     | 
    
         
            -
                def self.included(base)
         
     | 
| 
       24 
     | 
    
         
            -
                  base.class_eval do
         
     | 
| 
       25 
     | 
    
         
            -
                    def test_hook; end
         
     | 
| 
       26 
     | 
    
         
            -
                    before_action :test_hook
         
     | 
| 
      
 3 
     | 
    
         
            +
            Rails.application.config.to_prepare do
         
     | 
| 
      
 4 
     | 
    
         
            +
              Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                application_controller_mixin: Module.new do
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def self.included(base)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    base.class_eval do
         
     | 
| 
      
 9 
     | 
    
         
            +
                      def test_hook; end
         
     | 
| 
      
 10 
     | 
    
         
            +
                      before_action :test_hook
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
       27 
12 
     | 
    
         
             
                  end
         
     | 
| 
       28 
13 
     | 
    
         
             
                end
         
     | 
| 
       29 
14 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                  super(test: 1, **options)
         
     | 
| 
       32 
     | 
    
         
            -
                end
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                def scim_resource_type_url(options)
         
     | 
| 
       35 
     | 
    
         
            -
                  super(test: 1, **options)
         
     | 
| 
       36 
     | 
    
         
            -
                end
         
     | 
| 
       37 
     | 
    
         
            -
              end
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
            })
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
            module ScimSchemaExtensions
         
     | 
| 
       42 
     | 
    
         
            -
              module User
         
     | 
| 
       43 
     | 
    
         
            -
                class Enterprise < Scimitar::Schema::Base
         
     | 
| 
       44 
     | 
    
         
            -
                  def initialize(options = {})
         
     | 
| 
       45 
     | 
    
         
            -
                    super(
         
     | 
| 
       46 
     | 
    
         
            -
                      name:            'ExtendedUser',
         
     | 
| 
       47 
     | 
    
         
            -
                      description:     'Enterprise extension for a User',
         
     | 
| 
       48 
     | 
    
         
            -
                      id:              self.class.id,
         
     | 
| 
       49 
     | 
    
         
            -
                      scim_attributes: self.class.scim_attributes
         
     | 
| 
       50 
     | 
    
         
            -
                    )
         
     | 
| 
       51 
     | 
    
         
            -
                  end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                  def self.id
         
     | 
| 
       54 
     | 
    
         
            -
                    'urn:ietf:params:scim:schemas:extension:enterprise:2.0:User'
         
     | 
| 
       55 
     | 
    
         
            -
                  end
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
                  def self.scim_attributes
         
     | 
| 
       58 
     | 
    
         
            -
                    [
         
     | 
| 
       59 
     | 
    
         
            -
                      Scimitar::Schema::Attribute.new(name: 'organization', type: 'string'),
         
     | 
| 
       60 
     | 
    
         
            -
                      Scimitar::Schema::Attribute.new(name: 'department',   type: 'string')
         
     | 
| 
       61 
     | 
    
         
            -
                    ]
         
     | 
| 
       62 
     | 
    
         
            -
                  end
         
     | 
| 
       63 
     | 
    
         
            -
                end
         
     | 
| 
       64 
     | 
    
         
            -
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              })
         
     | 
| 
       65 
16 
     | 
    
         
             
            end
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
            Scimitar::Resources::User.extend_schema ScimSchemaExtensions::User::Enterprise
         
     | 
| 
         @@ -6,38 +6,17 @@ 
     | 
|
| 
       6 
6 
     | 
    
         
             
            Rails.application.routes.draw do
         
     | 
| 
       7 
7 
     | 
    
         
             
              mount Scimitar::Engine, at: '/'
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
              get    'Users', 
     | 
| 
       10 
     | 
    
         
            -
              get    'Users/:id', 
     | 
| 
       11 
     | 
    
         
            -
              post   'Users', 
     | 
| 
       12 
     | 
    
         
            -
              put    'Users/:id', 
     | 
| 
       13 
     | 
    
         
            -
              patch  'Users/:id', 
     | 
| 
       14 
     | 
    
         
            -
              delete 'Users/:id', 
     | 
| 
      
 9 
     | 
    
         
            +
              get    'Users',     to: 'mock_users#index'
         
     | 
| 
      
 10 
     | 
    
         
            +
              get    'Users/:id', to: 'mock_users#show'
         
     | 
| 
      
 11 
     | 
    
         
            +
              post   'Users',     to: 'mock_users#create'
         
     | 
| 
      
 12 
     | 
    
         
            +
              put    'Users/:id', to: 'mock_users#replace'
         
     | 
| 
      
 13 
     | 
    
         
            +
              patch  'Users/:id', to: 'mock_users#update'
         
     | 
| 
      
 14 
     | 
    
         
            +
              delete 'Users/:id', to: 'mock_users#destroy'
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
               
     | 
| 
       17 
     | 
    
         
            -
              get    'Groups/:id', to: 'mock_groups#show'
         
     | 
| 
       18 
     | 
    
         
            -
              patch  'Groups/:id', to: 'mock_groups#update'
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
              # For testing blocks passed to ActiveRecordBackedResourcesController#create,
         
     | 
| 
       21 
     | 
    
         
            -
              # #update, #replace and #destroy.
         
     | 
| 
      
 16 
     | 
    
         
            +
              # For testing blocks passed to ActiveRecordBackedResourcesController#destroy
         
     | 
| 
       22 
17 
     | 
    
         
             
              #
         
     | 
| 
       23 
     | 
    
         
            -
              post   'CustomCreateUsers',      to: 'custom_create_mock_users#create'
         
     | 
| 
       24 
     | 
    
         
            -
              patch  'CustomUpdateUsers/:id',  to: 'custom_update_mock_users#update'
         
     | 
| 
       25 
     | 
    
         
            -
              put    'CustomReplaceUsers/:id', to: 'custom_replace_mock_users#replace'
         
     | 
| 
       26 
18 
     | 
    
         
             
              delete 'CustomDestroyUsers/:id', to: 'custom_destroy_mock_users#destroy'
         
     | 
| 
       27 
19 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
              # Needed because the auto-render of most of the above includes a 'url_for'
         
     | 
| 
       29 
     | 
    
         
            -
              # call for a 'show' action, so we must include routes (implemented in the
         
     | 
| 
       30 
     | 
    
         
            -
              # base class) for the "show" endpoint.
         
     | 
| 
       31 
     | 
    
         
            -
              #
         
     | 
| 
       32 
     | 
    
         
            -
              get  'CustomCreateUsers/:id',  to: 'custom_create_mock_users#show'
         
     | 
| 
       33 
     | 
    
         
            -
              get  'CustomUpdateUsers/:id',  to: 'custom_update_mock_users#show'
         
     | 
| 
       34 
     | 
    
         
            -
              get  'CustomReplaceUsers/:id', to: 'custom_replace_mock_users#show'
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
              # For testing blocks passed to ActiveRecordBackedResourcesController#save!
         
     | 
| 
       37 
     | 
    
         
            -
              #
         
     | 
| 
       38 
     | 
    
         
            -
              post 'CustomSaveUsers',     to: 'custom_save_mock_users#create'
         
     | 
| 
       39 
     | 
    
         
            -
              get  'CustomSaveUsers/:id', to: 'custom_save_mock_users#show'
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
20 
     | 
    
         
             
              # For testing environment inside Scimitar::ApplicationController subclasses.
         
     | 
| 
       42 
21 
     | 
    
         
             
              #
         
     | 
| 
       43 
22 
     | 
    
         
             
              get  'CustomRequestVerifiers', to: 'custom_request_verifiers#index'
         
     |