scimaenaga 0.9.0 → 0.9.1

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -8
  3. data/Rakefile +6 -8
  4. data/app/controllers/concerns/{scim_rails → scimaenaga}/exception_handler.rb +10 -10
  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 +25 -25
  8. data/app/controllers/{scim_rails → scimaenaga}/scim_schemas_controller.rb +5 -5
  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 +2 -2
  12. data/app/libraries/scim_patch_operation.rb +1 -1
  13. data/app/libraries/scim_patch_operation_group.rb +3 -3
  14. data/app/libraries/scim_patch_operation_user.rb +2 -2
  15. data/app/models/{scim_rails → scimaenaga}/application_record.rb +1 -1
  16. data/app/models/scimaenaga/authorize_api_request.rb +39 -0
  17. data/app/models/{scim_rails → scimaenaga}/scim_count.rb +8 -4
  18. data/app/models/scimaenaga/scim_query_parser.rb +49 -0
  19. data/config/routes.rb +1 -1
  20. data/lib/generators/scimaenaga/USAGE +8 -0
  21. data/lib/generators/scimaenaga/scimaenaga_generator.rb +7 -0
  22. data/lib/generators/{scim_rails → scimaenaga}/templates/initializer.rb +22 -22
  23. data/lib/{scim_rails → scimaenaga}/config.rb +2 -2
  24. data/lib/scimaenaga/encoder.rb +27 -0
  25. data/lib/scimaenaga/engine.rb +12 -0
  26. data/lib/scimaenaga/version.rb +5 -0
  27. data/lib/scimaenaga.rb +6 -0
  28. data/lib/tasks/{scim_rails_tasks.rake → scimaenaga_tasks.rake} +1 -1
  29. data/spec/controllers/{scim_rails → scimaenaga}/scim_groups_controller_spec.rb +8 -8
  30. data/spec/controllers/{scim_rails → scimaenaga}/scim_groups_request_spec.rb +18 -18
  31. data/spec/controllers/{scim_rails → scimaenaga}/scim_schemas_controller_spec.rb +7 -7
  32. data/spec/controllers/{scim_rails → scimaenaga}/scim_schemas_request_spec.rb +1 -1
  33. data/spec/controllers/{scim_rails → scimaenaga}/scim_users_controller_spec.rb +14 -15
  34. data/spec/controllers/{scim_rails → scimaenaga}/scim_users_request_spec.rb +20 -20
  35. data/spec/dummy/app/assets/config/manifest.js +1 -1
  36. data/spec/dummy/config/application.rb +1 -2
  37. data/spec/dummy/config/initializers/{scim_rails_config.rb → scimaenaga_config.rb} +1 -1
  38. data/spec/dummy/config/routes.rb +1 -1
  39. data/spec/factories/company.rb +3 -3
  40. data/spec/lib/scimaenaga/encoder_spec.rb +64 -0
  41. data/spec/libraries/scim_patch_operation_group_spec.rb +14 -14
  42. data/spec/libraries/scim_patch_operation_user_spec.rb +5 -5
  43. data/spec/libraries/scim_patch_spec.rb +2 -2
  44. data/spec/models/scim_query_parser_spec.rb +5 -6
  45. metadata +40 -39
  46. data/app/controllers/concerns/scim_rails/response.rb +0 -94
  47. data/app/controllers/scim_rails/application_controller.rb +0 -72
  48. data/app/controllers/scim_rails/scim_users_controller.rb +0 -104
  49. data/app/models/scim_rails/authorize_api_request.rb +0 -40
  50. data/app/models/scim_rails/scim_query_parser.rb +0 -49
  51. data/lib/generators/scim_rails/USAGE +0 -8
  52. data/lib/generators/scim_rails/scim_rails_generator.rb +0 -7
  53. data/lib/scim_rails/encoder.rb +0 -25
  54. data/lib/scim_rails/engine.rb +0 -12
  55. data/lib/scim_rails/version.rb +0 -5
  56. data/lib/scim_rails.rb +0 -6
  57. data/spec/lib/scim_rails/encoder_spec.rb +0 -62
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58fc798213cd88360e3f55430717995ad195c6bac873128907233e82261fa4b1
4
- data.tar.gz: 5e0e88484123fb42ffd42e1174439c88773615b4be4b1c8aa2e3f7eb38f7b8c3
3
+ metadata.gz: 41335471b09b4e09028210f9c05586a1f171cf2e6cf3d12d03b07bddd0022dc3
4
+ data.tar.gz: 12c2072c1bc4a57274cb427a4507ed2b4a13a038b9e311bfdb7e29fabc94e524
5
5
  SHA512:
6
- metadata.gz: 66e68eba027f29f0f87bb94c339356c9b6bb5dce37561f1a9f35a96fd8d34d8fc2f7fbb7d0901106b2cf66fdc7fef18cf3861c593c6795c68834e8d67793ba32
7
- data.tar.gz: 6809bbeab71b8cb0bf645ecdca6819c43e2bbfa5bf26936b8772a28fdace71b47c63b1211c5454033168b8812b4ba249c7ae0423c6a1b047faafb16b6caf69ee
6
+ metadata.gz: fc91680912294a747970e1ede984f5bbe4ad555bfacace02cc844abd6d13b124cb07f62481a6e7a7aaf1258253ca5e3d9fc83d4606cebfc44e50041dbd0e881f
7
+ data.tar.gz: 87da8ec3d1a3295d1766f13dc8474e525dc0a0c96fc4a458e79279ff48b05d7e8d628311880b10aa15925f149a59a4f54991154eeea605304df4338779dc03d3
data/README.md CHANGED
@@ -17,7 +17,7 @@ The goal of the Gem is to offer a relatively painless way of adding SCIM 2.0 to
17
17
  Add this line to your application's Gemfile:
18
18
 
19
19
  ```ruby
20
- gem 'scimaenaga', require: 'scim_rails'
20
+ gem 'scimaenaga'
21
21
  ```
22
22
 
23
23
  And then execute:
@@ -35,13 +35,13 @@ $ gem install scimaenaga
35
35
  Generate the config file with:
36
36
 
37
37
  ```bash
38
- $ rails generate scim_rails config
38
+ $ rails generate scimaenaga config
39
39
  ```
40
40
 
41
41
  The config file will be located at:
42
42
 
43
43
  ```
44
- config/initializers/scim_rails_config.rb
44
+ config/initializers/scimaenaga_config.rb
45
45
  ```
46
46
 
47
47
  Please update the config file with the models and attributes of your app.
@@ -50,7 +50,7 @@ Mount the gem in your routes file:
50
50
 
51
51
  ```ruby
52
52
  Application.routes.draw do
53
- mount ScimRails::Engine => "/"
53
+ mount Scimaenaga::Engine => "/"
54
54
  end
55
55
  ```
56
56
 
@@ -95,7 +95,7 @@ The config setting `basic_auth_model_authenticatable_attribute` is the model att
95
95
 
96
96
  Assuming the attribute is `:api_token`, generate the password using:
97
97
  ```ruby
98
- token = ScimRails::Encoder.encode(company)
98
+ token = Scimaenaga::Encoder.encode(company)
99
99
  # use the token as password for requests
100
100
  company.api_token = token # required
101
101
  company.save! # don't forget to persist the company record
@@ -119,7 +119,7 @@ In the config settings, ensure you set `signing_secret` to a secret key that wil
119
119
 
120
120
  If you have already generated the `api_token` in the "Basic Auth" section, then use that as your bearer token and ignore the steps below:
121
121
  ```ruby
122
- token = ScimRails::Encoder.encode(company)
122
+ token = Scimaenaga::Encoder.encode(company)
123
123
  # use the token as bearer token for requests
124
124
  company.api_token = token #required
125
125
  company.save! # don't forget to persist the company record
@@ -245,7 +245,7 @@ If you would like, you can supply a custom handler for exceptions in the initial
245
245
  For example, you might want to notify Honeybadger:
246
246
 
247
247
  ```ruby
248
- ScimRails.configure do |config|
248
+ Scimaenaga.configure do |config|
249
249
  config.on_error = ->(e) { Honeybadger.notify(e) }
250
250
  end
251
251
  ```
