scimaenaga 0.7.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -7
  3. data/Rakefile +6 -8
  4. data/app/controllers/concerns/{scim_rails → scimaenaga}/exception_handler.rb +47 -37
  5. data/app/controllers/concerns/scimaenaga/response.rb +94 -0
  6. data/app/controllers/scimaenaga/application_controller.rb +72 -0
  7. data/app/controllers/{scim_rails → scimaenaga}/scim_groups_controller.rb +26 -26
  8. data/app/controllers/scimaenaga/scim_schemas_controller.rb +42 -0
  9. data/app/controllers/scimaenaga/scim_users_controller.rb +104 -0
  10. data/app/helpers/{scim_rails → scimaenaga}/application_helper.rb +1 -1
  11. data/app/libraries/scim_patch.rb +16 -9
  12. data/app/libraries/scim_patch_operation.rb +51 -141
  13. data/app/libraries/scim_patch_operation_converter.rb +90 -0
  14. data/app/libraries/scim_patch_operation_group.rb +100 -0
  15. data/app/libraries/scim_patch_operation_user.rb +53 -0
  16. data/app/models/{scim_rails → scimaenaga}/application_record.rb +1 -1
  17. data/app/models/scimaenaga/authorize_api_request.rb +39 -0
  18. data/app/models/{scim_rails → scimaenaga}/scim_count.rb +8 -4
  19. data/app/models/scimaenaga/scim_query_parser.rb +49 -0
  20. data/config/routes.rb +15 -13
  21. data/lib/generators/scimaenaga/USAGE +8 -0
  22. data/lib/generators/scimaenaga/scimaenaga_generator.rb +7 -0
  23. data/lib/generators/{scim_rails → scimaenaga}/templates/initializer.rb +128 -22
  24. data/lib/{scim_rails → scimaenaga}/config.rb +9 -7
  25. data/lib/scimaenaga/encoder.rb +27 -0
  26. data/lib/scimaenaga/engine.rb +12 -0
  27. data/lib/scimaenaga/version.rb +5 -0
  28. data/lib/scimaenaga.rb +6 -0
  29. data/lib/tasks/{scim_rails_tasks.rake → scimaenaga_tasks.rake} +1 -1
  30. data/spec/controllers/{scim_rails → scimaenaga}/scim_groups_controller_spec.rb +8 -8
  31. data/spec/controllers/{scim_rails → scimaenaga}/scim_groups_request_spec.rb +18 -18
  32. data/spec/controllers/scimaenaga/scim_schemas_controller_spec.rb +238 -0
  33. data/spec/controllers/scimaenaga/scim_schemas_request_spec.rb +39 -0
  34. data/spec/controllers/{scim_rails → scimaenaga}/scim_users_controller_spec.rb +14 -15
  35. data/spec/controllers/{scim_rails → scimaenaga}/scim_users_request_spec.rb +20 -20
  36. data/spec/dummy/app/assets/config/manifest.js +1 -1
  37. data/spec/dummy/config/application.rb +1 -2
  38. data/spec/dummy/config/initializers/{scim_rails_config.rb → scimaenaga_config.rb} +25 -25
  39. data/spec/dummy/config/routes.rb +1 -1
  40. data/spec/factories/company.rb +3 -3
  41. data/spec/lib/scimaenaga/encoder_spec.rb +64 -0
  42. data/spec/libraries/scim_patch_operation_group_spec.rb +165 -0
  43. data/spec/libraries/scim_patch_operation_user_spec.rb +101 -0
  44. data/spec/libraries/scim_patch_spec.rb +129 -45
  45. data/spec/models/scim_query_parser_spec.rb +5 -6
  46. metadata +107 -108
  47. data/app/controllers/concerns/scim_rails/response.rb +0 -94
  48. data/app/controllers/scim_rails/application_controller.rb +0 -72
  49. data/app/controllers/scim_rails/scim_users_controller.rb +0 -107
  50. data/app/models/scim_rails/authorize_api_request.rb +0 -40
  51. data/app/models/scim_rails/scim_query_parser.rb +0 -49
  52. data/lib/generators/scim_rails/USAGE +0 -8
  53. data/lib/generators/scim_rails/scim_rails_generator.rb +0 -7
  54. data/lib/scim_rails/encoder.rb +0 -25
  55. data/lib/scim_rails/engine.rb +0 -12
  56. data/lib/scim_rails/version.rb +0 -5
  57. data/lib/scim_rails.rb +0 -6
  58. data/spec/dummy/db/development.sqlite3 +0 -0
  59. data/spec/dummy/db/test.sqlite3 +0 -0
  60. data/spec/dummy/log/development.log +0 -0
  61. data/spec/dummy/log/test.log +0 -5770
  62. data/spec/dummy/put_group.http +0 -5
  63. data/spec/dummy/tmp/restart.txt +0 -0
  64. data/spec/lib/scim_rails/encoder_spec.rb +0 -62
  65. data/spec/libraries/scim_patch_operation_spec.rb +0 -116
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scimaenaga
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Studist Corporation
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-02 00:00:00.000000000 Z
11
+ date: 2022-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -135,7 +135,7 @@ dependencies:
135
135
  - !ruby/object:Gem::Version
