scimitar 2.5.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/scimitar/active_record_backed_resources_controller.rb +21 -4
- data/app/controllers/scimitar/schemas_controller.rb +5 -0
- data/app/models/scimitar/resources/base.rb +12 -2
- data/app/models/scimitar/schema/attribute.rb +12 -3
- data/app/models/scimitar/schema/base.rb +1 -1
- data/config/initializers/scimitar.rb +9 -4
- data/lib/scimitar/version.rb +2 -2
- data/spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb +24 -0
- data/spec/apps/dummy/app/models/mock_user.rb +2 -0
- data/spec/apps/dummy/config/initializers/scimitar.rb +8 -0
- data/spec/apps/dummy/config/routes.rb +5 -0
- data/spec/apps/dummy/db/migrate/20210304014602_create_mock_users.rb +1 -0
- data/spec/apps/dummy/db/schema.rb +2 -1
- data/spec/controllers/scimitar/resource_types_controller_spec.rb +2 -2
- data/spec/controllers/scimitar/schemas_controller_spec.rb +8 -0
- data/spec/models/scimitar/resources/base_spec.rb +38 -4
- data/spec/models/scimitar/resources/mixin_spec.rb +4 -1
- data/spec/models/scimitar/schema/attribute_spec.rb +22 -0
- data/spec/requests/active_record_backed_resources_controller_spec.rb +16 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13a1cc0fad873f6524c65d4d24c6556d22b75abcd13ecdbb422d074a8ce94afc
|
4
|
+
data.tar.gz: 9244ab9bcf9f32b3a8e9b6b16653c92f0e7a228320f7c3fefe751e7bee290372
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc24687beb3d360e5b548b617b699a9b0a6384f3b1477336b18a95fc4647d1364727dd4bf66984a05efc7d06210689a7ad33f662c82ff42b81abae4e1aa26584
|
7
|
+
data.tar.gz: 9291068aae0c3eb047eedaaf9d2d7587aa49bfd7703b8d4db0235a15a43b2d8d0e3ddeaf5784f432f3f0df0edb6bc8099e85d1eb5937ca262399634d3fc51965
|
@@ -153,7 +153,13 @@ module Scimitar
|
|
153
153
|
# Save a record, dealing with validation exceptions by raising SCIM
|
154
154
|
# errors.
|
155
155
|
#
|
156
|
-
# +record+:: ActiveRecord subclass to save
|
156
|
+
# +record+:: ActiveRecord subclass to save.
|
157
|
+
#
|
158
|
+
# If you just let this superclass handle things, it'll call the standard
|
159
|
+
# +#save!+ method on the record. If you pass a block, then this block is
|
160
|
+
# invoked and passed the ActiveRecord model instance to be saved. You can
|
161
|
+
# then do things like calling a different method, using a service object of
|
162
|
+
# some kind, perform audit-related operations and so-on.
|
157
163
|
#
|
158
164
|
# The return value is not used internally, making life easier for
|
159
165
|
# overriding subclasses to "do the right thing" / avoid mistakes (instead
|
@@ -161,10 +167,21 @@ module Scimitar
|
|
161
167
|
# and relying upon this to generate correct response payloads - an early
|
162
168
|
# version of the gem did this and it caused a confusing subclass bug).
|
163
169
|
#
|
164
|
-
def save!(record)
|
165
|
-
|
166
|
-
|
170
|
+
def save!(record, &block)
|
171
|
+
if block_given?
|
172
|
+
yield(record)
|
173
|
+
else
|
174
|
+
record.save!
|
175
|
+
end
|
167
176
|
rescue ActiveRecord::RecordInvalid => exception
|
177
|
+
handle_invalid_record(exception.record)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Deal with validation errors by responding with an appropriate SCIM error.
|
181
|
+
#
|
182
|
+
# +record+:: The record with validation errors.
|
183
|
+
#
|
184
|
+
def handle_invalid_record(record)
|
168
185
|
joined_errors = record.errors.full_messages.join('; ')
|
169
186
|
|
170
187
|
# https://tools.ietf.org/html/rfc7644#page-12
|
@@ -4,6 +4,11 @@ module Scimitar
|
|
4
4
|
class SchemasController < ApplicationController
|
5
5
|
def index
|
6
6
|
schemas = Scimitar::Engine.schemas
|
7
|
+
|
8
|
+
schemas.each do |schema|
|
9
|
+
schema.meta.location = scim_schemas_url(name: schema.id)
|
10
|
+
end
|
11
|
+
|
7
12
|
schemas_by_id = schemas.reduce({}) do |hash, schema|
|
8
13
|
hash[schema.id] = schema
|
9
14
|
hash
|
@@ -139,13 +139,23 @@ module Scimitar
|
|
139
139
|
|
140
140
|
def as_json(options = {})
|
141
141
|
self.meta = Meta.new unless self.meta && self.meta.is_a?(Meta)
|
142
|
-
meta.resourceType = self.class.resource_type_id
|
143
|
-
|
142
|
+
self.meta.resourceType = self.class.resource_type_id
|
143
|
+
|
144
|
+
non_returnable_attributes = self.class
|
145
|
+
.schemas
|
146
|
+
.flat_map(&:scim_attributes)
|
147
|
+
.filter_map { |attribute| attribute.name if attribute.returned == 'never' }
|
148
|
+
|
149
|
+
non_returnable_attributes << 'errors'
|
150
|
+
|
151
|
+
original_hash = super(options).except(*non_returnable_attributes)
|
144
152
|
original_hash.merge!('schemas' => self.class.schemas.map(&:id))
|
153
|
+
|
145
154
|
self.class.extended_schemas.each do |extension_schema|
|
146
155
|
extension_attributes = extension_schema.scim_attributes.map(&:name)
|
147
156
|
original_hash.merge!(extension_schema.id => original_hash.extract!(*extension_attributes))
|
148
157
|
end
|
158
|
+
|
149
159
|
original_hash
|
150
160
|
end
|
151
161
|
|
@@ -93,12 +93,21 @@ module Scimitar
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def valid_simple_type?(value)
|
96
|
-
|
96
|
+
if multiValued
|
97
|
+
valid = value.is_a?(Array) && value.all? { |v| simple_type?(v) }
|
98
|
+
errors.add(self.name, "or one of its elements has the wrong type. It has to be an array of #{self.type}s.") unless valid
|
99
|
+
else
|
100
|
+
valid = simple_type?(value)
|
101
|
+
errors.add(self.name, "has the wrong type. It has to be a(n) #{self.type}.") unless valid
|
102
|
+
end
|
103
|
+
valid
|
104
|
+
end
|
105
|
+
|
106
|
+
def simple_type?(value)
|
107
|
+
(type == 'string' && value.is_a?(String)) ||
|
97
108
|
(type == 'boolean' && (value.is_a?(TrueClass) || value.is_a?(FalseClass))) ||
|
98
109
|
(type == 'integer' && (value.is_a?(Integer))) ||
|
99
110
|
(type == 'dateTime' && valid_date_time?(value))
|
100
|
-
errors.add(self.name, "has the wrong type. It has to be a(n) #{self.type}.") unless valid
|
101
|
-
valid
|
102
111
|
end
|
103
112
|
|
104
113
|
def valid_date_time?(value)
|
@@ -13,7 +13,7 @@ module Scimitar
|
|
13
13
|
|
14
14
|
# Converts the schema to its json representation that will be returned by /SCHEMAS end-point of a SCIM service provider.
|
15
15
|
def as_json(options = {})
|
16
|
-
@meta.location
|
16
|
+
@meta.location ||= Scimitar::Engine.routes.url_helpers.scim_schemas_path(name: id)
|
17
17
|
original = super
|
18
18
|
original.merge('attributes' => original.delete('scim_attributes'))
|
19
19
|
end
|
@@ -37,10 +37,11 @@ Rails.application.config.to_prepare do # (required for >= Rails 7 / Zeitwerk)
|
|
37
37
|
#
|
38
38
|
Scimitar.engine_configuration = Scimitar::EngineConfiguration.new({
|
39
39
|
|
40
|
-
# If you have filters you want to run for any Scimitar action/route, you
|
41
|
-
#
|
42
|
-
#
|
43
|
-
# verification
|
40
|
+
# If you have filters you want to run for any Scimitar action/route, you can
|
41
|
+
# define them here. You can also override any shared controller methods
|
42
|
+
# here. For example, you might use a before-action to set up some
|
43
|
+
# multi-tenancy related state, skip Rails CSRF token verification, or
|
44
|
+
# customize how Scimitar generates URLs:
|
44
45
|
#
|
45
46
|
# application_controller_mixin: Module.new do
|
46
47
|
# def self.included(base)
|
@@ -54,6 +55,10 @@ Rails.application.config.to_prepare do # (required for >= Rails 7 / Zeitwerk)
|
|
54
55
|
# prepend_before_action :setup_some_kind_of_multi_tenancy_data
|
55
56
|
# end
|
56
57
|
# end
|
58
|
+
#
|
59
|
+
# def scim_schemas_url(options)
|
60
|
+
# super(custom_param: 'value', **options)
|
61
|
+
# end
|
57
62
|
# end, # ...other configuration entries might follow...
|
58
63
|
|
59
64
|
# If you want to support username/password authentication:
|
data/lib/scimitar/version.rb
CHANGED
@@ -3,11 +3,11 @@ module Scimitar
|
|
3
3
|
# Gem version. If this changes, be sure to re-run "bundle install" or
|
4
4
|
# "bundle update".
|
5
5
|
#
|
6
|
-
VERSION = '2.
|
6
|
+
VERSION = '2.6.0'
|
7
7
|
|
8
8
|
# Date for VERSION. If this changes, be sure to re-run "bundle install"
|
9
9
|
# or "bundle update".
|
10
10
|
#
|
11
|
-
DATE = '2023-
|
11
|
+
DATE = '2023-11-14'
|
12
12
|
|
13
13
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# For tests only - uses custom 'save!' implementation which passes a block to
|
2
|
+
# Scimitar::ActiveRecordBackedResourcesController#save!.
|
3
|
+
#
|
4
|
+
class CustomSaveMockUsersController < Scimitar::ActiveRecordBackedResourcesController
|
5
|
+
|
6
|
+
CUSTOM_SAVE_BLOCK_USERNAME_INDICATOR = 'Custom save-block invoked'
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def save!(_record)
|
11
|
+
super do | record |
|
12
|
+
record.update!(username: CUSTOM_SAVE_BLOCK_USERNAME_INDICATOR)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def storage_class
|
17
|
+
MockUser
|
18
|
+
end
|
19
|
+
|
20
|
+
def storage_scope
|
21
|
+
MockUser.all
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -10,6 +10,7 @@ class MockUser < ActiveRecord::Base
|
|
10
10
|
primary_key
|
11
11
|
scim_uid
|
12
12
|
username
|
13
|
+
password
|
13
14
|
first_name
|
14
15
|
last_name
|
15
16
|
work_email_address
|
@@ -46,6 +47,7 @@ class MockUser < ActiveRecord::Base
|
|
46
47
|
id: :primary_key,
|
47
48
|
externalId: :scim_uid,
|
48
49
|
userName: :username,
|
50
|
+
password: :password,
|
49
51
|
name: {
|
50
52
|
givenName: :first_name,
|
51
53
|
familyName: :last_name
|
@@ -21,6 +21,11 @@ Rails.application.routes.draw do
|
|
21
21
|
#
|
22
22
|
delete 'CustomDestroyUsers/:id', to: 'custom_destroy_mock_users#destroy'
|
23
23
|
|
24
|
+
# For testing blocks passed to ActiveRecordBackedResourcesController#save!
|
25
|
+
#
|
26
|
+
post 'CustomSaveUsers', to: 'custom_save_mock_users#create'
|
27
|
+
get 'CustomSaveUsers/:id', to: 'custom_save_mock_users#show'
|
28
|
+
|
24
29
|
# For testing environment inside Scimitar::ApplicationController subclasses.
|
25
30
|
#
|
26
31
|
get 'CustomRequestVerifiers', to: 'custom_request_verifiers#index'
|
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema[7.
|
13
|
+
ActiveRecord::Schema[7.1].define(version: 2021_03_08_044214) do
|
14
14
|
# These are extensions that must be enabled in order to support this database
|
15
15
|
enable_extension "plpgsql"
|
16
16
|
|
@@ -33,6 +33,7 @@ ActiveRecord::Schema[7.0].define(version: 2021_03_08_044214) do
|
|
33
33
|
t.datetime "updated_at", null: false
|
34
34
|
t.text "scim_uid"
|
35
35
|
t.text "username"
|
36
|
+
t.text "password"
|
36
37
|
t.text "first_name"
|
37
38
|
t.text "last_name"
|
38
39
|
t.text "work_email_address"
|
@@ -9,8 +9,8 @@ RSpec.describe Scimitar::ResourceTypesController do
|
|
9
9
|
it 'renders the resource type for user' do
|
10
10
|
get :index, format: :scim
|
11
11
|
response_hash = JSON.parse(response.body)
|
12
|
-
expected_response = [ Scimitar::Resources::User.resource_type(scim_resource_type_url(name: 'User')),
|
13
|
-
Scimitar::Resources::Group.resource_type(scim_resource_type_url(name: 'Group'))
|
12
|
+
expected_response = [ Scimitar::Resources::User.resource_type(scim_resource_type_url(name: 'User', test: 1)),
|
13
|
+
Scimitar::Resources::Group.resource_type(scim_resource_type_url(name: 'Group', test: 1))
|
14
14
|
].to_json
|
15
15
|
|
16
16
|
response_hash = JSON.parse(response.body)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Scimitar::SchemasController do
|
4
|
+
routes { Scimitar::Engine.routes }
|
4
5
|
|
5
6
|
before(:each) { allow(controller).to receive(:authenticated?).and_return(true) }
|
6
7
|
|
@@ -26,6 +27,13 @@ RSpec.describe Scimitar::SchemasController do
|
|
26
27
|
expect(parsed_body['name']).to eql('User')
|
27
28
|
end
|
28
29
|
|
30
|
+
it 'includes the controller customized schema location' do
|
31
|
+
get :index, params: { name: Scimitar::Schema::User.id, format: :scim }
|
32
|
+
expect(response).to be_ok
|
33
|
+
parsed_body = JSON.parse(response.body)
|
34
|
+
expect(parsed_body.dig('meta', 'location')).to eq scim_schemas_url(name: Scimitar::Schema::User.id, test: 1)
|
35
|
+
end
|
36
|
+
|
29
37
|
it 'returns only the Group schema when its id is provided' do
|
30
38
|
get :index, params: { name: Scimitar::Schema::Group.id, format: :scim }
|
31
39
|
expect(response).to be_ok
|
@@ -14,7 +14,10 @@ RSpec.describe Scimitar::Resources::Base do
|
|
14
14
|
),
|
15
15
|
Scimitar::Schema::Attribute.new(
|
16
16
|
name: 'names', multiValued: true, complexType: Scimitar::ComplexTypes::Name, required: false
|
17
|
-
)
|
17
|
+
),
|
18
|
+
Scimitar::Schema::Attribute.new(
|
19
|
+
name: 'privateName', complexType: Scimitar::ComplexTypes::Name, required: false, returned: false
|
20
|
+
),
|
18
21
|
]
|
19
22
|
end
|
20
23
|
end
|
@@ -30,6 +33,10 @@ RSpec.describe Scimitar::Resources::Base do
|
|
30
33
|
name: {
|
31
34
|
givenName: 'John',
|
32
35
|
familyName: 'Smith'
|
36
|
+
},
|
37
|
+
privateName: {
|
38
|
+
givenName: 'Alt John',
|
39
|
+
familyName: 'Alt Smith'
|
33
40
|
}
|
34
41
|
}
|
35
42
|
|
@@ -39,6 +46,9 @@ RSpec.describe Scimitar::Resources::Base do
|
|
39
46
|
expect(resource.name.is_a?(Scimitar::ComplexTypes::Name)).to be(true)
|
40
47
|
expect(resource.name.givenName).to eql('John')
|
41
48
|
expect(resource.name.familyName).to eql('Smith')
|
49
|
+
expect(resource.privateName.is_a?(Scimitar::ComplexTypes::Name)).to be(true)
|
50
|
+
expect(resource.privateName.givenName).to eql('Alt John')
|
51
|
+
expect(resource.privateName.familyName).to eql('Alt Smith')
|
42
52
|
end
|
43
53
|
|
44
54
|
it 'which builds an array of nested resources' do
|
@@ -101,14 +111,38 @@ RSpec.describe Scimitar::Resources::Base do
|
|
101
111
|
context '#as_json' do
|
102
112
|
it 'renders the json with the resourceType' do
|
103
113
|
resource = CustomResourse.new(name: {
|
104
|
-
givenName:
|
114
|
+
givenName: 'John',
|
105
115
|
familyName: 'Smith'
|
106
116
|
})
|
107
117
|
|
108
118
|
result = resource.as_json
|
109
|
-
|
119
|
+
|
120
|
+
expect(result['schemas'] ).to eql(['custom-id'])
|
121
|
+
expect(result['meta']['resourceType']).to eql('CustomResourse')
|
122
|
+
expect(result['errors'] ).to be_nil
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'excludes attributes that are flagged as do-not-return' do
|
126
|
+
resource = CustomResourse.new(
|
127
|
+
name: {
|
128
|
+
givenName: 'John',
|
129
|
+
familyName: 'Smith'
|
130
|
+
},
|
131
|
+
privateName: {
|
132
|
+
givenName: 'Alt John',
|
133
|
+
familyName: 'Alt Smith'
|
134
|
+
}
|
135
|
+
)
|
136
|
+
|
137
|
+
result = resource.as_json
|
138
|
+
|
139
|
+
expect(result['schemas'] ).to eql(['custom-id'])
|
110
140
|
expect(result['meta']['resourceType']).to eql('CustomResourse')
|
111
|
-
expect(result['errors']).to be_nil
|
141
|
+
expect(result['errors'] ).to be_nil
|
142
|
+
expect(result['name'] ).to be_present
|
143
|
+
expect(result['name']['givenName'] ).to eql('John')
|
144
|
+
expect(result['name']['familyName'] ).to eql('Smith')
|
145
|
+
expect(result['privateName'] ).to be_present
|
112
146
|
end
|
113
147
|
end # "context '#as_json' do"
|
114
148
|
|
@@ -160,13 +160,14 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
160
160
|
|
161
161
|
context '#to_scim' do
|
162
162
|
context 'with a UUID, renamed primary key column' do
|
163
|
-
it 'compiles instance attribute values into a SCIM representation' do
|
163
|
+
it 'compiles instance attribute values into a SCIM representation, but omits do-not-return fields' do
|
164
164
|
uuid = SecureRandom.uuid
|
165
165
|
|
166
166
|
instance = MockUser.new
|
167
167
|
instance.primary_key = uuid
|
168
168
|
instance.scim_uid = 'AA02984'
|
169
169
|
instance.username = 'foo'
|
170
|
+
instance.password = 'correcthorsebatterystaple'
|
170
171
|
instance.first_name = 'Foo'
|
171
172
|
instance.last_name = 'Bar'
|
172
173
|
instance.work_email_address = 'foo.bar@test.com'
|
@@ -404,6 +405,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
404
405
|
it 'ignoring read-only lists' do
|
405
406
|
hash = {
|
406
407
|
'userName' => 'foo',
|
408
|
+
'password' => 'staplebatteryhorsecorrect',
|
407
409
|
'name' => {'givenName' => 'Foo', 'familyName' => 'Bar'},
|
408
410
|
'active' => true,
|
409
411
|
'emails' => [{'type' => 'work', 'primary' => true, 'value' => 'foo.bar@test.com'}],
|
@@ -428,6 +430,7 @@ RSpec.describe Scimitar::Resources::Mixin do
|
|
428
430
|
|
429
431
|
expect(instance.scim_uid ).to eql('AA02984')
|
430
432
|
expect(instance.username ).to eql('foo')
|
433
|
+
expect(instance.password ).to eql('staplebatteryhorsecorrect')
|
431
434
|
expect(instance.first_name ).to eql('Foo')
|
432
435
|
expect(instance.last_name ).to eql('Bar')
|
433
436
|
expect(instance.work_email_address).to eql('foo.bar@test.com')
|
@@ -46,6 +46,28 @@ RSpec.describe Scimitar::Schema::Attribute do
|
|
46
46
|
expect(attribute.errors.messages.to_h).to eql({userName: ['has the wrong type. It has to be a(n) string.']})
|
47
47
|
end
|
48
48
|
|
49
|
+
it 'is valid if multi-valued and type is string and given value is an array of strings' do
|
50
|
+
attribute = described_class.new(name: 'scopes', multiValued: true, type: 'string')
|
51
|
+
expect(attribute.valid?(['something', 'something else'])).to be(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'is valid if multi-valued and type is string and given value is an empty array' do
|
55
|
+
attribute = described_class.new(name: 'scopes', multiValued: true, type: 'string')
|
56
|
+
expect(attribute.valid?([])).to be(true)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'is invalid if multi-valued and type is string and given value is not an array' do
|
60
|
+
attribute = described_class.new(name: 'scopes', multiValued: true, type: 'string')
|
61
|
+
expect(attribute.valid?('something')).to be(false)
|
62
|
+
expect(attribute.errors.messages.to_h).to eql({scopes: ['or one of its elements has the wrong type. It has to be an array of strings.']})
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'is invalid if multi-valued and type is string and given value is an array containing another type' do
|
66
|
+
attribute = described_class.new(name: 'scopes', multiValued: true, type: 'string')
|
67
|
+
expect(attribute.valid?(['something', 123])).to be(false)
|
68
|
+
expect(attribute.errors.messages.to_h).to eql({scopes: ['or one of its elements has the wrong type. It has to be an array of strings.']})
|
69
|
+
end
|
70
|
+
|
49
71
|
it 'is valid if type is boolean and given value is boolean' do
|
50
72
|
expect(described_class.new(name: 'name', type: 'boolean').valid?(false)).to be(true)
|
51
73
|
expect(described_class.new(name: 'name', type: 'boolean').valid?(true)).to be(true)
|
@@ -397,6 +397,22 @@ RSpec.describe Scimitar::ActiveRecordBackedResourcesController do
|
|
397
397
|
expect(result['scimType']).to eql('invalidValue')
|
398
398
|
expect(result['detail']).to include('is reserved')
|
399
399
|
end
|
400
|
+
|
401
|
+
it 'invokes a block if given one' do
|
402
|
+
mock_before = MockUser.all.to_a
|
403
|
+
attributes = { userName: '5' } # Minimum required by schema
|
404
|
+
|
405
|
+
expect_any_instance_of(CustomSaveMockUsersController).to receive(:create).once.and_call_original
|
406
|
+
expect {
|
407
|
+
post "/CustomSaveUsers", params: attributes.merge(format: :scim)
|
408
|
+
}.to change { MockUser.count }.by(1)
|
409
|
+
|
410
|
+
mock_after = MockUser.all.to_a
|
411
|
+
new_mock = (mock_after - mock_before).first
|
412
|
+
|
413
|
+
expect(response.status).to eql(201)
|
414
|
+
expect(new_mock.username).to eql(CustomSaveMockUsersController::CUSTOM_SAVE_BLOCK_USERNAME_INDICATOR)
|
415
|
+
end
|
400
416
|
end # "context '#create' do"
|
401
417
|
|
402
418
|
# ===========================================================================
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scimitar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- RIPA Global
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-11-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -196,6 +196,7 @@ files:
|
|
196
196
|
- lib/scimitar/version.rb
|
197
197
|
- spec/apps/dummy/app/controllers/custom_destroy_mock_users_controller.rb
|
198
198
|
- spec/apps/dummy/app/controllers/custom_request_verifiers_controller.rb
|
199
|
+
- spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb
|
199
200
|
- spec/apps/dummy/app/controllers/mock_groups_controller.rb
|
200
201
|
- spec/apps/dummy/app/controllers/mock_users_controller.rb
|
201
202
|
- spec/apps/dummy/app/models/mock_group.rb
|
@@ -260,13 +261,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
261
|
- !ruby/object:Gem::Version
|
261
262
|
version: '0'
|
262
263
|
requirements: []
|
263
|
-
rubygems_version: 3.4.
|
264
|
+
rubygems_version: 3.4.10
|
264
265
|
signing_key:
|
265
266
|
specification_version: 4
|
266
267
|
summary: SCIM v2 for Rails
|
267
268
|
test_files:
|
268
269
|
- spec/apps/dummy/app/controllers/custom_destroy_mock_users_controller.rb
|
269
270
|
- spec/apps/dummy/app/controllers/custom_request_verifiers_controller.rb
|
271
|
+
- spec/apps/dummy/app/controllers/custom_save_mock_users_controller.rb
|
270
272
|
- spec/apps/dummy/app/controllers/mock_groups_controller.rb
|
271
273
|
- spec/apps/dummy/app/controllers/mock_users_controller.rb
|
272
274
|
- spec/apps/dummy/app/models/mock_group.rb
|