@@ -262,7 +262,7 @@ e.g.) When `userName` is defined in `mutable_user_attributes`, configure `userNa
262
262
  - corresponding with your model.
263
263
  e.g.) When `userName` must be specified configure `userName` as `required: true`
264
264
 
265
- Sample config (with comment) is written in lib/generators/scim_rails/templates/initializer.rb.
265
+ Sample config (with comment) is written in lib/generators/scimaenaga/templates/initializer.rb.
266
266
  For more details, read [Schema Definition](https://datatracker.ietf.org/doc/html/rfc7643#section-7), and [Schema Representation](https://datatracker.ietf.org/doc/html/rfc7643#section-8.7)
267
267
 
268
268
  ## Contributing
data/Rakefile CHANGED
@@ -8,27 +8,25 @@ require 'rdoc/task'
8
8
 
9
9
  RDoc::Task.new(:rdoc) do |rdoc|
10
10
  rdoc.rdoc_dir = 'rdoc'
11
- rdoc.title = 'ScimRails'
11
+ rdoc.title = 'Scimaenaga'
12
12
  rdoc.options << '--line-numbers'
13
13
  rdoc.rdoc_files.include('README.md')
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
17
- APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
17
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
-
21
20
  load 'rails/tasks/statistics.rake'
22
21
 
23
-
24
22
  Bundler::GemHelper.install_tasks
25
23
 
26
- Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
24
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each { |f| load f }
27
25
 
28
26
  require 'rspec/core'
29
27
  require 'rspec/core/rake_task'
30
28
 
31
- desc "Run all specs in spec directory (excluding plugin specs)"
32
- RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
29
+ desc 'Run all specs in spec directory (excluding plugin specs)'
30
+ RSpec::Core::RakeTask.new(spec: 'app:db:test:prepare')
33
31
 
34
- task :default => :spec
32
+ task default: :spec
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ScimRails
3
+ module Scimaenaga
4
4
  module ExceptionHandler
5
5
  extend ActiveSupport::Concern
6
6
 
@@ -37,7 +37,7 @@ module ScimRails
37
37
  included do
38
38
  if Rails.env.production?
39
39
  rescue_from StandardError do |exception|
40
- on_error = ScimRails.config.on_error
40
+ on_error = Scimaenaga.config.on_error
41
41
  if on_error.respond_to?(:call)
42
42
  on_error.call(exception)
43
43
  else
@@ -54,7 +54,7 @@ module ScimRails
54
54
  end
55
55
  end
56
56
 
57
- rescue_from ScimRails::ExceptionHandler::InvalidCredentials do
57
+ rescue_from Scimaenaga::ExceptionHandler::InvalidCredentials do
58
58
  json_response(
59
59
  {
60
60
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -65,7 +65,7 @@ module ScimRails
65
65
  )
66
66
  end
67
67
 
68
- rescue_from ScimRails::ExceptionHandler::InvalidRequest do |e|
68
+ rescue_from Scimaenaga::ExceptionHandler::InvalidRequest do |e|
69
69
  json_response(
70
70
  {
71
71
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -76,7 +76,7 @@ module ScimRails
76
76
  )
77
77
  end
78
78
 
79
- rescue_from ScimRails::ExceptionHandler::InvalidQuery do
79
+ rescue_from Scimaenaga::ExceptionHandler::InvalidQuery do
80
80
  json_response(
81
81
  {
82
82
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -88,7 +88,7 @@ module ScimRails
88
88
  )
89
89
  end
90
90
 
91
- rescue_from ScimRails::ExceptionHandler::UnsupportedPatchRequest do
91
+ rescue_from Scimaenaga::ExceptionHandler::UnsupportedPatchRequest do
92
92
  json_response(
93
93
  {
94
94
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -99,7 +99,7 @@ module ScimRails
99
99
  )
100
100
  end
101
101
 
102
- rescue_from ScimRails::ExceptionHandler::UnsupportedDeleteRequest do
102
+ rescue_from Scimaenaga::ExceptionHandler::UnsupportedDeleteRequest do
103
103
  json_response(
104
104
  {
105
105
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -110,7 +110,7 @@ module ScimRails
110
110
  )
111
111
  end
112
112
 
113
- rescue_from ScimRails::ExceptionHandler::InvalidConfiguration do |e|
113
+ rescue_from Scimaenaga::ExceptionHandler::InvalidConfiguration do |e|
114
114
  json_response(
115
115
  {
116
116
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -121,7 +121,7 @@ module ScimRails
121
121
  )
122
122
  end
123
123
 
124
- rescue_from ScimRails::ExceptionHandler::UnexpectedError do |e|
124
+ rescue_from Scimaenaga::ExceptionHandler::UnexpectedError do |e|
125
125
  json_response(
126
126
  {
127
127
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -133,7 +133,7 @@ module ScimRails
133
133
  end
134
134
 
135
135
  rescue_from ActiveRecord::RecordNotFound,
136
- ScimRails::ExceptionHandler::ResourceNotFound do |e|
136
+ Scimaenaga::ExceptionHandler::ResourceNotFound do |e|
137
137
  json_response(
138
138
  {
139
139
  schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scimaenaga
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 Scimaenaga.config.scim_users_model
56
+ Scimaenaga.config.user_schema
57
+ when Scimaenaga.config.scim_groups_model
58
+ Scimaenaga.config.group_schema
59
+ else
60
+ raise Scimaenaga::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 Scimaenaga.config.scim_users_model
84
+ find_value(schema, Scimaenaga.config.user_abbreviated_schema)
85
+ when Scimaenaga.config.scim_groups_model
86
+ find_value(schema, Scimaenaga.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
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scimaenaga
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 Scimaenaga::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 = Scimaenaga::Encoder.decode(authentication_attribute).with_indifferent_access
35
+ searchable_attribute = payload[Scimaenaga.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,27 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ScimRails
4
- class ScimGroupsController < ScimRails::ApplicationController
3
+ module Scimaenaga
4
+ class ScimGroupsController < Scimaenaga::ApplicationController
5
5
  def index
6
6
  if params[:filter].present?
7
- query = ScimRails::ScimQueryParser.new(
8
- params[:filter], ScimRails.config.queryable_group_attributes
7
+ query = Scimaenaga::ScimQueryParser.new(
8
+ params[:filter], Scimaenaga.config.queryable_group_attributes
9
9
  )
10
10
 
11
11
  groups = @company
12
- .public_send(ScimRails.config.scim_groups_scope)
12
+ .public_send(Scimaenaga.config.scim_groups_scope)
13
13
  .where(
14
- "#{ScimRails.config.scim_groups_model
14
+ "#{Scimaenaga.config.scim_groups_model
15
15
  .connection.quote_column_name(query.attribute)}
16
16
  #{query.operator} ?",
17
17
  query.parameter
18
18
  )
19
- .order(ScimRails.config.scim_groups_list_order)
19
+ .order(Scimaenaga.config.scim_groups_list_order)
20
20
  else
21
21
  groups = @company
22
- .public_send(ScimRails.config.scim_groups_scope)
22
+ .public_send(Scimaenaga.config.scim_groups_scope)
23
23
  .preload(:users)
24
- .order(ScimRails.config.scim_groups_list_order)
24
+ .order(Scimaenaga.config.scim_groups_list_order)
25
25
  end
26
26
 
27
27
  counts = ScimCount.new(
@@ -35,14 +35,14 @@ module ScimRails
35
35
 
36
36
  def show
37
37
  group = @company
38
- .public_send(ScimRails.config.scim_groups_scope)
38
+ .public_send(Scimaenaga.config.scim_groups_scope)
39
39
  .find(params[:id])
40
40
  json_scim_response(object: group)
41
41
  end
42
42
 
43
43
  def create
44
44
  group = @company
45
- .public_send(ScimRails.config.scim_groups_scope)
45
+ .public_send(Scimaenaga.config.scim_groups_scope)
46
46
  .create!(permitted_group_params)
47
47
 
48
48
  json_scim_response(object: group, status: :created)
@@ -50,7 +50,7 @@ module ScimRails
50
50
 
51
51
  def put_update
52
52
  group = @company
53
- .public_send(ScimRails.config.scim_groups_scope)
53
+ .public_send(Scimaenaga.config.scim_groups_scope)
54
54
  .find(params[:id])
55
55
  group.update!(permitted_group_params)
56
56
  json_scim_response(object: group)
@@ -58,7 +58,7 @@ module ScimRails
58
58
 
59
59
  def patch_update
60
60
  group = @company
61
- .public_send(ScimRails.config.scim_groups_scope)
61
+ .public_send(Scimaenaga.config.scim_groups_scope)
62
62
  .find(params[:id])
63
63
  patch = ScimPatch.new(params, :group)
64
64
  patch.save(group)
@@ -67,23 +67,23 @@ module ScimRails
67
67
  end
68
68
 
69
69
  def destroy
70
- unless ScimRails.config.group_destroy_method
71
- raise ScimRails::ExceptionHandler::InvalidConfiguration
70
+ unless Scimaenaga.config.group_destroy_method
71
+ raise Scimaenaga::ExceptionHandler::InvalidConfiguration
72
72
  end
73
73
 
74
74
  group = @company
75
- .public_send(ScimRails.config.scim_groups_scope)
75
+ .public_send(Scimaenaga.config.scim_groups_scope)
76
76
  .find(params[:id])
77
77
  raise ActiveRecord::RecordNotFound unless group
78
78
 
79
79
  begin
80
- group.public_send(ScimRails.config.group_destroy_method)
80
+ group.public_send(Scimaenaga.config.group_destroy_method)
81
81
  rescue NoMethodError => e
82
- raise ScimRails::ExceptionHandler::InvalidConfiguration, e.message
82
+ raise Scimaenaga::ExceptionHandler::InvalidConfiguration, e.message
83
83
  rescue ActiveRecord::RecordNotDestroyed => e
84
- raise ScimRails::ExceptionHandler::InvalidRequest, e.message
85
- rescue => e
86
- raise ScimRails::ExceptionHandler::UnexpectedError, e.message
84
+ raise Scimaenaga::ExceptionHandler::InvalidRequest, e.message
85
+ rescue StandardError => e
86
+ raise Scimaenaga::ExceptionHandler::UnexpectedError, e.message
87
87
  end
88
88
 
89
89
  head :no_content
@@ -102,19 +102,19 @@ module ScimRails
102
102
 
103
103
  def member_params
104
104
  {
105
- ScimRails.config.group_member_relation_attribute =>
105
+ Scimaenaga.config.group_member_relation_attribute =>
106
106
  params[:members].map do |member|
107
- member[ScimRails.config.group_member_relation_schema.keys.first]
107
+ member[Scimaenaga.config.group_member_relation_schema.keys.first]
108
108
  end,
109
109
  }
110
110
  end
111
111
 
112
112
  def mutable_attributes
113
- ScimRails.config.mutable_group_attributes
113
+ Scimaenaga.config.mutable_group_attributes
114
114
  end
115
115
 
116
116
  def controller_schema
117
- ScimRails.config.mutable_group_attributes_schema
117
+ Scimaenaga.config.mutable_group_attributes_schema
118
118
  end
119
119
  end
120
120
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ScimRails
4
- class ScimSchemasController < ScimRails::ApplicationController
3
+ module Scimaenaga
4
+ class ScimSchemasController < Scimaenaga::ApplicationController
5
5
  def index
6
- schemas = ScimRails.config.schemas
6
+ schemas = Scimaenaga.config.schemas
7
7
 
8
8
  counts = ScimCount.new(
9
9
  start_index: params[:startIndex],
@@ -15,11 +15,11 @@ module ScimRails
15
15
  end
16
16
 
17
17
  def show
18
- schema = ScimRails.config.schemas.find do |s|
18
+ schema = Scimaenaga.config.schemas.find do |s|
19
19
  s[:id] == params[:id]
20
20
  end
21
21
 
22
- raise ScimRails::ExceptionHandler::ResourceNotFound, params[:id] if schema.nil?
22
+ raise Scimaenaga::ExceptionHandler::ResourceNotFound, params[:id] if schema.nil?
23
23
 
24
24
  json_response(schema)
25
25
  end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scimaenaga
4
+ class ScimUsersController < Scimaenaga::ApplicationController
5
+
6
+ def index
7
+ if params[:filter].present?
8
+ query = Scimaenaga::ScimQueryParser.new(
9
+ params[:filter], Scimaenaga.config.queryable_user_attributes
10
+ )
11
+
12
+ users = @company
13
+ .public_send(Scimaenaga.config.scim_users_scope)
14
+ .where(
15
+ "#{Scimaenaga.config.scim_users_model
16
+ .connection.quote_column_name(query.attribute)} #{query.operator} ?",
17
+ query.parameter
18
+ )
19
+ .order(Scimaenaga.config.scim_users_list_order)
20
+ else
21
+ users = @company
22
+ .public_send(Scimaenaga.config.scim_users_scope)
23
+ .order(Scimaenaga.config.scim_users_list_order)
24
+ end
25
+
26
+ counts = ScimCount.new(
27
+ start_index: params[:startIndex],
28
+ limit: params[:count],
29
+ total: users.count
30
+ )
31
+
32
+ json_scim_response(object: users, counts: counts)
33
+ end
34
+
35
+ def create
36
+ if Scimaenaga.config.scim_user_prevent_update_on_create
37
+ user = @company
38
+ .public_send(Scimaenaga.config.scim_users_scope)
39
+ .create!(permitted_user_params)
40
+ else
41
+ username_key = Scimaenaga.config.queryable_user_attributes[:userName]
42
+ find_by_username = {}
43
+ find_by_username[username_key] = permitted_user_params[username_key]
44
+ user = @company
45
+ .public_send(Scimaenaga.config.scim_users_scope)
46
+ .find_or_create_by(find_by_username)
47
+ user.update!(permitted_user_params)
48
+ end
49
+ json_scim_response(object: user, status: :created)
50
+ end
51
+
52
+ def show
53
+ user = @company.public_send(Scimaenaga.config.scim_users_scope).find(params[:id])
54
+ json_scim_response(object: user)
55
+ end
56
+
57
+ def put_update
58
+ user = @company.public_send(Scimaenaga.config.scim_users_scope).find(params[:id])
59
+ user.update!(permitted_user_params)
60
+ json_scim_response(object: user)
61
+ end
62
+
63
+ def patch_update
64
+ user = @company.public_send(Scimaenaga.config.scim_users_scope).find(params[:id])
65
+ patch = ScimPatch.new(params, :user)
66
+ patch.save(user)
67
+
68
+ json_scim_response(object: user)
69
+ end
70
+
71
+ def destroy
72
+ unless Scimaenaga.config.user_destroy_method
73
+ raise Scimaenaga::ExceptionHandler::InvalidConfiguration
74
+ end
75
+
76
+ user = @company.public_send(Scimaenaga.config.scim_users_scope).find(params[:id])
77
+ raise ActiveRecord::RecordNotFound unless user
78
+
79
+ begin
80
+ user.public_send(Scimaenaga.config.user_destroy_method)
81
+ rescue NoMethodError => e
82
+ raise Scimaenaga::ExceptionHandler::InvalidConfiguration, e.message
83
+ rescue ActiveRecord::RecordNotDestroyed => e
84
+ raise Scimaenaga::ExceptionHandler::InvalidRequest, e.message
85
+ rescue StandardError => e
86
+ raise Scimaenaga::ExceptionHandler::UnexpectedError, e.message
87
+ end
88
+
89
+ head :no_content
90
+ end
91
+
92
+ private
93
+
94
+ def permitted_user_params
95
+ Scimaenaga.config.mutable_user_attributes.each.with_object({}) do |attribute, hash|
96
+ hash[attribute] = find_value_for(attribute)
97
+ end
98
+ end
99
+
100
+ def controller_schema
101
+ Scimaenaga.config.mutable_user_attributes_schema
102
+ end
103
+ end
104
+ end
@@ -1,4 +1,4 @@
1
- module ScimRails
1
+ module Scimaenaga
2
2
  module ApplicationHelper
3
3
  end
4
4
  end
@@ -7,7 +7,7 @@ class ScimPatch
7
7
  def initialize(params, resource_type)
8
8
  if params['schemas'] != ['urn:ietf:params:scim:api:messages:2.0:PatchOp'] ||
9
9
  params['Operations'].nil?
10
- raise ScimRails::ExceptionHandler::UnsupportedPatchRequest
10
+ raise Scimaenaga::ExceptionHandler::UnsupportedPatchRequest
11
11
  end
12
12
 
13
13
  # complex-value(Hash) operation is converted to multiple single-value operations
@@ -35,6 +35,6 @@ class ScimPatch
35
35
  rescue ActiveRecord::RecordNotFound
36
36
  raise
37
37
  rescue StandardError
38
- raise ScimRails::ExceptionHandler::UnsupportedPatchRequest
38
+ raise Scimaenaga::ExceptionHandler::UnsupportedPatchRequest
39
39
  end
40
40
  end
@@ -10,7 +10,7 @@ class ScimPatchOperation
10
10
  # complex-value(Hash) is converted to multiple single-value operations by ScimPatchOperationConverter
11
11
  def initialize(op, path, value)
12
12
  if !op.in?(%w[add replace remove]) || path.nil?
13
- raise ScimRails::ExceptionHandler::UnsupportedPatchRequest
13
+ raise Scimaenaga::ExceptionHandler::UnsupportedPatchRequest
14
14
  end
15
15
 
16
16
  # define validate method in the inherited class