136
136
  version: '1.5'
137
137
  description: SCIM Adapter for Rails.
138
- email:
138
+ email:
139
139
  executables: []
140
140
  extensions: []
141
141
  extra_rdoc_files: []
@@ -143,33 +143,39 @@ files:
143
143
  - MIT-LICENSE
144
144
  - README.md
145
145
  - Rakefile
146
- - app/controllers/concerns/scim_rails/exception_handler.rb
147
- - app/controllers/concerns/scim_rails/response.rb
148
- - app/controllers/scim_rails/application_controller.rb
149
- - app/controllers/scim_rails/scim_groups_controller.rb
150
- - app/controllers/scim_rails/scim_users_controller.rb
151
- - app/helpers/scim_rails/application_helper.rb
146
+ - app/controllers/concerns/scimaenaga/exception_handler.rb
147
+ - app/controllers/concerns/scimaenaga/response.rb
148
+ - app/controllers/scimaenaga/application_controller.rb
149
+ - app/controllers/scimaenaga/scim_groups_controller.rb
150
+ - app/controllers/scimaenaga/scim_schemas_controller.rb
151
+ - app/controllers/scimaenaga/scim_users_controller.rb
152
+ - app/helpers/scimaenaga/application_helper.rb
152
153
  - app/libraries/scim_patch.rb
153
154
  - app/libraries/scim_patch_operation.rb
154
- - app/models/scim_rails/application_record.rb
155
- - app/models/scim_rails/authorize_api_request.rb
156
- - app/models/scim_rails/scim_count.rb
157
- - app/models/scim_rails/scim_query_parser.rb
155
+ - app/libraries/scim_patch_operation_converter.rb
156
+ - app/libraries/scim_patch_operation_group.rb
157
+ - app/libraries/scim_patch_operation_user.rb
158
+ - app/models/scimaenaga/application_record.rb
159
+ - app/models/scimaenaga/authorize_api_request.rb
160
+ - app/models/scimaenaga/scim_count.rb
161
+ - app/models/scimaenaga/scim_query_parser.rb
158
162
  - config/initializers/mime_types.rb
159
163
  - config/routes.rb
160
- - lib/generators/scim_rails/USAGE
161
- - lib/generators/scim_rails/scim_rails_generator.rb
162
- - lib/generators/scim_rails/templates/initializer.rb
163
- - lib/scim_rails.rb
164
- - lib/scim_rails/config.rb
165
- - lib/scim_rails/encoder.rb
166
- - lib/scim_rails/engine.rb
167
- - lib/scim_rails/version.rb
168
- - lib/tasks/scim_rails_tasks.rake
169
- - spec/controllers/scim_rails/scim_groups_controller_spec.rb
170
- - spec/controllers/scim_rails/scim_groups_request_spec.rb
171
- - spec/controllers/scim_rails/scim_users_controller_spec.rb
172
- - spec/controllers/scim_rails/scim_users_request_spec.rb
164
+ - lib/generators/scimaenaga/USAGE
165
+ - lib/generators/scimaenaga/scimaenaga_generator.rb
166
+ - lib/generators/scimaenaga/templates/initializer.rb
167
+ - lib/scimaenaga.rb
168
+ - lib/scimaenaga/config.rb
169
+ - lib/scimaenaga/encoder.rb
170
+ - lib/scimaenaga/engine.rb
171
+ - lib/scimaenaga/version.rb
172
+ - lib/tasks/scimaenaga_tasks.rake
173
+ - spec/controllers/scimaenaga/scim_groups_controller_spec.rb
174
+ - spec/controllers/scimaenaga/scim_groups_request_spec.rb
175
+ - spec/controllers/scimaenaga/scim_schemas_controller_spec.rb
176
+ - spec/controllers/scimaenaga/scim_schemas_request_spec.rb
177
+ - spec/controllers/scimaenaga/scim_users_controller_spec.rb
178
+ - spec/controllers/scimaenaga/scim_users_request_spec.rb
173
179
  - spec/dummy/Rakefile
