scimaenaga 0.7.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.
- checksums.yaml +4 -4
- data/README.md +22 -7
- data/Rakefile +6 -8
- data/app/controllers/concerns/{scim_rails → scimaenaga}/exception_handler.rb +47 -37
- data/app/controllers/concerns/scimaenaga/response.rb +94 -0
- data/app/controllers/scimaenaga/application_controller.rb +72 -0
- data/app/controllers/{scim_rails → scimaenaga}/scim_groups_controller.rb +26 -26
- data/app/controllers/scimaenaga/scim_schemas_controller.rb +42 -0
- data/app/controllers/scimaenaga/scim_users_controller.rb +104 -0
- data/app/helpers/{scim_rails → scimaenaga}/application_helper.rb +1 -1
- data/app/libraries/scim_patch.rb +16 -9
- data/app/libraries/scim_patch_operation.rb +51 -141
- data/app/libraries/scim_patch_operation_converter.rb +90 -0
- data/app/libraries/scim_patch_operation_group.rb +100 -0
- data/app/libraries/scim_patch_operation_user.rb +53 -0
- data/app/models/{scim_rails → scimaenaga}/application_record.rb +1 -1
- data/app/models/scimaenaga/authorize_api_request.rb +39 -0
- data/app/models/{scim_rails → scimaenaga}/scim_count.rb +8 -4
- data/app/models/scimaenaga/scim_query_parser.rb +49 -0
- data/config/routes.rb +15 -13
- data/lib/generators/scimaenaga/USAGE +8 -0
- data/lib/generators/scimaenaga/scimaenaga_generator.rb +7 -0
- data/lib/generators/{scim_rails → scimaenaga}/templates/initializer.rb +128 -22
- data/lib/{scim_rails → scimaenaga}/config.rb +9 -7
- data/lib/scimaenaga/encoder.rb +27 -0
- data/lib/scimaenaga/engine.rb +12 -0
- data/lib/scimaenaga/version.rb +5 -0
- data/lib/scimaenaga.rb +6 -0
- data/lib/tasks/{scim_rails_tasks.rake → scimaenaga_tasks.rake} +1 -1
- data/spec/controllers/{scim_rails → scimaenaga}/scim_groups_controller_spec.rb +8 -8
- data/spec/controllers/{scim_rails → scimaenaga}/scim_groups_request_spec.rb +18 -18
- data/spec/controllers/scimaenaga/scim_schemas_controller_spec.rb +238 -0
- data/spec/controllers/scimaenaga/scim_schemas_request_spec.rb +39 -0
- data/spec/controllers/{scim_rails → scimaenaga}/scim_users_controller_spec.rb +14 -15
- data/spec/controllers/{scim_rails → scimaenaga}/scim_users_request_spec.rb +20 -20
- data/spec/dummy/app/assets/config/manifest.js +1 -1
- data/spec/dummy/config/application.rb +1 -2
- data/spec/dummy/config/initializers/{scim_rails_config.rb → scimaenaga_config.rb} +25 -25
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/factories/company.rb +3 -3
- data/spec/lib/scimaenaga/encoder_spec.rb +64 -0
- data/spec/libraries/scim_patch_operation_group_spec.rb +165 -0
- data/spec/libraries/scim_patch_operation_user_spec.rb +101 -0
- data/spec/libraries/scim_patch_spec.rb +129 -45
- data/spec/models/scim_query_parser_spec.rb +5 -6
- metadata +107 -108
- data/app/controllers/concerns/scim_rails/response.rb +0 -94
- data/app/controllers/scim_rails/application_controller.rb +0 -72
- data/app/controllers/scim_rails/scim_users_controller.rb +0 -107
- data/app/models/scim_rails/authorize_api_request.rb +0 -40
- data/app/models/scim_rails/scim_query_parser.rb +0 -49
- data/lib/generators/scim_rails/USAGE +0 -8
- data/lib/generators/scim_rails/scim_rails_generator.rb +0 -7
- data/lib/scim_rails/encoder.rb +0 -25
- data/lib/scim_rails/engine.rb +0 -12
- data/lib/scim_rails/version.rb +0 -5
- data/lib/scim_rails.rb +0 -6
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +0 -5770
- data/spec/dummy/put_group.http +0 -5
- data/spec/dummy/tmp/restart.txt +0 -0
- data/spec/lib/scim_rails/encoder_spec.rb +0 -62
- data/spec/libraries/scim_patch_operation_spec.rb +0 -116
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Scimaenaga
|
4
|
+
class ScimQueryParser
|
5
|
+
attr_accessor :query_elements, :query_attributes
|
6
|
+
|
7
|
+
def initialize(query_string, queryable_attributes)
|
8
|
+
self.query_elements = query_string.gsub(/\[(.+?)\]/, '.0').split
|
9
|
+
self.query_attributes = queryable_attributes
|
10
|
+
end
|
11
|
+
|
12
|
+
def attribute
|
13
|
+
attribute = query_elements[0]
|
14
|
+
raise Scimaenaga::ExceptionHandler::InvalidQuery if attribute.blank?
|
15
|
+
|
16
|
+
dig_keys = attribute.split('.').map do |step|
|
17
|
+
step == '0' ? 0 : step.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
mapped_attribute = query_attributes.dig(*dig_keys)
|
21
|
+
raise Scimaenaga::ExceptionHandler::InvalidQuery if mapped_attribute.blank?
|
22
|
+
|
23
|
+
mapped_attribute
|
24
|
+
end
|
25
|
+
|
26
|
+
def operator
|
27
|
+
sql_comparison_operator(query_elements[1])
|
28
|
+
end
|
29
|
+
|
30
|
+
def parameter
|
31
|
+
parameter = query_elements[2..-1].join(' ')
|
32
|
+
return if parameter.blank?
|
33
|
+
|
34
|
+
parameter.gsub(/"/, '')
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def sql_comparison_operator(element)
|
40
|
+
case element
|
41
|
+
when 'eq'
|
42
|
+
'='
|
43
|
+
else
|
44
|
+
# TODO: implement additional query filters
|
45
|
+
raise Scimaenaga::ExceptionHandler::InvalidQuery
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/config/routes.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
|
-
|
2
|
-
get 'scim/v2/Users',
|
3
|
-
post 'scim/v2/Users',
|
4
|
-
get 'scim/v2/Users/:id',
|
5
|
-
put 'scim/v2/Users/:id',
|
6
|
-
patch 'scim/v2/Users/:id',
|
7
|
-
delete 'scim/v2/Users/:id',
|
8
|
-
get 'scim/v2/Groups',
|
9
|
-
post 'scim/v2/Groups',
|
10
|
-
get 'scim/v2/Groups/:id',
|
11
|
-
put 'scim/v2/Groups/:id',
|
12
|
-
patch 'scim/v2/Groups/:id',
|
13
|
-
delete 'scim/v2/Groups/:id',
|
1
|
+
Scimaenaga::Engine.routes.draw do
|
2
|
+
get 'scim/v2/Users', action: :index, controller: 'scim_users'
|
3
|
+
post 'scim/v2/Users', action: :create, controller: 'scim_users'
|
4
|
+
get 'scim/v2/Users/:id', action: :show, controller: 'scim_users'
|
5
|
+
put 'scim/v2/Users/:id', action: :put_update, controller: 'scim_users'
|
6
|
+
patch 'scim/v2/Users/:id', action: :patch_update, controller: 'scim_users'
|
7
|
+
delete 'scim/v2/Users/:id', action: :destroy, controller: 'scim_users'
|
8
|
+
get 'scim/v2/Groups', action: :index, controller: 'scim_groups'
|
9
|
+
post 'scim/v2/Groups', action: :create, controller: 'scim_groups'
|
10
|
+
get 'scim/v2/Groups/:id', action: :show, controller: 'scim_groups'
|
11
|
+
put 'scim/v2/Groups/:id', action: :put_update, controller: 'scim_groups'
|
12
|
+
patch 'scim/v2/Groups/:id', action: :patch_update, controller: 'scim_groups'
|
13
|
+
delete 'scim/v2/Groups/:id', action: :destroy, controller: 'scim_groups'
|
14
|
+
get 'scim/v2/Schemas', action: :index, controller: 'scim_schemas'
|
15
|
+
get 'scim/v2/Schemas/:id', action: :show, controller: 'scim_schemas'
|
14
16
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
Scimaenaga.configure do |config|
|
4
4
|
# Model used for authenticating and scoping users.
|
5
|
-
config.basic_auth_model =
|
5
|
+
config.basic_auth_model = 'Company'
|
6
6
|
|
7
7
|
# Attribute used to search for a given record. This
|
8
8
|
# attribute should be unique as it will return the
|
@@ -14,7 +14,7 @@ ScimRails.configure do |config|
|
|
14
14
|
config.basic_auth_model_authenticatable_attribute = :api_token
|
15
15
|
|
16
16
|
# Model used for user records.
|
17
|
-
config.scim_users_model =
|
17
|
+
config.scim_users_model = 'User'
|
18
18
|
|
19
19
|
# Method used for retrieving user records from the
|
20
20
|
# authenticatable model.
|
@@ -25,7 +25,7 @@ ScimRails.configure do |config|
|
|
25
25
|
config.scim_user_prevent_update_on_create = false
|
26
26
|
|
27
27
|
# Model used for group records.
|
28
|
-
config.scim_groups_model =
|
28
|
+
config.scim_groups_model = 'Group'
|
29
29
|
# Method used for retrieving user records from the
|
30
30
|
# authenticatable model.
|
31
31
|
config.scim_groups_scope = :groups
|
@@ -56,16 +56,16 @@ ScimRails.configure do |config|
|
|
56
56
|
userName: :email,
|
57
57
|
givenName: :first_name,
|
58
58
|
familyName: :last_name,
|
59
|
-
email: :email
|
59
|
+
email: :email,
|
60
60
|
}
|
61
61
|
|
62
62
|
# Array of attributes that can be modified on the
|
63
63
|
# user model. If the attribute is not in this array
|
64
64
|
# the attribute cannot be modified by this Gem.
|
65
|
-
config.mutable_user_attributes = [
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
config.mutable_user_attributes = %i[
|
66
|
+
first_name
|
67
|
+
last_name
|
68
|
+
email
|
69
69
|
]
|
70
70
|
|
71
71
|
# Hash of mutable attributes. This object is the map
|
@@ -76,13 +76,13 @@ ScimRails.configure do |config|
|
|
76
76
|
config.mutable_user_attributes_schema = {
|
77
77
|
name: {
|
78
78
|
givenName: :first_name,
|
79
|
-
familyName: :last_name
|
79
|
+
familyName: :last_name,
|
80
80
|
},
|
81
81
|
emails: [
|
82
82
|
{
|
83
|
-
value: :email
|
83
|
+
value: :email,
|
84
84
|
}
|
85
|
-
]
|
85
|
+
],
|
86
86
|
}
|
87
87
|
|
88
88
|
# Hash of SCIM structure for a user schema. This object
|
@@ -93,31 +93,31 @@ ScimRails.configure do |config|
|
|
93
93
|
# through as is, symbols will be passed to the user
|
94
94
|
# object to return a value.
|
95
95
|
config.user_schema = {
|
96
|
-
schemas: [
|
96
|
+
schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'],
|
97
97
|
id: :id,
|
98
98
|
userName: :email,
|
99
99
|
name: {
|
100
100
|
givenName: :first_name,
|
101
|
-
familyName: :last_name
|
101
|
+
familyName: :last_name,
|
102
102
|
},
|
103
103
|
emails: [
|
104
104
|
{
|
105
|
-
value: :email
|
105
|
+
value: :email,
|
106
106
|
}
|
107
107
|
],
|
108
|
-
active: :active
|
108
|
+
active: :active?,
|
109
109
|
}
|
110
110
|
|
111
111
|
# Schema for users used in "abbreviated" lists such as in
|
112
112
|
# the `members` field of a Group.
|
113
113
|
config.user_abbreviated_schema = {
|
114
114
|
value: :id,
|
115
|
-
display: :email
|
115
|
+
display: :email,
|
116
116
|
}
|
117
117
|
|
118
118
|
# Allow filtering Groups based on these parameters
|
119
119
|
config.queryable_group_attributes = {
|
120
|
-
displayName: :name
|
120
|
+
displayName: :name,
|
121
121
|
}
|
122
122
|
|
123
123
|
# List of attributes on a Group that can be updated through SCIM
|
@@ -131,7 +131,7 @@ ScimRails.configure do |config|
|
|
131
131
|
# include all attributes listed in
|
132
132
|
# config.mutable_group_attributes.
|
133
133
|
config.mutable_group_attributes_schema = {
|
134
|
-
displayName: :name
|
134
|
+
displayName: :name,
|
135
135
|
}
|
136
136
|
|
137
137
|
# The User relation's IDs field name on the Group model.
|
@@ -143,18 +143,124 @@ ScimRails.configure do |config|
|
|
143
143
|
config.group_member_relation_schema = { value: :user_ids }
|
144
144
|
|
145
145
|
config.group_schema = {
|
146
|
-
schemas: [
|
146
|
+
schemas: ['urn:ietf:params:scim:schemas:core:2.0:Group'],
|
147
147
|
id: :id,
|
148
148
|
displayName: :name,
|
149
|
-
members: :users
|
149
|
+
members: :users,
|
150
150
|
}
|
151
151
|
|
152
152
|
config.group_abbreviated_schema = {
|
153
153
|
value: :id,
|
154
|
-
display: :name
|
154
|
+
display: :name,
|
155
155
|
}
|
156
156
|
|
157
157
|
# Set group_destroy_method to a method on the Group model
|
158
158
|
# to be called on a destroy request
|
159
159
|
# config.group_destroy_method = :destroy!
|
160
|
+
|
161
|
+
# /Schemas settings.
|
162
|
+
# These settings are not used in /Users and /Groups for now.
|
163
|
+
# Configure this only when you need Schemas endpoint.
|
164
|
+
# Schemas endpoint returns the configured values as-is.
|
165
|
+
config.schemas = [
|
166
|
+
# Define User schemas
|
167
|
+
{
|
168
|
+
# Normally you don't have to change schemas/id/name/description
|
169
|
+
schemas: ['urn:ietf:params:scim:schemas:core:2.0:Schema'],
|
170
|
+
id: 'urn:ietf:params:scim:schemas:core:2.0:User',
|
171
|
+
name: 'User',
|
172
|
+
description: 'User Account',
|
173
|
+
|
174
|
+
# Configure 'attributes' as it corresponds with other configurations and your model
|
175
|
+
attributes: [
|
176
|
+
{
|
177
|
+
# Name of SCIM attribute. It must be configured in "user_schema"
|
178
|
+
name: 'userName',
|
179
|
+
|
180
|
+
# "type" must be string/boolan/decimal/integer/dateTime/reference
|
181
|
+
# "complex" value is not supported now
|
182
|
+
type: 'string',
|
183
|
+
|
184
|
+
# Multi value attribute is not supported, must be false
|
185
|
+
multiValued: false,
|
186
|
+
|
187
|
+
description: 'Unique identifier for the User. REQUIRED.',
|
188
|
+
|
189
|
+
# Specify true when you require this attribute
|
190
|
+
required: true,
|
191
|
+
|
192
|
+
# In this Library, String value is always handled as case exact
|
193
|
+
caseExact: true,
|
194
|
+
|
195
|
+
# "mutability" must be readOnly/readWrite/writeOnly
|
196
|
+
# "immutable" is not supported.
|
197
|
+
# readOnly: attribute is defined in queryable_user_attributes but not in mutable_user_attributes and user_schema
|
198
|
+
# readWrite: attribute is defined in queryable_user_attributes, mutable_user_attributes and user_schema
|
199
|
+
# writeOnly: attribute is defined in mutable_user_attributes, and user_schema but not in queryable_user_attributes
|
200
|
+
mutability: 'readWrite',
|
201
|
+
|
202
|
+
# "returned" must be always/never. default and request are not supported
|
203
|
+
# always: attribute is defined in user_schema
|
204
|
+
# never: attribute is not defined in user_schema
|
205
|
+
returned: 'always',
|
206
|
+
|
207
|
+
# "uniqueness" must be none/server/global. It's dependent on your service
|
208
|
+
uniqueness: 'server',
|
209
|
+
}
|
210
|
+
],
|
211
|
+
meta: {
|
212
|
+
resourceType: 'Schema',
|
213
|
+
location:
|
214
|
+
'/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:User',
|
215
|
+
},
|
216
|
+
},
|
217
|
+
# define Group schemas
|
218
|
+
{
|
219
|
+
schemas: ['urn:ietf:params:scim:schemas:core:2.0:Schema'],
|
220
|
+
id: 'urn:ietf:params:scim:schemas:core:2.0:Group',
|
221
|
+
name: 'Group',
|
222
|
+
description: 'Group',
|
223
|
+
attributes: [
|
224
|
+
{
|
225
|
+
# Same as the User attributes
|
226
|
+
name: 'displayName',
|
227
|
+
type: 'string',
|
228
|
+
multiValued: false,
|
229
|
+
description: 'A human-readable name for the Group. REQUIRED.',
|
230
|
+
required: true,
|
231
|
+
caseExact: true,
|
232
|
+
mutability: 'readWrite',
|
233
|
+
returned: 'always',
|
234
|
+
uniqueness: 'none',
|
235
|
+
},
|
236
|
+
{
|
237
|
+
name: 'members',
|
238
|
+
|
239
|
+
# Only "members" can be configured as a complex and multivalued attribute
|
240
|
+
type: 'complex',
|
241
|
+
multiValued: true,
|
242
|
+
|
243
|
+
description: 'A list of members of the Group.',
|
244
|
+
required: false,
|
245
|
+
subAttributes: [
|
246
|
+
{
|
247
|
+
name: 'value',
|
248
|
+
type: 'string',
|
249
|
+
multiValued: false,
|
250
|
+
description: 'Identifier of the member of this Group.',
|
251
|
+
required: false,
|
252
|
+
caseExact: true,
|
253
|
+
mutability: 'immutable',
|
254
|
+
returned: 'default',
|
255
|
+
uniqueness: 'none',
|
256
|
+
}
|
257
|
+
],
|
258
|
+
}
|
259
|
+
],
|
260
|
+
meta: {
|
261
|
+
resourceType: 'Schema',
|
262
|
+
location: '/v2/Schemas/urn:ietf:params:scim:schemas:core:2.0:Group',
|
263
|
+
},
|
264
|
+
}
|
265
|
+
]
|
160
266
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module Scimaenaga
|
4
4
|
class << self
|
5
5
|
def configure
|
6
6
|
yield config
|
@@ -11,9 +11,9 @@ module ScimRails
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
# Class containing configuration of
|
14
|
+
# Class containing configuration of Scimaenaga
|
15
15
|
class Config
|
16
|
-
ALGO_NONE =
|
16
|
+
ALGO_NONE = 'none'
|
17
17
|
|
18
18
|
attr_writer \
|
19
19
|
:basic_auth_model,
|
@@ -45,20 +45,22 @@ module ScimRails
|
|
45
45
|
:user_schema,
|
46
46
|
:group_schema,
|
47
47
|
:user_destroy_method,
|
48
|
-
:group_destroy_method
|
48
|
+
:group_destroy_method,
|
49
|
+
:schemas
|
49
50
|
|
50
51
|
def initialize
|
51
|
-
@basic_auth_model =
|
52
|
+
@basic_auth_model = 'Company'
|
52
53
|
@scim_users_list_order = :id
|
53
|
-
@scim_users_model =
|
54
|
+
@scim_users_model = 'User'
|
54
55
|
@scim_groups_list_order = :id
|
55
|
-
@scim_groups_model =
|
56
|
+
@scim_groups_model = 'Group'
|
56
57
|
@signing_algorithm = ALGO_NONE
|
57
58
|
@user_schema = {}
|
58
59
|
@user_attributes = []
|
59
60
|
@user_abbreviated_schema = {}
|
60
61
|
@group_schema = {}
|
61
62
|
@group_abbreviated_schema = {}
|
63
|
+
@schemas = []
|
62
64
|
end
|
63
65
|
|
64
66
|
def mutable_user_attributes_schema
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'jwt'
|
2
|
+
|
3
|
+
module Scimaenaga
|
4
|
+
module Encoder
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def encode(company)
|
8
|
+
payload = {
|
9
|
+
iat: Time.current.to_i,
|
10
|
+
Scimaenaga.config.basic_auth_model_searchable_attribute =>
|
11
|
+
company.public_send(Scimaenaga.config.basic_auth_model_searchable_attribute),
|
12
|
+
}
|
13
|
+
|
14
|
+
JWT.encode(payload, Scimaenaga.config.signing_secret,
|
15
|
+
Scimaenaga.config.signing_algorithm)
|
16
|
+
end
|
17
|
+
|
18
|
+
def decode(token)
|
19
|
+
verify = Scimaenaga.config.signing_algorithm != Scimaenaga::Config::ALGO_NONE
|
20
|
+
|
21
|
+
JWT.decode(token, Scimaenaga.config.signing_secret, verify,
|
22
|
+
algorithm: Scimaenaga.config.signing_algorithm).first
|
23
|
+
rescue JWT::VerificationError, JWT::DecodeError
|
24
|
+
raise Scimaenaga::ExceptionHandler::InvalidCredentials
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Scimaenaga
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace Scimaenaga
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec, fixture: false
|
7
|
+
g.fixture_replacement :factory_bot, dir: 'spec/factories'
|
8
|
+
g.assets false
|
9
|
+
g.helper false
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/scimaenaga.rb
ADDED
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
RSpec.describe
|
5
|
+
RSpec.describe Scimaenaga::ScimGroupsController, type: :controller do
|
6
6
|
include AuthHelper
|
7
7
|
|
8
|
-
routes {
|
8
|
+
routes { Scimaenaga::Engine.routes }
|
9
9
|
|
10
10
|
describe 'index' do
|
11
11
|
let(:company) { create(:company) }
|
@@ -86,7 +86,7 @@ RSpec.describe ScimRails::ScimGroupsController, type: :controller do
|
|
86
86
|
end
|
87
87
|
|
88
88
|
it 'paginates results by configurable scim_groups_list_order' do
|
89
|
-
allow(
|
89
|
+
allow(Scimaenaga.config).to(
|
90
90
|
receive(:scim_groups_list_order).and_return(created_at: :desc)
|
91
91
|
)
|
92
92
|
|
@@ -417,8 +417,8 @@ RSpec.describe ScimRails::ScimGroupsController, type: :controller do
|
|
417
417
|
Operations: [{
|
418
418
|
op: 'Replace',
|
419
419
|
path: 'displayName',
|
420
|
-
value: 'changed'
|
421
|
-
}]
|
420
|
+
value: 'changed',
|
421
|
+
}],
|
422
422
|
}, as: :json
|
423
423
|
end.to change { group.reload.name }.to('changed')
|
424
424
|
|
@@ -543,7 +543,7 @@ RSpec.describe ScimRails::ScimGroupsController, type: :controller do
|
|
543
543
|
|
544
544
|
context 'when Group destroy method is not configured' do
|
545
545
|
it 'does not delete Group' do
|
546
|
-
allow(
|
546
|
+
allow(Scimaenaga.config).to(
|
547
547
|
receive(:group_destroy_method).and_return(nil)
|
548
548
|
)
|
549
549
|
|
@@ -557,7 +557,7 @@ RSpec.describe ScimRails::ScimGroupsController, type: :controller do
|
|
557
557
|
|
558
558
|
context 'when Group destroy method is invalid' do
|
559
559
|
it 'does not delete Group' do
|
560
|
-
allow(
|
560
|
+
allow(Scimaenaga.config).to(
|
561
561
|
receive(:group_destroy_method).and_return('destory!')
|
562
562
|
)
|
563
563
|
|
@@ -572,7 +572,7 @@ RSpec.describe ScimRails::ScimGroupsController, type: :controller do
|
|
572
572
|
context 'whenr target Group is not found' do
|
573
573
|
it 'return 404 not found' do
|
574
574
|
expect do
|
575
|
-
delete :destroy, params: { id:
|
575
|
+
delete :destroy, params: { id: 999_999 }, as: :json
|
576
576
|
end.not_to change { company.groups.reload.count }.from(1)
|
577
577
|
|
578
578
|
expect(response.status).to eq 404
|
@@ -1,42 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
-
RSpec.describe
|
5
|
+
RSpec.describe Scimaenaga::ScimGroupsController, type: :request do
|
6
6
|
let(:company) { create(:company) }
|
7
7
|
let(:credentials) do
|
8
8
|
Base64.encode64("#{company.subdomain}:#{company.api_token}")
|
9
9
|
end
|
10
10
|
let(:authorization) { "Basic #{credentials}" }
|
11
11
|
|
12
|
-
def post_request(content_type =
|
13
|
-
post
|
12
|
+
def post_request(content_type = 'application/scim+json')
|
13
|
+
post '/scim/v2/Groups',
|
14
14
|
params: {
|
15
|
-
displayName:
|
16
|
-
members: []
|
15
|
+
displayName: 'Dummy Group',
|
16
|
+
members: [],
|
17
17
|
}.to_json,
|
18
18
|
headers: {
|
19
19
|
Authorization: authorization,
|
20
|
-
'Content-Type': content_type
|
20
|
+
'Content-Type': content_type,
|
21
21
|
}
|
22
22
|
end
|
23
23
|
|
24
|
-
describe
|
25
|
-
it
|
24
|
+
describe 'Content-Type' do
|
25
|
+
it 'accepts scim+json' do
|
26
26
|
expect(company.groups.count).to eq 0
|
27
27
|
|
28
|
-
post_request(
|
28
|
+
post_request('application/scim+json')
|
29
29
|
|
30
30
|
expect(request.params).to include :displayName
|
31
31
|
expect(response.status).to eq 201
|
32
|
-
expect(response.media_type).to eq
|
32
|
+
expect(response.media_type).to eq 'application/scim+json'
|
33
33
|
expect(company.groups.count).to eq 1
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
36
|
+
it 'can not parse unfamiliar content types' do
|
37
37
|
expect(company.groups.count).to eq 0
|
38
38
|
|
39
|
-
post_request(
|
39
|
+
post_request('text/csv')
|
40
40
|
|
41
41
|
expect(request.params).not_to include :displayName
|
42
42
|
expect(response.status).to eq 422
|
@@ -44,21 +44,21 @@ RSpec.describe ScimRails::ScimGroupsController, type: :request do
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
context
|
48
|
-
context
|
47
|
+
context 'OAuth Bearer Authorization' do
|
48
|
+
context 'with valid token' do
|
49
49
|
let(:authorization) { "Bearer #{company.api_token}" }
|
50
50
|
|
51
|
-
it
|
51
|
+
it 'supports OAuth bearer authorization and succeeds' do
|
52
52
|
expect { post_request }.to change(company.groups, :count).from(0).to(1)
|
53
53
|
|
54
54
|
expect(response.status).to eq 201
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
context
|
58
|
+
context 'with invalid token' do
|
59
59
|
let(:authorization) { "Bearer #{SecureRandom.hex}" }
|
60
60
|
|
61
|
-
it
|
61
|
+
it 'The request fails' do
|
62
62
|
expect { post_request }.not_to change(company.groups, :count)
|
63
63
|
|
64
64
|
expect(response.status).to eq 401
|