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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d2d55daa03a9b1e4771b1f2e1287a75075514d57faeb0075ea8784a7dd8cc9e
4
- data.tar.gz: b4a38c2c629cce871703a2a1874c3be93e34d55f0d5eacadae8da9b8c5e5c438
3
+ metadata.gz: 41335471b09b4e09028210f9c05586a1f171cf2e6cf3d12d03b07bddd0022dc3
4
+ data.tar.gz: 12c2072c1bc4a57274cb427a4507ed2b4a13a038b9e311bfdb7e29fabc94e524
5
5
  SHA512:
6
- metadata.gz: 43e2ec416e2f9bad5c185042aff3e6fd576437d3d9bff5ac6ad5d1f930246fa0b59b12e1940a5498e386c8c8f385a245d531907e7ab5850cc8ebc5a7c35df607
7
- data.tar.gz: 284bead26bc660ca0d4cc229dd5f13102501904b7658e3e780f5ea5657eb367c52cd5399d4a29dcd20af66eee19ce4592af7defa62c2f182bb7b23f76ebe6a31
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,11 +245,26 @@ 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
  ```
252
252
 
253
+ ### Schemas endpoint
254
+
255
+ If you need Schemas endpoint configure `schemas`.
256
+ (Azure AD requires Schemas endpoint when registering to Application Gallery.)
257
+
258
+ You have to configure `schemas` as
259
+ - corresponding with other configurations.
260
+ e.g.) When `userName` is defined in `mutable_user_attributes`, configure `userName` as `mutability: 'readWrite'`.
261
+
262
+ - corresponding with your model.
263
+ e.g.) When `userName` must be specified configure `userName` as `required: true`
264
+
265
+ Sample config (with comment) is written in lib/generators/scimaenaga/templates/initializer.rb.
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
+
253
268
  ## Contributing
254
269
 
255
270
  ### [Code of Conduct](https://github.com/StudistCorporation/scimaenaga/blob/master/CODE_OF_CONDUCT.md)
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
 
@@ -25,10 +25,19 @@ module ScimRails
25
25
  class UnexpectedError < StandardError
26
26
  end
27
27
 
28
+ class ResourceNotFound < StandardError
29
+ attr_reader :id
30
+
31
+ def initialize(id)
32
+ super
33
+ @id = id
34
+ end
35
+ end
36
+
28
37
  included do
29
38
  if Rails.env.production?
30
39
  rescue_from StandardError do |exception|
31
- on_error = ScimRails.config.on_error
40
+ on_error = Scimaenaga.config.on_error
32
41
  if on_error.respond_to?(:call)
33
42
  on_error.call(exception)
34
43
  else
@@ -37,98 +46,99 @@ module ScimRails
37
46
 
38
47
  json_response(
39
48
  {
40
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
41
- status: "500"
49
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
50
+ status: '500',
42
51
  },
43
52
  :internal_server_error
44
53
  )
45
54
  end
46
55
  end
47
56
 
48
- rescue_from ScimRails::ExceptionHandler::InvalidCredentials do
57
+ rescue_from Scimaenaga::ExceptionHandler::InvalidCredentials do
49
58
  json_response(
50
59
  {
51
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
52
- detail: "Authorization failure. The authorization header is invalid or missing.",
53
- status: "401"
60
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
61
+ detail: 'Authorization failure. The authorization header is invalid or missing.',
62
+ status: '401',
54
63
  },
55
64
  :unauthorized
56
65
  )
57
66
  end
58
67
 
59
- rescue_from ScimRails::ExceptionHandler::InvalidRequest do |e|
68
+ rescue_from Scimaenaga::ExceptionHandler::InvalidRequest do |e|
60
69
  json_response(
61
70
  {
62
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
71
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
63
72
  detail: "Invalid request. #{e.message}",
64
- status: "400"
73
+ status: '400',
65
74
  },
66
75
  :bad_request
67
76
  )
68
77
  end
69
78
 
70
- rescue_from ScimRails::ExceptionHandler::InvalidQuery do
79
+ rescue_from Scimaenaga::ExceptionHandler::InvalidQuery do
71
80
  json_response(
72
81
  {
73
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
74
- scimType: "invalidFilter",
75
- detail: "The specified filter syntax was invalid, or the specified attribute and filter comparison combination is not supported.",
76
- status: "400"
82
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
83
+ scimType: 'invalidFilter',
84
+ detail: 'The specified filter syntax was invalid, or the specified attribute and filter comparison combination is not supported.',
85
+ status: '400',
77
86
  },
78
87
  :bad_request
79
88
  )
80
89
  end
81
90
 
82
- rescue_from ScimRails::ExceptionHandler::UnsupportedPatchRequest do
91
+ rescue_from Scimaenaga::ExceptionHandler::UnsupportedPatchRequest do
83
92
  json_response(
84
93
  {
85
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
86
- detail: "Invalid PATCH request.",
87
- status: "422"
94
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
95
+ detail: 'Invalid PATCH request.',
96
+ status: '422',
88
97
  },
89
98
  :unprocessable_entity
90
99
  )
91
100
  end
92
101
 
93
- rescue_from ScimRails::ExceptionHandler::UnsupportedDeleteRequest do
102
+ rescue_from Scimaenaga::ExceptionHandler::UnsupportedDeleteRequest do
94
103
  json_response(
95
104
  {
96
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
97
- detail: "Delete operation is disabled for the requested resource.",
98
- status: "501"
105
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
106
+ detail: 'Delete operation is disabled for the requested resource.',
107
+ status: '501',
99
108
  },
100
109
  :not_implemented
101
110
  )
102
111
  end
103
112
 
104
- rescue_from ScimRails::ExceptionHandler::InvalidConfiguration do |e|
113
+ rescue_from Scimaenaga::ExceptionHandler::InvalidConfiguration do |e|
105
114
  json_response(
106
115
  {
107
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
116
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
108
117
  detail: "Invalid configuration. #{e.message}",
109
- status: "500"
118
+ status: '500',
110
119
  },
111
120
  :internal_server_error
112
121
  )
113
122
  end
114
123
 
115
- rescue_from ScimRails::ExceptionHandler::UnexpectedError do |e|
124
+ rescue_from Scimaenaga::ExceptionHandler::UnexpectedError do |e|
116
125
  json_response(
117
126
  {
118
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
127
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
119
128
  detail: "Unexpected Error. #{e.message}",
120
- status: "500"
129
+ status: '500',
121
130
  },
122
131
  :internal_server_error
123
132
  )
124
133
  end
125
134
 
126
- rescue_from ActiveRecord::RecordNotFound do |e|
135
+ rescue_from ActiveRecord::RecordNotFound,
136
+ Scimaenaga::ExceptionHandler::ResourceNotFound do |e|
127
137
  json_response(
128
138
  {
129
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
139
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
130
140
  detail: "Resource #{e.id} not found.",
131
- status: "404"
141
+ status: '404',
132
142
  },
133
143
  :not_found
134
144
  )
@@ -139,18 +149,18 @@ module ScimRails
139
149
  when /has already been taken/
140
150
  json_response(
141
151
  {
142
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
152
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
143
153
  detail: e.message,
144
- status: "409"
154
+ status: '409',
145
155
  },
146
156
  :conflict
147
157
  )
148
158
  else
149
159
  json_response(
150
160
  {
151
- schemas: ["urn:ietf:params:scim:api:messages:2.0:Error"],
161
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:Error'],
152
162
  detail: e.message,
153
- status: "422"
163
+ status: '422',
154
164
  },
155
165
  :unprocessable_entity
156
166
  )
@@ -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,32 +58,32 @@ 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
- patch = ScimPatch.new(params, ScimRails.config.mutable_group_attributes_schema)
63
+ patch = ScimPatch.new(params, :group)
64
64
  patch.save(group)
65
65
 
66
66
  json_scim_response(object: group)
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
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scimaenaga
4
+ class ScimSchemasController < Scimaenaga::ApplicationController
5
+ def index
6
+ schemas = Scimaenaga.config.schemas
7
+
8
+ counts = ScimCount.new(
9
+ start_index: params[:startIndex],
10
+ limit: params[:count],
11
+ total: schemas.count
12
+ )
13
+
14
+ list_schemas_response(schemas, counts)
15
+ end
16
+
17
+ def show
18
+ schema = Scimaenaga.config.schemas.find do |s|
19
+ s[:id] == params[:id]
20
+ end
21
+
22
+ raise Scimaenaga::ExceptionHandler::ResourceNotFound, params[:id] if schema.nil?
23
+
24
+ json_response(schema)
25
+ end
26
+
27
+ private
28
+
29
+ def list_schemas_response(schemas, counts)
30
+ response = {
31
+ schemas: [
32
+ 'urn:ietf:params:scim:api:messages:2.0:ListResponse'
33
+ ],
34
+ totalResults: counts.total,
35
+ startIndex: counts.start_index,
36
+ itemsPerPage: counts.limit,
37
+ Resources: schemas[counts.offset...counts.offset + counts.limit],
38
+ }
39
+ json_response(response)
40
+ end
41
+ end
42
+ end