174
180
  - spec/dummy/app/assets/config/manifest.js
175
181
  - spec/dummy/app/assets/javascripts/application.js
@@ -211,7 +217,7 @@ files:
211
217
  - spec/dummy/config/initializers/inflections.rb
212
218
  - spec/dummy/config/initializers/mime_types.rb
213
219
  - spec/dummy/config/initializers/new_framework_defaults.rb
214
- - spec/dummy/config/initializers/scim_rails_config.rb
220
+ - spec/dummy/config/initializers/scimaenaga_config.rb
215
221
  - spec/dummy/config/initializers/session_store.rb
216
222
  - spec/dummy/config/initializers/wrap_parameters.rb
217
223
  - spec/dummy/config/locales/en.yml
@@ -219,7 +225,6 @@ files:
219
225
  - spec/dummy/config/routes.rb
220
226
  - spec/dummy/config/secrets.yml
221
227
  - spec/dummy/config/spring.rb
222
- - spec/dummy/db/development.sqlite3
223
228
  - spec/dummy/db/migrate/20181206184304_create_users.rb
224
229
  - spec/dummy/db/migrate/20181206184313_create_companies.rb
225
230
  - spec/dummy/db/migrate/20210423075859_create_groups.rb
@@ -228,22 +233,18 @@ files:
228
233
  - spec/dummy/db/migrate/20220131090107_add_deletable_to_users.rb
229
234
  - spec/dummy/db/schema.rb
230
235
  - spec/dummy/db/seeds.rb
231
- - spec/dummy/db/test.sqlite3
232
- - spec/dummy/log/development.log
233
- - spec/dummy/log/test.log
234
236
  - spec/dummy/public/404.html
235
237
  - spec/dummy/public/422.html
236
238
  - spec/dummy/public/500.html
237
239
  - spec/dummy/public/apple-touch-icon-precomposed.png
238
240
  - spec/dummy/public/apple-touch-icon.png
239
241
  - spec/dummy/public/favicon.ico
240
- - spec/dummy/put_group.http
241
- - spec/dummy/tmp/restart.txt
242
242
  - spec/factories/company.rb
243
243
  - spec/factories/group.rb
244
244
  - spec/factories/user.rb
245
- - spec/lib/scim_rails/encoder_spec.rb
246
- - spec/libraries/scim_patch_operation_spec.rb
245
+ - spec/lib/scimaenaga/encoder_spec.rb
246
+ - spec/libraries/scim_patch_operation_group_spec.rb
247
+ - spec/libraries/scim_patch_operation_user_spec.rb
247
248
  - spec/libraries/scim_patch_spec.rb
248
249
  - spec/models/scim_query_parser_spec.rb
249
250
  - spec/spec_helper.rb
@@ -252,8 +253,9 @@ files:
252
253
  homepage: https://github.com/StudistCorporation/scimaenaga
253
254
  licenses:
254
255
  - MIT
255
- metadata: {}
256
- post_install_message:
256
+ metadata:
257
+ rubygems_mfa_required: 'true'
258
+ post_install_message:
257
259
  rdoc_options: []
258
260
  require_paths:
259
261
  - lib
@@ -272,90 +274,87 @@ required_rubygems_version: !ruby/object:Gem::Requirement
272
274
  version: '0'
273
275
  requirements: []
274
276
  rubygems_version: 3.0.3
275
- signing_key:
277
+ signing_key:
276
278
  specification_version: 4
