mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Revert " [#65747] Make /scim_v2/Schemas endpoint return required by OP schemas."
This reverts commit b249fd36b4.
This commit is contained in:
@@ -89,27 +89,6 @@ module ScimV2
|
||||
|
||||
all_possible_attributes - excluded_attributes - excluded_parents
|
||||
end
|
||||
|
||||
def raise_result_errors_for_scim(result)
|
||||
result.on_failure do |result|
|
||||
uniqueness_error = result.errors.find { |e| e.type == :taken }
|
||||
unauthorized_error = result.errors.find { |e| e.type == :error_unauthorized }
|
||||
if uniqueness_error.present?
|
||||
raise Scimitar::ErrorResponse.new(
|
||||
status: 409,
|
||||
scimType: "uniqueness",
|
||||
detail: "Operation failed due to a uniqueness constraint: #{result.message}"
|
||||
)
|
||||
elsif unauthorized_error.present?
|
||||
raise Scimitar::ErrorResponse.new(
|
||||
status: 403,
|
||||
detail: "Action forbidden: insufficient permissions."
|
||||
)
|
||||
else
|
||||
raise result.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,15 +40,26 @@ module ScimV2
|
||||
call = Groups::CreateService
|
||||
.new(user: User.current, model: group)
|
||||
.call(group.attributes)
|
||||
raise_result_errors_for_scim(call)
|
||||
.on_failure do |result|
|
||||
uniqueness_error = result.errors.find { |e| e.type == :taken }
|
||||
if uniqueness_error.present?
|
||||
raise Scimitar::ErrorResponse.new(
|
||||
status: 409,
|
||||
scimType: "uniqueness",
|
||||
detail: "Operation failed due to a uniqueness constraint: #{result.message}"
|
||||
)
|
||||
else
|
||||
raise result.message
|
||||
end
|
||||
end
|
||||
group = call.result
|
||||
|
||||
members = scim_resource.members
|
||||
if members.present?
|
||||
raise_result_errors_for_scim(
|
||||
Groups::AddUsersService
|
||||
.new(group, current_user: User.system)
|
||||
.call(ids: members.map(&:value), send_notifications: false)
|
||||
)
|
||||
Groups::AddUsersService
|
||||
.new(group, current_user: User.system)
|
||||
.call(ids: members.map(&:value), send_notifications: false)
|
||||
.on_failure { |call| raise call.message }
|
||||
end
|
||||
|
||||
group.to_scim(
|
||||
@@ -64,11 +75,10 @@ module ScimV2
|
||||
storage_class.transaction do
|
||||
group = storage_scope.find(group_id)
|
||||
group.from_scim!(scim_hash: scim_resource.as_json)
|
||||
raise_result_errors_for_scim(
|
||||
Groups::UpdateService
|
||||
.new(user: User.current, model: group)
|
||||
.call(user_ids: scim_resource.members.map(&:value))
|
||||
)
|
||||
Groups::UpdateService
|
||||
.new(user: User.current, model: group)
|
||||
.call(user_ids: scim_resource.members.map(&:value))
|
||||
.on_failure { |call| raise call.message }
|
||||
group.reload
|
||||
group.to_scim(
|
||||
location: url_for(action: :show, id: group.id),
|
||||
@@ -84,11 +94,10 @@ module ScimV2
|
||||
group = storage_scope.find(group_id)
|
||||
group.from_scim_patch!(patch_hash: patch_hash)
|
||||
user_ids = group.scim_members.map(&:id)
|
||||
raise_result_errors_for_scim(
|
||||
Groups::UpdateService
|
||||
.new(user: User.current, model: group)
|
||||
.call(user_ids:)
|
||||
)
|
||||
Groups::UpdateService
|
||||
.new(user: User.current, model: group)
|
||||
.call(user_ids:)
|
||||
.on_failure { |call| raise call.message }
|
||||
group.reload
|
||||
group.to_scim(
|
||||
location: url_for(action: :show, id: group.id),
|
||||
@@ -101,11 +110,10 @@ module ScimV2
|
||||
def destroy
|
||||
super do |group_id|
|
||||
group = storage_scope.find(group_id)
|
||||
raise_result_errors_for_scim(
|
||||
Groups::DeleteService
|
||||
.new(user: User.current, model: group)
|
||||
.call
|
||||
)
|
||||
Groups::DeleteService
|
||||
.new(user: User.current, model: group)
|
||||
.call
|
||||
.on_failure { |call| raise call.message }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -40,7 +40,19 @@ module ScimV2
|
||||
call = Users::CreateService
|
||||
.new(user: User.current, model: user)
|
||||
.call(user.attributes)
|
||||
raise_result_errors_for_scim(call)
|
||||
.on_failure do |result|
|
||||
uniqueness_error = result.errors.find { |e| e.type == :taken }
|
||||
if uniqueness_error.present?
|
||||
raise Scimitar::ErrorResponse.new(
|
||||
status: 409,
|
||||
scimType: "uniqueness",
|
||||
detail: "Operation failed due to a uniqueness constraint: #{result.message}"
|
||||
)
|
||||
else
|
||||
raise result.message
|
||||
end
|
||||
end
|
||||
|
||||
user = call.result
|
||||
user.to_scim(
|
||||
location: url_for(action: :show, id: user.id),
|
||||
@@ -55,11 +67,10 @@ module ScimV2
|
||||
storage_class.transaction do
|
||||
user = storage_scope.find(user_id)
|
||||
user.from_scim!(scim_hash: scim_resource.as_json)
|
||||
call = Users::UpdateService
|
||||
.new(user: User.current, model: user)
|
||||
.call
|
||||
raise_result_errors_for_scim(call)
|
||||
user = call.result
|
||||
Users::UpdateService
|
||||
.new(user: User.current, model: user)
|
||||
.call
|
||||
.on_failure { |call| raise call.message }
|
||||
user.to_scim(
|
||||
location: url_for(action: :show, id: user.id),
|
||||
include_attributes:
|
||||
@@ -73,11 +84,10 @@ module ScimV2
|
||||
storage_class.transaction do
|
||||
user = storage_scope.find(user_id)
|
||||
user.from_scim_patch!(patch_hash: patch_hash)
|
||||
call = Users::UpdateService
|
||||
.new(user: User.current, model: user)
|
||||
.call
|
||||
raise_result_errors_for_scim(call)
|
||||
user = call.result
|
||||
Users::UpdateService
|
||||
.new(user: User.current, model: user)
|
||||
.call
|
||||
.on_failure { |call| raise call.message }
|
||||
user.to_scim(
|
||||
location: url_for(action: :show, id: user.id),
|
||||
include_attributes:
|
||||
@@ -89,10 +99,20 @@ module ScimV2
|
||||
def destroy
|
||||
super do |user_id|
|
||||
user = storage_scope.find(user_id)
|
||||
call = Users::DeleteService
|
||||
.new(user: User.current, model: user)
|
||||
.call
|
||||
raise_result_errors_for_scim(call)
|
||||
Users::DeleteService
|
||||
.new(user: User.current, model: user)
|
||||
.call
|
||||
.on_failure do |result|
|
||||
unauthorized_error = result.errors.find { |e| e.type == :error_unauthorized }
|
||||
if unauthorized_error.present?
|
||||
raise Scimitar::ErrorResponse.new(
|
||||
status: 403,
|
||||
detail: "User can't be deleted due to permission absence."
|
||||
)
|
||||
else
|
||||
raise result.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -38,10 +38,10 @@ Rails.application.config.to_prepare do
|
||||
)
|
||||
|
||||
Scimitar::Schema::User.singleton_class.class_eval do
|
||||
prepend ScimitarSchemaExtension::User
|
||||
prepend ScimitarSchemaExtension
|
||||
end
|
||||
|
||||
Scimitar::Schema::Group.singleton_class.class_eval do
|
||||
prepend ScimitarSchemaExtension::Group
|
||||
prepend ScimitarSchemaExtension
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,43 +28,11 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
class OpenProjectNameSchema < Scimitar::Schema::Base
|
||||
def self.scim_attributes
|
||||
@scim_attributes ||= [
|
||||
Scimitar::Schema::Attribute.new(name: "familyName", caseExact: true, type: "string", required: true),
|
||||
Scimitar::Schema::Attribute.new(name: "givenName", caseExact: true, type: "string", required: true)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
class OpenProjectNameComplexType < Scimitar::ComplexTypes::Base
|
||||
set_schema OpenProjectNameSchema
|
||||
end
|
||||
|
||||
module ScimitarSchemaExtension
|
||||
module Group
|
||||
def scim_attributes
|
||||
[
|
||||
Scimitar::Schema::Attribute.new(name: "displayName", caseExact: true, type: "string", required: true),
|
||||
Scimitar::Schema::Attribute.new(name: "members", multiValued: true, complexType: Scimitar::ComplexTypes::ReferenceMember,
|
||||
mutability: "readWrite"),
|
||||
Scimitar::Schema::Attribute.new(name: "externalId", type: "string", caseExact: true, required: true)
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
module User
|
||||
def scim_attributes
|
||||
[
|
||||
Scimitar::Schema::Attribute.new(name: "userName", caseExact: true, type: "string", uniqueness: "server", required: true),
|
||||
Scimitar::Schema::Attribute.new(name: "name", caseExact: true, complexType: OpenProjectNameComplexType, required: true),
|
||||
Scimitar::Schema::Attribute.new(name: "active", type: "boolean"),
|
||||
Scimitar::Schema::Attribute.new(name: "emails", multiValued: true, complexType: Scimitar::ComplexTypes::Email,
|
||||
required: true),
|
||||
Scimitar::Schema::Attribute.new(name: "groups", multiValued: true, complexType: Scimitar::ComplexTypes::ReferenceGroup,
|
||||
mutability: "readOnly"),
|
||||
Scimitar::Schema::Attribute.new(name: "externalId", type: "string", caseExact: true, required: true)
|
||||
]
|
||||
end
|
||||
def scim_attributes
|
||||
super + [Scimitar::Schema::Attribute.new(name: "externalId",
|
||||
type: "string",
|
||||
caseExact: true,
|
||||
required: true)]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -61,26 +61,26 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Groups", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to match("Resources" => contain_exactly({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] }, { "displayName" => group_without_external_id.name,
|
||||
"id" => group_without_external_id.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group_without_external_id.id}",
|
||||
"created" => group_without_external_id.created_at.iso8601,
|
||||
"lastModified" => group_without_external_id.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] }),
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 2)
|
||||
expect(response_body).to match({ "Resources" => contain_exactly({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] }, { "displayName" => group_without_external_id.name,
|
||||
"id" => group_without_external_id.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group_without_external_id.id}",
|
||||
"created" => group_without_external_id.created_at.iso8601,
|
||||
"lastModified" => group_without_external_id.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] }),
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 2 })
|
||||
end
|
||||
|
||||
it "filters results" do
|
||||
@@ -88,29 +88,29 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Groups?filter=#{filter}", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("Resources" => [{ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] }],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 1)
|
||||
expect(response_body).to eq({ "Resources" => [{ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] }],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 1 })
|
||||
|
||||
filter = ERB::Util.url_encode('displayName Eq "NONEXISTENT GROUP NAME"')
|
||||
get "/scim_v2/Groups?filter=#{filter}", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("Resources" => [],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 0)
|
||||
expect(response_body).to eq({ "Resources" => [],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 0 })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -120,9 +120,8 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -136,29 +135,29 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Groups/#{group.id}", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
|
||||
it "excludes specified attributes" do
|
||||
get "/scim_v2/Groups/#{group.id}?excludedAttributes=members", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
expect(response_body["members"]).to be_nil
|
||||
end
|
||||
end
|
||||
@@ -169,9 +168,8 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -194,15 +192,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group = Group.find_by(name: group_name)
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
|
||||
it "creates group without members specified" do
|
||||
@@ -216,15 +214,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group = Group.find_by(name: group_name)
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -234,9 +232,8 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -255,15 +252,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Groups/#{group.id}", "", headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
|
||||
perform_enqueued_jobs
|
||||
assert_performed_jobs 1
|
||||
@@ -272,9 +269,9 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Resource \"#{group.id}\" not found",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "404"
|
||||
{ "detail" => "Resource \"#{group.id}\" not found",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "404" }
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -285,9 +282,8 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -315,15 +311,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group.reload
|
||||
expect(response_body).to match("displayName" => group.name,
|
||||
"externalId" => new_external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"members" => contain_exactly({ "value" => user.id.to_s }, { "value" => admin.id.to_s }),
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to match({ "displayName" => group.name,
|
||||
"externalId" => new_external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"members" => contain_exactly({ "value" => user.id.to_s }, { "value" => admin.id.to_s }),
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -333,9 +329,8 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -360,15 +355,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group.reload
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => new_external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => new_external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
|
||||
it "supports replacing of members" do
|
||||
@@ -390,15 +385,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group.reload
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user2.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user2.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
|
||||
it "supports adding of a member" do
|
||||
@@ -418,16 +413,16 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group.reload
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user1.id.to_s },
|
||||
{ "value" => user2.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [{ "value" => user1.id.to_s },
|
||||
{ "value" => user2.id.to_s }],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
|
||||
it "supports removal of a member" do
|
||||
@@ -446,15 +441,15 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group.reload
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"members" => [],
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
|
||||
it "supports removal of a member with exclusion of members list from the response" do
|
||||
@@ -473,14 +468,14 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
group.reload
|
||||
expect(response_body).to eq("displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"])
|
||||
expect(response_body).to eq({ "displayName" => group.name,
|
||||
"externalId" => external_group_id,
|
||||
"id" => group.id.to_s,
|
||||
"meta" => { "location" => "http://test.host/scim_v2/Groups/#{group.id}",
|
||||
"created" => group.created_at.iso8601,
|
||||
"lastModified" => group.updated_at.iso8601,
|
||||
"resourceType" => "Group" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:Group"] })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -490,9 +485,8 @@ RSpec.describe "SCIM API Groups", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,93 +42,26 @@ RSpec.describe "SCIM API Schemas", with_ee: [:scim_api] do
|
||||
|
||||
describe "GET /scim_v2/Schemas" do
|
||||
context "with the feature flag enabled", with_flag: { scim_api: true } do
|
||||
# rubocop:disable Layout/LineLength
|
||||
it "responds with supported schemas" do
|
||||
get "/scim_v2/Schemas", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body["totalResults"]).to eq(2)
|
||||
expect(response_body["schemas"]).to eq(["urn:ietf:params:scim:api:messages:2.0:ListResponse"])
|
||||
expect(response_body["schemas"]).to eq(["urn:ietf:params:scim:api:messages:2.0:ListResponse"])
|
||||
group_schema = response_body["Resources"].find { |r| r["name"] == "Group" }
|
||||
user_schema = response_body["Resources"].find { |r| r["name"] == "User" }
|
||||
|
||||
expect(group_schema).to eq(
|
||||
"name" => "Group",
|
||||
"id" => "urn:ietf:params:scim:schemas:core:2.0:Group",
|
||||
"description" => "Represents a Group",
|
||||
"meta" => { "resourceType" => "Schema",
|
||||
"location" => "http://test.host/scim_v2/Schemas?name=urn%3Aietf%3Aparams%3Ascim%3Aschemas%3Acore%3A2.0%3AGroup" },
|
||||
"attributes" => [
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => true, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "displayName", "type" => "string" },
|
||||
{ "multiValued" => true,
|
||||
"required" => false,
|
||||
"caseExact" => false,
|
||||
"mutability" => "readWrite",
|
||||
"uniqueness" => "none",
|
||||
"returned" => "default",
|
||||
"type" => "complex",
|
||||
"subAttributes" => [
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => false, "mutability" => "immutable", "uniqueness" => "none", "returned" => "default", "name" => "value", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "immutable", "uniqueness" => "none", "returned" => "default", "name" => "type", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "immutable", "uniqueness" => "none", "returned" => "default", "name" => "display", "type" => "string" }
|
||||
],
|
||||
"name" => "members" },
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => true, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "externalId", "type" => "string" }
|
||||
]
|
||||
)
|
||||
expect(user_schema).to eq(
|
||||
"name" => "User",
|
||||
"id" => "urn:ietf:params:scim:schemas:core:2.0:User",
|
||||
"description" => "Represents a User",
|
||||
"meta" => { "resourceType" => "Schema",
|
||||
"location" => "http://test.host/scim_v2/Schemas?name=urn%3Aietf%3Aparams%3Ascim%3Aschemas%3Acore%3A2.0%3AUser" },
|
||||
"attributes" => [
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => true, "mutability" => "readWrite", "uniqueness" => "server", "returned" => "default", "name" => "userName", "type" => "string" },
|
||||
{ "multiValued" => false,
|
||||
"required" => true,
|
||||
"caseExact" => true,
|
||||
"mutability" => "readWrite",
|
||||
"uniqueness" => "none",
|
||||
"returned" => "default",
|
||||
"type" => "complex",
|
||||
"subAttributes" => [
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => true, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "familyName", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => true, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "givenName", "type" => "string" }
|
||||
],
|
||||
"name" => "name" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "active", "type" => "boolean" },
|
||||
{ "multiValued" => true,
|
||||
"required" => true,
|
||||
"caseExact" => false,
|
||||
"mutability" => "readWrite",
|
||||
"uniqueness" => "none",
|
||||
"returned" => "default",
|
||||
"type" => "complex",
|
||||
"subAttributes" => [
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => false, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "value", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "readOnly", "uniqueness" => "none", "returned" => "default", "name" => "display", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "type", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "primary", "type" => "boolean" }
|
||||
],
|
||||
"name" => "emails" },
|
||||
{ "multiValued" => true,
|
||||
"required" => false,
|
||||
"caseExact" => false,
|
||||
"mutability" => "readOnly",
|
||||
"uniqueness" => "none",
|
||||
"returned" => "default",
|
||||
"type" => "complex",
|
||||
"subAttributes" => [
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => false, "mutability" => "readOnly", "uniqueness" => "none", "returned" => "default", "name" => "value", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "readOnly", "uniqueness" => "none", "returned" => "default", "name" => "display", "type" => "string" },
|
||||
{ "multiValued" => false, "required" => false, "caseExact" => false, "mutability" => "readOnly", "uniqueness" => "none", "returned" => "default", "name" => "type", "type" => "string" }
|
||||
],
|
||||
"name" => "groups" },
|
||||
{ "multiValued" => false, "required" => true, "caseExact" => true, "mutability" => "readWrite", "uniqueness" => "none", "returned" => "default", "name" => "externalId", "type" => "string" }
|
||||
]
|
||||
)
|
||||
external_id_schema = { "multiValued" => false,
|
||||
"required" => true,
|
||||
"caseExact" => true,
|
||||
"mutability" => "readWrite",
|
||||
"uniqueness" => "none",
|
||||
"returned" => "default",
|
||||
"name" => "externalId",
|
||||
"type" => "string" }
|
||||
expect(group_schema["attributes"]).to include(external_id_schema)
|
||||
expect(user_schema["attributes"]).to include(external_id_schema)
|
||||
end
|
||||
# rubocop:enable Layout/LineLength
|
||||
end
|
||||
|
||||
context "with the feature flag disabled", with_flag: { scim_api: false } do
|
||||
@@ -137,9 +70,8 @@ RSpec.describe "SCIM API Schemas", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
+148
-211
@@ -122,11 +122,11 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Users?filter=#{filter_with_nonexisting_rows}", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("Resources" => [],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 0)
|
||||
expect(response_body).to eq({ "Resources" => [],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 0 })
|
||||
end
|
||||
|
||||
it "filters results by externalId" do
|
||||
@@ -158,11 +158,11 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Users?filter=#{filter_with_nonexisting_rows}", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("Resources" => [],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 0)
|
||||
expect(response_body).to eq({ "Resources" => [],
|
||||
"itemsPerPage" => 100,
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
|
||||
"startIndex" => 1,
|
||||
"totalResults" => 0 })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -172,9 +172,8 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -188,21 +187,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Users/#{user.id}", {}, headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => user.mail }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login)
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => user.mail }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -212,9 +211,8 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -249,71 +247,14 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
expect(last_response).to have_http_status(409)
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"detail" => "Operation failed due to a uniqueness constraint: Username has already been taken.",
|
||||
"status" => "409",
|
||||
"scimType" => "uniqueness"
|
||||
{ "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"detail" => "Operation failed due to a uniqueness constraint: Username has already been taken.",
|
||||
"status" => "409",
|
||||
"scimType" => "uniqueness" }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "responds with 400 when email is missing" do
|
||||
group
|
||||
request_body = {
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"externalId" => external_user_id,
|
||||
"userName" => user.login,
|
||||
"name" => {
|
||||
"givenName" => "John",
|
||||
"familyName" => "Doe"
|
||||
},
|
||||
"active" => true,
|
||||
"emails" => []
|
||||
}
|
||||
|
||||
post "/scim_v2/Users/", request_body.to_json, headers
|
||||
|
||||
expect(last_response).to have_http_status(400)
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"detail" => "Invalid resource: Emails is required.",
|
||||
"status" => "400",
|
||||
"scimType" => "invalidValue"
|
||||
)
|
||||
end
|
||||
|
||||
it "responds with 400 when familyName is missing" do
|
||||
group
|
||||
request_body = {
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"externalId" => external_user_id,
|
||||
"userName" => user.login,
|
||||
"name" => {
|
||||
"givenName" => "John"
|
||||
},
|
||||
"active" => true,
|
||||
"emails" => [
|
||||
{
|
||||
"value" => "jdoe@example.com",
|
||||
"type" => "work",
|
||||
"primary" => true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
post "/scim_v2/Users/", request_body.to_json, headers
|
||||
|
||||
expect(last_response).to have_http_status(400)
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"detail" => "Invalid resource: Name familyname is required.",
|
||||
"status" => "400",
|
||||
"scimType" => "invalidValue"
|
||||
)
|
||||
end
|
||||
|
||||
it "creates user with provided data and excludes some attributes" do
|
||||
request_body = {
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
@@ -337,17 +278,17 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
response_body = JSON.parse(last_response.body)
|
||||
created_user = User.find_by(login: "jdoe")
|
||||
expect(created_user).to be_present
|
||||
expect(response_body).to eq("active" => true,
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [],
|
||||
"id" => created_user.id.to_s,
|
||||
"meta" => { "created" => created_user.created_at.iso8601,
|
||||
"lastModified" => created_user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{created_user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => "Doe" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => "jdoe")
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [],
|
||||
"id" => created_user.id.to_s,
|
||||
"meta" => { "created" => created_user.created_at.iso8601,
|
||||
"lastModified" => created_user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{created_user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => "Doe" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => "jdoe" })
|
||||
end
|
||||
|
||||
it "creates user with provided data" do
|
||||
@@ -373,21 +314,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
response_body = JSON.parse(last_response.body)
|
||||
created_user = User.find_by(login: "jdoe")
|
||||
expect(created_user).to be_present
|
||||
expect(response_body).to eq("active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => "jdoe@example.com" }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [],
|
||||
"id" => created_user.id.to_s,
|
||||
"meta" => { "created" => created_user.created_at.iso8601,
|
||||
"lastModified" => created_user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{created_user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => "Doe",
|
||||
"givenName" => "John" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => "jdoe")
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => "jdoe@example.com" }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [],
|
||||
"id" => created_user.id.to_s,
|
||||
"meta" => { "created" => created_user.created_at.iso8601,
|
||||
"lastModified" => created_user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{created_user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => "Doe",
|
||||
"givenName" => "John" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => "jdoe" })
|
||||
end
|
||||
|
||||
it "creates user with any email type string provided" do
|
||||
@@ -411,21 +352,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
created_user = User.find_by(login: "jdoe")
|
||||
expect(response_body).to eq("active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => "jdoe@example.com" }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [],
|
||||
"id" => created_user.id.to_s,
|
||||
"meta" => { "created" => created_user.created_at.iso8601,
|
||||
"lastModified" => created_user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{created_user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => "Doe",
|
||||
"givenName" => "John" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => "jdoe")
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => "jdoe@example.com" }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [],
|
||||
"id" => created_user.id.to_s,
|
||||
"meta" => { "created" => created_user.created_at.iso8601,
|
||||
"lastModified" => created_user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{created_user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => "Doe",
|
||||
"givenName" => "John" },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => "jdoe" })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -435,9 +376,8 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -458,21 +398,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
get "/scim_v2/Users/#{user.id}", "", headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("active" => false,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => user.mail }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login)
|
||||
expect(response_body).to eq({ "active" => false,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => user.mail }],
|
||||
"externalId" => external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login })
|
||||
|
||||
perform_enqueued_jobs
|
||||
assert_performed_jobs 1
|
||||
@@ -481,9 +421,9 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Resource \"#{user.id}\" not found",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "404"
|
||||
{ "detail" => "Resource \"#{user.id}\" not found",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "404" }
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -494,9 +434,9 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
delete "/scim_v2/Users/#{user.id}", "", headers
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq("schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"detail" => "Action forbidden: insufficient permissions.",
|
||||
"status" => "403")
|
||||
expect(response_body).to eq({ "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"detail" => "User can't be deleted due to permission absence.",
|
||||
"status" => "403" })
|
||||
expect(last_response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
@@ -508,9 +448,8 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -546,21 +485,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
user.reload
|
||||
expect(response_body).to eq("active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => request_body["emails"].first["value"] }],
|
||||
"externalId" => new_external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => request_body["name"]["familyName"],
|
||||
"givenName" => request_body["name"]["givenName"] },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => request_body["userName"])
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => request_body["emails"].first["value"] }],
|
||||
"externalId" => new_external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => request_body["name"]["familyName"],
|
||||
"givenName" => request_body["name"]["givenName"] },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => request_body["userName"] })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -570,9 +509,8 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
@@ -599,21 +537,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
user.reload
|
||||
expect(response_body).to eq("active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => user.mail }],
|
||||
"externalId" => new_external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login)
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => user.mail }],
|
||||
"externalId" => new_external_user_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login })
|
||||
end
|
||||
|
||||
it "changes email value" do
|
||||
@@ -636,21 +574,21 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
user.reload
|
||||
expect(response_body).to eq("active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => new_email_value }],
|
||||
"externalId" => user.scim_external_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login)
|
||||
expect(response_body).to eq({ "active" => true,
|
||||
"emails" => [{ "primary" => true,
|
||||
"type" => "work",
|
||||
"value" => new_email_value }],
|
||||
"externalId" => user.scim_external_id,
|
||||
"groups" => [{ "value" => group.id.to_s }],
|
||||
"id" => user.id.to_s,
|
||||
"meta" => { "created" => user.created_at.iso8601,
|
||||
"lastModified" => user.updated_at.iso8601,
|
||||
"location" => "http://test.host/scim_v2/Users/#{user.id}",
|
||||
"resourceType" => "User" },
|
||||
"name" => { "familyName" => user.lastname,
|
||||
"givenName" => user.firstname },
|
||||
"schemas" => ["urn:ietf:params:scim:schemas:core:2.0:User"],
|
||||
"userName" => user.login })
|
||||
end
|
||||
end
|
||||
|
||||
@@ -660,9 +598,8 @@ RSpec.describe "SCIM API Users", with_ee: [:scim_api] do
|
||||
|
||||
response_body = JSON.parse(last_response.body)
|
||||
expect(response_body).to eq(
|
||||
"detail" => "Requires authentication",
|
||||
"schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401"
|
||||
{ "detail" => "Requires authentication", "schemas" => ["urn:ietf:params:scim:api:messages:2.0:Error"],
|
||||
"status" => "401" }
|
||||
)
|
||||
expect(last_response).to have_http_status(401)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user