trabajo-afectivo/spec/requests/user/permission_spec.rb

679 lines
17 KiB
Ruby

# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
require 'rails_helper'
RSpec.describe 'User endpoint', type: :request do
let(:role_with_admin_user_permissions) do
create(:role).tap do |role|
role.permission_grant('admin.user')
end
end
let(:admin_with_admin_user_permissions) { create(:user, roles: [role_with_admin_user_permissions]) }
let(:role_without_admin_user_permissions) do
create(:role).tap do |role|
role.permission_grant('admin.tag')
end
end
let(:admin_without_admin_user_permissions) { create(:user, roles: [role_without_admin_user_permissions]) }
describe 'User creation' do
let(:attributes) { attributes_params_for(:user) }
it 'responds forbidden for customer' do
requester = create(:customer)
authenticated_as(requester)
expect do
post api_v1_users_path, params: attributes
end.to not_change {
User.count
}
expect(response).to have_http_status(:forbidden)
end
context 'privileged attributes' do
context 'group assignment' do
# group access assignment is in general only valid for agents
# see HasGroups.groups_access_permission?
let(:agent_attributes) do
attributes.merge(
roles: Role.where(name: 'Agent').map(&:name),
)
end
shared_examples 'group assignment' do |map_method_id|
it 'responds success for admin.user' do
authenticated_as(admin_with_admin_user_permissions)
expect do
post api_v1_users_path, params: payload
end.to change(User, :count).by(1)
expect(response).to have_http_status(:success)
expect(User.last.send(map_method_id)).to eq(send(map_method_id))
end
it 'responds forbidden for sub admin without admin.user' do
authenticated_as(admin_without_admin_user_permissions)
expect do
post api_v1_users_path, params: payload
end.to not_change {
User.count
}
expect(response).to have_http_status(:forbidden)
end
it 'responds successful for agent but removes assignment' do
requester = create(:agent)
authenticated_as(requester)
expect do
post api_v1_users_path, params: payload
end.to change(User, :count).by(1)
expect(response).to have_http_status(:success)
expect(User.last.send(map_method_id)).to be_blank
end
end
context 'parameter groups' do
let(:group_names_access_map) do
Group.all.to_h { |g| [g.name, ['full']] }
end
let(:payload) do
agent_attributes.merge(
groups: group_names_access_map,
)
end
it_behaves_like 'group assignment', :group_names_access_map
end
context 'parameter group_ids' do
let(:group_ids_access_map) do
Group.all.to_h { |g| [g.id, ['full']] }
end
let(:payload) do
agent_attributes.merge(
group_ids: group_ids_access_map,
)
end
it_behaves_like 'group assignment', :group_ids_access_map
end
end
context 'role assignment' do
shared_examples 'role assignment' do
let(:privileged) { Role.where(name: 'Admin') }
it 'responds success for admin.user' do
authenticated_as(admin_with_admin_user_permissions)
expect do
post api_v1_users_path, params: payload
end.to change(User, :count).by(1)
expect(response).to have_http_status(:success)
expect(User.last.roles).to eq(privileged)
end
it 'responds forbidden for sub admin without admin.user' do
authenticated_as(admin_without_admin_user_permissions)
expect do
post api_v1_users_path, params: payload
end.to not_change {
User.count
}
expect(response).to have_http_status(:forbidden)
end
it 'responds successful for agent but removes assignment' do
requester = create(:agent)
authenticated_as(requester)
expect do
post api_v1_users_path, params: payload
end.to change(User, :count).by(1)
expect(response).to have_http_status(:success)
expect(User.last.roles).to eq(Role.signup_roles)
end
end
context 'parameter roles' do
let(:payload) do
attributes.merge(
roles: privileged.map(&:name),
)
end
it_behaves_like 'role assignment'
end
context 'parameter role_ids' do
let(:payload) do
attributes.merge(
role_ids: privileged.map(&:id),
)
end
it_behaves_like 'role assignment'
end
end
end
end
describe 'User update' do
def authorized_update_request(requester:, requested:)
authenticated_as(requester)
expect do
put api_v1_update_user_path(requested), params: cleaned_params_for(requested).merge(firstname: 'Changed')
end.to change {
requested.reload.firstname
}
expect(response).to have_http_status(:success)
end
def forbidden_update_request(requester:, requested:)
authenticated_as(requester)
expect do
put api_v1_update_user_path(requested), params: cleaned_params_for(requested).merge(firstname: 'Changed')
end.to not_change {
requested.reload.attributes.tap do |attributes|
# take attributes as they are for different users
next if requester != requested
# last_login and updated_at change every time
# even if the record itself should not change
attributes.delete_if do |key, _value|
%w[last_login updated_at].include?(key)
end
end
}
expect(response).to have_http_status(:forbidden)
end
context 'request by admin.user' do
let(:requester) { admin_with_admin_user_permissions }
it 'is successful for same admin' do
authorized_update_request(
requester: requester,
requested: requester,
)
end
it 'is successful for other admin' do
authorized_update_request(
requester: requester,
requested: create(:admin),
)
end
it 'is successful for agent' do
authorized_update_request(
requester: requester,
requested: create(:agent),
)
end
it 'is successful for customer' do
authorized_update_request(
requester: requester,
requested: create(:customer),
)
end
end
context 'request by sub admin without admin.user' do
let(:requester) { admin_without_admin_user_permissions }
it 'is forbidden for same admin' do
forbidden_update_request(
requester: requester,
requested: requester,
)
end
it 'is forbidden for other admin' do
forbidden_update_request(
requester: requester,
requested: create(:admin),
)
end
it 'is forbidden for agent' do
forbidden_update_request(
requester: requester,
requested: create(:agent),
)
end
it 'is forbidden for customer' do
forbidden_update_request(
requester: requester,
requested: create(:customer),
)
end
end
context 'request by agent' do
let(:requester) { create(:agent) }
it 'is forbidden for admin' do
forbidden_update_request(
requester: requester,
requested: create(:admin),
)
end
it 'is forbidden same agent' do
forbidden_update_request(
requester: requester,
requested: requester,
)
end
it 'is forbidden for other agent' do
forbidden_update_request(
requester: requester,
requested: create(:agent),
)
end
it 'is successful for customer' do
authorized_update_request(
requester: requester,
requested: create(:customer),
)
end
end
context 'request by customer' do
let(:requester) { create(:customer) }
it 'is forbidden for admin' do
forbidden_update_request(
requester: requester,
requested: create(:admin),
)
end
it 'is forbidden for agent' do
forbidden_update_request(
requester: requester,
requested: create(:agent),
)
end
it 'is forbidden for same customer' do
forbidden_update_request(
requester: requester,
requested: requester,
)
end
it 'is forbidden for other customer' do
forbidden_update_request(
requester: requester,
requested: create(:customer),
)
end
it 'is forbidden for same organization' do
same_organization = create(:organization)
requester.update!(organization: same_organization)
forbidden_update_request(
requester: requester,
requested: create(:customer, organization: same_organization),
)
end
end
context 'privileged attributes' do
let(:requested) { create(:user) }
let(:attribute) { privileged.keys.first }
let(:payload) { cleaned_params_for(requested).merge(privileged) }
def value_of_attribute
# we need to call .to_a otherwise Rails will load the
# ActiveRecord::Associations::CollectionProxy
# on comparsion which is to late
requested.reload.public_send(attribute).to_a
end
shared_examples 'admin types requests' do
it 'responds success for admin.user' do
authenticated_as(admin_with_admin_user_permissions)
expect do
put api_v1_update_user_path(requested), params: payload
end.to change {
value_of_attribute
}
expect(response).to have_http_status(:success)
end
it 'responds forbidden for sub admin without admin.user' do
authenticated_as(admin_without_admin_user_permissions)
expect do
put api_v1_update_user_path(requested), params: payload
end.to not_change {
value_of_attribute
}
expect(response).to have_http_status(:forbidden)
end
end
shared_examples 'permitted agent update' do
it 'responds successful for agent but removes assignment' do
requester = create(:agent)
authenticated_as(requester)
expect do
put api_v1_update_user_path(requested), params: payload
end.to change {
value_of_attribute
}
expect(response).to have_http_status(:success)
end
end
shared_examples 'forbidden agent update' do
it 'responds successful for agent but removes assignment' do
requester = create(:agent)
authenticated_as(requester)
expect do
put api_v1_update_user_path(requested), params: payload
end.to not_change {
value_of_attribute
}
expect(response).to have_http_status(:success)
end
end
context 'group assignment' do
context 'parameter groups' do
let(:privileged) do
{
groups: Group.all.to_h { |g| [g.name, ['full']] }
}
end
it_behaves_like 'admin types requests'
it_behaves_like 'forbidden agent update'
end
context 'parameter group_ids' do
let(:privileged) do
{
group_ids: Group.all.to_h { |g| [g.id, ['full']] }
}
end
it_behaves_like 'admin types requests'
it_behaves_like 'forbidden agent update'
end
end
context 'role assignment' do
let(:admin_role) { Role.where(name: 'Admin') }
context 'parameter roles' do
let(:privileged) do
{
roles: admin_role.map(&:name),
}
end
it_behaves_like 'admin types requests'
it_behaves_like 'forbidden agent update'
end
context 'parameter role_ids' do
let(:privileged) do
{
role_ids: admin_role.map(&:id),
}
end
it_behaves_like 'admin types requests'
it_behaves_like 'forbidden agent update'
end
end
context 'organization assignment' do
let(:new_organizations) { create_list(:organization, 2) }
context 'parameter organizations' do
let(:privileged) do
{
organizations: new_organizations.map(&:name),
}
end
it_behaves_like 'admin types requests'
it_behaves_like 'permitted agent update'
end
context 'parameter organization_ids' do
let(:privileged) do
{
organization_ids: new_organizations.map(&:id),
}
end
it_behaves_like 'admin types requests'
it_behaves_like 'permitted agent update'
end
end
end
end
describe 'User deletion' do
def authorized_destroy_request(requester:, requested:)
authenticated_as(requester)
delete api_v1_delete_user_path(requested)
expect(response).to have_http_status(:success)
expect(requested).not_to exist_in_database
end
def forbidden_destroy_request(requester:, requested:)
authenticated_as(requester)
delete api_v1_delete_user_path(requested)
expect(response).to have_http_status(:forbidden)
expect(requested).to exist_in_database
end
context 'request by admin.user' do
let(:requester) { admin_with_admin_user_permissions }
it 'is successful for same admin' do
authorized_destroy_request(
requester: requester,
requested: requester,
)
end
it 'is successful for other admin' do
authorized_destroy_request(
requester: requester,
requested: create(:admin),
)
end
it 'is successful for agent' do
authorized_destroy_request(
requester: requester,
requested: create(:agent),
)
end
it 'is successful for customer' do
authorized_destroy_request(
requester: requester,
requested: create(:customer),
)
end
end
context 'request by sub admin without admin.user' do
let(:requester) { admin_without_admin_user_permissions }
it 'is forbidden for same admin' do
forbidden_destroy_request(
requester: requester,
requested: requester,
)
end
it 'is forbidden for other admin' do
forbidden_destroy_request(
requester: requester,
requested: create(:admin),
)
end
it 'is forbidden for agent' do
forbidden_destroy_request(
requester: requester,
requested: create(:agent),
)
end
it 'is forbidden for customer' do
forbidden_destroy_request(
requester: requester,
requested: create(:customer),
)
end
end
context 'request by agent' do
let(:requester) { create(:agent) }
it 'is forbidden for admin' do
forbidden_destroy_request(
requester: requester,
requested: create(:admin),
)
end
it 'is forbidden same agent' do
forbidden_destroy_request(
requester: requester,
requested: requester,
)
end
it 'is forbidden for other agent' do
forbidden_destroy_request(
requester: requester,
requested: create(:agent),
)
end
it 'is forbidden for customer' do
forbidden_destroy_request(
requester: requester,
requested: create(:customer),
)
end
end
context 'request by customer' do
let(:requester) { create(:customer) }
it 'is forbidden for admin' do
forbidden_destroy_request(
requester: requester,
requested: create(:admin),
)
end
it 'is forbidden for agent' do
forbidden_destroy_request(
requester: requester,
requested: create(:agent),
)
end
it 'is forbidden for same customer' do
forbidden_destroy_request(
requester: requester,
requested: requester,
)
end
it 'is forbidden for other customer' do
forbidden_destroy_request(
requester: requester,
requested: create(:customer),
)
end
it 'is forbidden for same organization' do
same_organization = create(:organization)
requester.update!(organization: same_organization)
forbidden_destroy_request(
requester: requester,
requested: create(:customer, organization: same_organization),
)
end
end
end
end