277
279
  summary: SCIM Adapter for Rails.
278
280
  test_files:
279
- - spec/spec_helper.rb
280
- - spec/dummy/app/mailers/application_mailer.rb
281
- - spec/dummy/app/models/group.rb
282
- - spec/dummy/app/models/company.rb
283
- - spec/dummy/app/models/group_user.rb
284
- - spec/dummy/app/models/application_record.rb
285
- - spec/dummy/app/models/user.rb
286
- - spec/dummy/app/jobs/application_job.rb
287
- - spec/dummy/app/controllers/application_controller.rb
288
- - spec/dummy/app/views/layouts/application.html.erb
289
- - spec/dummy/app/views/layouts/mailer.html.erb
290
- - spec/dummy/app/views/layouts/mailer.text.erb
291
- - spec/dummy/app/assets/config/manifest.js
292
- - spec/dummy/app/assets/javascripts/cable.js
293
- - spec/dummy/app/assets/javascripts/application.js
294
- - spec/dummy/app/assets/stylesheets/application.css
295
- - spec/dummy/app/helpers/application_helper.rb
296
- - spec/dummy/app/channels/application_cable/connection.rb
297
- - spec/dummy/app/channels/application_cable/channel.rb
298
- - spec/dummy/bin/update
299
- - spec/dummy/bin/rake
300
- - spec/dummy/bin/setup
301
- - spec/dummy/bin/bundle
302
- - spec/dummy/bin/rails
303
- - spec/dummy/config/secrets.yml
304
- - spec/dummy/config/routes.rb
305
- - spec/dummy/config/locales/en.yml
306
- - spec/dummy/config/cable.yml
307
- - spec/dummy/config/environments/production.rb
308
- - spec/dummy/config/environments/development.rb
309
- - spec/dummy/config/environments/test.rb
281
+ - spec/dummy/config.ru
282
+ - spec/dummy/db/migrate/20181206184313_create_companies.rb
283
+ - spec/dummy/db/migrate/20181206184304_create_users.rb
284
+ - spec/dummy/db/migrate/20210423075950_create_group_users.rb
285
+ - spec/dummy/db/migrate/20210423075859_create_groups.rb
286
+ - spec/dummy/db/migrate/20220131090107_add_deletable_to_users.rb
287
+ - spec/dummy/db/migrate/20220117095407_add_country_to_users.rb
288
+ - spec/dummy/db/schema.rb
289
+ - spec/dummy/db/seeds.rb
310
290
  - spec/dummy/config/spring.rb
311
291
  - spec/dummy/config/environment.rb
312
- - spec/dummy/config/application.rb
313
- - spec/dummy/config/puma.rb
292
+ - spec/dummy/config/routes.rb
293
+ - spec/dummy/config/cable.yml
314
294
  - spec/dummy/config/database.yml
315
- - spec/dummy/config/boot.rb
316
- - spec/dummy/config/initializers/application_controller_renderer.rb
317
- - spec/dummy/config/initializers/backtrace_silencers.rb
295
+ - spec/dummy/config/secrets.yml
296
+ - spec/dummy/config/application.rb
318
297
  - spec/dummy/config/initializers/mime_types.rb
319
- - spec/dummy/config/initializers/filter_parameter_logging.rb
320
- - spec/dummy/config/initializers/session_store.rb
298
+ - spec/dummy/config/initializers/backtrace_silencers.rb
321
299
  - spec/dummy/config/initializers/wrap_parameters.rb
322
- - spec/dummy/config/initializers/new_framework_defaults.rb
323
300
  - spec/dummy/config/initializers/assets.rb
324
- - spec/dummy/config/initializers/cookies_serializer.rb
325
- - spec/dummy/config/initializers/scim_rails_config.rb
326
301
  - spec/dummy/config/initializers/inflections.rb
