scimaenaga 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
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