327
- - spec/dummy/config.ru
328
- - spec/dummy/put_group.http
302
+ - spec/dummy/config/initializers/new_framework_defaults.rb
303
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
304
+ - spec/dummy/config/initializers/session_store.rb
305
+ - spec/dummy/config/initializers/scimaenaga_config.rb
306
+ - spec/dummy/config/initializers/cookies_serializer.rb
307
+ - spec/dummy/config/initializers/application_controller_renderer.rb
308
+ - spec/dummy/config/boot.rb
309
+ - spec/dummy/config/puma.rb
310
+ - spec/dummy/config/environments/test.rb
311
+ - spec/dummy/config/environments/production.rb
312
+ - spec/dummy/config/environments/development.rb
313
+ - spec/dummy/config/locales/en.yml
314
+ - spec/dummy/app/views/layouts/mailer.html.erb
315
+ - spec/dummy/app/views/layouts/mailer.text.erb
316
+ - spec/dummy/app/views/layouts/application.html.erb
317
+ - spec/dummy/app/channels/application_cable/channel.rb
318
+ - spec/dummy/app/channels/application_cable/connection.rb
319
+ - spec/dummy/app/jobs/application_job.rb
320
+ - spec/dummy/app/assets/config/manifest.js
321
+ - spec/dummy/app/assets/javascripts/application.js
322
+ - spec/dummy/app/assets/javascripts/cable.js
323
+ - spec/dummy/app/assets/stylesheets/application.css
324
+ - spec/dummy/app/helpers/application_helper.rb
325
+ - spec/dummy/app/controllers/application_controller.rb
326
+ - spec/dummy/app/models/user.rb
327
+ - spec/dummy/app/models/group.rb
328
+ - spec/dummy/app/models/application_record.rb
329
+ - spec/dummy/app/models/group_user.rb
330
+ - spec/dummy/app/models/company.rb
331
+ - spec/dummy/app/mailers/application_mailer.rb
329
332
  - spec/dummy/Rakefile
330
- - spec/dummy/public/favicon.ico
331
- - spec/dummy/public/422.html
332
- - spec/dummy/public/apple-touch-icon.png
333
+ - spec/dummy/bin/setup
334
+ - spec/dummy/bin/rails
335
+ - spec/dummy/bin/bundle
336
+ - spec/dummy/bin/rake
337
+ - spec/dummy/bin/update
333
338
  - spec/dummy/public/500.html
334
- - spec/dummy/public/404.html
335
339
  - spec/dummy/public/apple-touch-icon-precomposed.png
336
- - spec/dummy/db/schema.rb
337
- - spec/dummy/db/seeds.rb
338
- - spec/dummy/db/test.sqlite3
339
- - spec/dummy/db/migrate/20220117095407_add_country_to_users.rb
340
- - spec/dummy/db/migrate/20220131090107_add_deletable_to_users.rb
341
- - spec/dummy/db/migrate/20181206184304_create_users.rb
342
- - spec/dummy/db/migrate/20210423075950_create_group_users.rb
343
- - spec/dummy/db/migrate/20181206184313_create_companies.rb
344
- - spec/dummy/db/migrate/20210423075859_create_groups.rb
345
- - spec/dummy/db/development.sqlite3
346
- - spec/dummy/log/test.log
347
- - spec/dummy/log/development.log
348
- - spec/dummy/tmp/restart.txt
349
- - spec/libraries/scim_patch_operation_spec.rb
350
- - spec/libraries/scim_patch_spec.rb
351
- - spec/models/scim_query_parser_spec.rb
340
+ - spec/dummy/public/favicon.ico
341
+ - spec/dummy/public/404.html
342
+ - spec/dummy/public/apple-touch-icon.png
343
+ - spec/dummy/public/422.html
352
344
  - spec/support/factory_bot.rb
353
345
  - spec/support/auth_helper.rb
346
+ - spec/lib/scimaenaga/encoder_spec.rb
347
+ - spec/controllers/scimaenaga/scim_users_controller_spec.rb
348
+ - spec/controllers/scimaenaga/scim_schemas_request_spec.rb
349
+ - spec/controllers/scimaenaga/scim_users_request_spec.rb
350
+ - spec/controllers/scimaenaga/scim_schemas_controller_spec.rb
351
+ - spec/controllers/scimaenaga/scim_groups_request_spec.rb
352
+ - spec/controllers/scimaenaga/scim_groups_controller_spec.rb
353
+ - spec/libraries/scim_patch_operation_user_spec.rb
354
+ - spec/libraries/scim_patch_spec.rb
355
+ - spec/libraries/scim_patch_operation_group_spec.rb
356
+ - spec/factories/user.rb
354
357
  - spec/factories/group.rb
355
358
  - spec/factories/company.rb
356
- - spec/factories/user.rb
357
- - spec/lib/scim_rails/encoder_spec.rb
358
- - spec/controllers/scim_rails/scim_users_request_spec.rb
359
- - spec/controllers/scim_rails/scim_users_controller_spec.rb
360
- - spec/controllers/scim_rails/scim_groups_controller_spec.rb
361
- - spec/controllers/scim_rails/scim_groups_request_spec.rb
359
+ - spec/spec_helper.rb
360
+ - spec/models/scim_query_parser_spec.rb
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ScimRails
4
- module Response
5
- CONTENT_TYPE = "application/scim+json"
6
-
7
- def json_response(object, status = :ok)
8
- render \
9
- json: object,
10
- status: status,
11
- content_type: CONTENT_TYPE
12
- end
13
-
14
- def json_scim_response(object:, status: :ok, counts: nil)
15
- case params[:action]
16
- when "index"
17
- render \
18
- json: list_response(object, counts),
19
- status: status,
20
- content_type: CONTENT_TYPE
21
- when "show", "create", "put_update", "patch_update"
22
- render \
23
- json: object_response(object),
24
- status: status,
25
- content_type: CONTENT_TYPE
26
- end
27
- end
28
-
29
- private
30
-
31
- def list_response(object, counts)
32
- object = object
33
- .order(:id)
34
- .offset(counts.offset)
35
- .limit(counts.limit)
36
- {
37
- schemas: [
38
- "urn:ietf:params:scim:api:messages:2.0:ListResponse"
39
- ],
40
- totalResults: counts.total,
41
- startIndex: counts.start_index,
42
- itemsPerPage: counts.limit,
43
- Resources: list_objects(object)
44
- }
45
- end
46
-
47
- def list_objects(objects)
48
- objects.map do |object|
49
- object_response(object)
50
- end
51
- end
52
-
53
- def object_response(object)
54
- schema = case object
55
- when ScimRails.config.scim_users_model
56
- ScimRails.config.user_schema
57
- when ScimRails.config.scim_groups_model
58
- ScimRails.config.group_schema
59
- else
60
- raise ScimRails::ExceptionHandler::InvalidQuery,
61
- "Unknown model: #{object}"
62
- end
63
- find_value(object, schema)
64
- end
65
-
66
- # `find_value` is a recursive method that takes a "user" and a
67
- # "user schema" and replaces any symbols in the schema with the
68
- # corresponding value from the user. Given a schema with symbols,
69
- # `find_value` will search through the object for the symbols,
70
- # send those symbols to the model, and replace the symbol with
71
- # the return value.
72
-
73
- def find_value(object, schema)
74
- case schema
75
- when Hash
76
- schema.each.with_object({}) do |(key, value), hash|
77
- hash[key] = find_value(object, value)
78
- end
79
- when Array, ActiveRecord::Associations::CollectionProxy
80
- schema.map do |value|
81
- find_value(object, value)
82
- end
83
- when ScimRails.config.scim_users_model
84
- find_value(schema, ScimRails.config.user_abbreviated_schema)
85
- when ScimRails.config.scim_groups_model
86
- find_value(schema, ScimRails.config.group_abbreviated_schema)
87
- when Symbol
88
- find_value(object, object.public_send(schema))
89
- else
90
- schema
91
- end
92
- end
93
- end
94
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ScimRails
4
- class ApplicationController < ActionController::API
5
- include ActionController::HttpAuthentication::Basic::ControllerMethods
6
- include ExceptionHandler
7
- include Response
8
-
9
- before_action :authorize_request
10
-
11
- private
12
-
13
- def authorize_request
14
- send(authentication_strategy) do |searchable_attribute, authentication_attribute|
15
- authorization = AuthorizeApiRequest.new(
16
- searchable_attribute: searchable_attribute,
17
- authentication_attribute: authentication_attribute
18
- )
19
- @company = authorization.company
20
- end
21
- raise ScimRails::ExceptionHandler::InvalidCredentials if @company.blank?
22
- end
23
-
24
- def authentication_strategy
25
- if request.headers["Authorization"]&.include?("Bearer")
26
- :authenticate_with_oauth_bearer
27
- else
28
- :authenticate_with_http_basic
29
- end
30
- end
31
-
32
- def authenticate_with_oauth_bearer
33
- authentication_attribute = request.headers["Authorization"].split.last
34
- payload = ScimRails::Encoder.decode(authentication_attribute).with_indifferent_access
35
- searchable_attribute = payload[ScimRails.config.basic_auth_model_searchable_attribute]
36
-
37
- yield searchable_attribute, authentication_attribute
38
- end
39
-
40
- def find_value_for(attribute)
41
- params.dig(*path_for(attribute))
42
- end
43
-
44
- # `path_for` is a recursive method used to find the "path" for
45
- # `.dig` to take when looking for a given attribute in the
46
- # params.
47
- #
48
- # Example: `path_for(:name)` should return an array that looks
49
- # like [:names, 0, :givenName]. `.dig` can then use that path
50
- # against the params to translate the :name attribute to "John".
51
-
52
- def path_for(attribute, object = controller_schema, path = [])
53
- at_path = path.empty? ? object : object.dig(*path)
54
- return path if at_path == attribute
55
-
56
- case at_path
57
- when Hash
58
- at_path.each do |key, _value|
59
- found_path = path_for(attribute, object, [*path, key])
60
- return found_path if found_path
61
- end
62
- nil
63
- when Array
64
- at_path.each_with_index do |_value, index|
65
- found_path = path_for(attribute, object, [*path, index])
66
- return found_path if found_path
67
- end
68
- nil
69
- end
70
- end
71
- end
72
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ScimRails
4
- class ScimUsersController < ScimRails::ApplicationController
5
-
6
-
7
- def index
8
- if params[:filter].present?
9
- query = ScimRails::ScimQueryParser.new(
10
- params[:filter], ScimRails.config.queryable_user_attributes
11
- )
12
-
13
- users = @company
14
- .public_send(ScimRails.config.scim_users_scope)
15
- .where(
16
- "#{ScimRails.config.scim_users_model
17
- .connection.quote_column_name(query.attribute)} #{query.operator} ?",
18
- query.parameter
19
- )
20
- .order(ScimRails.config.scim_users_list_order)
21
- else
22
- users = @company
23
- .public_send(ScimRails.config.scim_users_scope)
24
- .order(ScimRails.config.scim_users_list_order)
25
- end
26
-
27
- counts = ScimCount.new(
28
- start_index: params[:startIndex],
29
- limit: params[:count],
30
- total: users.count
31
- )
32
-
33
- json_scim_response(object: users, counts: counts)
34
- end
35
-
36
- def create
37
- if ScimRails.config.scim_user_prevent_update_on_create
38
- user = @company
39
- .public_send(ScimRails.config.scim_users_scope)
40
- .create!(permitted_user_params)
41
- else
42
- username_key = ScimRails.config.queryable_user_attributes[:userName]
43
- find_by_username = {}
44
- find_by_username[username_key] = permitted_user_params[username_key]
45
- user = @company
46
- .public_send(ScimRails.config.scim_users_scope)
47
- .find_or_create_by(find_by_username)
48
- user.update!(permitted_user_params)
49
- end
50
- json_scim_response(object: user, status: :created)
51
- end
52
-
53
-
54
-
55
- def show
56
- user = @company.public_send(ScimRails.config.scim_users_scope).find(params[:id])
57
- json_scim_response(object: user)
58
- end
59
-
60
- def put_update
61
- user = @company.public_send(ScimRails.config.scim_users_scope).find(params[:id])
62
- user.update!(permitted_user_params)
63
- json_scim_response(object: user)
64
- end
65
-
66
- def patch_update
67
- user = @company.public_send(ScimRails.config.scim_users_scope).find(params[:id])
68
- patch = ScimPatch.new(params, ScimRails.config.mutable_user_attributes_schema)
69
- patch.save(user)
70
-
71
- json_scim_response(object: user)
72
- end
73
-
74
- def destroy
75
- unless ScimRails.config.user_destroy_method
76
- raise ScimRails::ExceptionHandler::InvalidConfiguration
77
- end
78
-
79
- user = @company.public_send(ScimRails.config.scim_users_scope).find(params[:id])
80
- raise ActiveRecord::RecordNotFound unless user
81
-
82
- begin
83
- user.public_send(ScimRails.config.user_destroy_method)
84
- rescue NoMethodError => e
85
- raise ScimRails::ExceptionHandler::InvalidConfiguration, e.message
86
- rescue ActiveRecord::RecordNotDestroyed => e
87
- raise ScimRails::ExceptionHandler::InvalidRequest, e.message
88
- rescue => e
89
- raise ScimRails::ExceptionHandler::UnexpectedError, e.message
90
- end
91
-
92
- head :no_content
93
- end
94
-
95
- private
96
-
97
- def permitted_user_params
98
- ScimRails.config.mutable_user_attributes.each.with_object({}) do |attribute, hash|
99
- hash[attribute] = find_value_for(attribute)
100
- end
101
- end
102
-
103
- def controller_schema
104
- ScimRails.config.mutable_user_attributes_schema
105
- end
106
- end
107
- end
@@ -1,40 +0,0 @@
1
- module ScimRails
2
- class AuthorizeApiRequest
3
-
4
- def initialize(searchable_attribute:, authentication_attribute:)
5
- @searchable_attribute = searchable_attribute
6
- @authentication_attribute = authentication_attribute
7
-
8
- raise ScimRails::ExceptionHandler::InvalidCredentials if searchable_attribute.blank? || authentication_attribute.blank?
9
-
10
- @search_parameter = { ScimRails.config.basic_auth_model_searchable_attribute => @searchable_attribute }
11
- end
12
-
13
- def company
14
- company = find_company
15
- authorize(company)
16
- company
17
- end
18
-
19
- private
20
-
21
- attr_reader :authentication_attribute
22
- attr_reader :search_parameter
23
- attr_reader :searchable_attribute
24
-
25
- def find_company
26
- @company ||= ScimRails.config.basic_auth_model.find_by!(search_parameter)
27
-
28
- rescue ActiveRecord::RecordNotFound
29
- raise ScimRails::ExceptionHandler::InvalidCredentials
30
- end
31
-
32
- def authorize(authentication_model)
33
- authorized = ActiveSupport::SecurityUtils.secure_compare(
34
- authentication_model.public_send(ScimRails.config.basic_auth_model_authenticatable_attribute),
35
- authentication_attribute
36
- )
37
- raise ScimRails::ExceptionHandler::InvalidCredentials unless authorized
38
- end
39
- end
40
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ScimRails
4
- class ScimQueryParser
5
- attr_accessor :query_elements, :query_attributes
6
-
7
- def initialize(query_string, queryable_attributes)
8
- self.query_elements = query_string.gsub(/\[(.+?)\]/, ".0").split
9
- self.query_attributes = queryable_attributes
10
- end
11
-
12
- def attribute
13
- attribute = query_elements[0]
14
- raise ScimRails::ExceptionHandler::InvalidQuery if attribute.blank?
15
-
16
- dig_keys = attribute.split(".").map do |step|
17
- step == "0" ? 0 : step.to_sym
18
- end
19
-
20
- mapped_attribute = query_attributes.dig(*dig_keys)
21
- raise ScimRails::ExceptionHandler::InvalidQuery if mapped_attribute.blank?
22
-
23
- mapped_attribute
24
- end
25
-
26
- def operator
27
- sql_comparison_operator(query_elements[1])
28
- end
29
-
30
- def parameter
31
- parameter = query_elements[2..-1].join(" ")
32
- return if parameter.blank?
33
-
34
- parameter.gsub(/"/, "")
35
- end
36
-
37
- private
38
-
39
- def sql_comparison_operator(element)
40
- case element
41
- when "eq"
42
- "="
43
- else
44
- # TODO: implement additional query filters
45
- raise ScimRails::ExceptionHandler::InvalidQuery
46
- end
47
- end
48
- end
49
- end
@@ -1,8 +0,0 @@
1
- Description:
2
- Generates the scim_rails initializer.
3
-
4
- Example:
5
- rails generate scim_rails config
6
-
7
- This will create:
8
- config/initializers/scim_rails_config.rb