spec/unit/controllers/runtime/users_controller_spec.rb
require 'spec_helper'
## NOTICE: Prefer request specs over controller specs as per ADR #0003 ##
module VCAP::CloudController
RSpec.describe VCAP::CloudController::UsersController do
let(:uaa_client) { instance_double(UaaClient) }
before do
allow(UaaClient).to receive(:new).and_return(uaa_client)
end
describe 'Query Parameters' do
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:space_guid) }
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:organization_guid) }
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:managed_organization_guid) }
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:billing_managed_organization_guid) }
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:audited_organization_guid) }
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:managed_space_guid) }
it { expect(VCAP::CloudController::UsersController).to be_queryable_by(:audited_space_guid) }
end
describe 'Attributes' do
it do
expect(VCAP::CloudController::UsersController).to have_creatable_attributes({
guid: { type: 'string', required: true },
admin: { type: 'bool', default: false },
space_guids: { type: '[string]' },
organization_guids: { type: '[string]' },
managed_organization_guids: { type: '[string]' },
billing_managed_organization_guids: { type: '[string]' },
audited_organization_guids: { type: '[string]' },
managed_space_guids: { type: '[string]' },
audited_space_guids: { type: '[string]' },
default_space_guid: { type: 'string' }
})
end
it do
expect(VCAP::CloudController::UsersController).to have_updatable_attributes({
admin: { type: 'bool' },
space_guids: { type: '[string]' },
organization_guids: { type: '[string]' },
managed_organization_guids: { type: '[string]' },
billing_managed_organization_guids: { type: '[string]' },
audited_organization_guids: { type: '[string]' },
managed_space_guids: { type: '[string]' },
audited_space_guids: { type: '[string]' },
default_space_guid: { type: 'string' }
})
end
end
describe 'Associations' do
it do
expect(VCAP::CloudController::UsersController).to have_nested_routes(
{
spaces: %i[get put delete],
organizations: %i[get put delete],
managed_organizations: %i[get put delete],
billing_managed_organizations: %i[get put delete],
audited_organizations: %i[get put delete],
managed_spaces: %i[get put delete],
audited_spaces: %i[get put delete]
}
)
end
end
describe 'permissions' do
include_context 'permissions'
before do
@obj_a = member_a
allow(uaa_client).to receive(:usernames_for_ids).and_return({})
end
context 'normal user' do
before { @obj_b = member_b }
let(:member_a) { @org_a_manager }
let(:member_b) { @space_a_manager }
include_examples 'permission enumeration', 'User',
name: 'user',
path: '/v2/users',
enumerate: :not_allowed
end
context 'admin user' do
let(:member_a) { User.make }
let(:enumeration_expectation_a) { User.order(:id).limit(50) }
include_examples 'permission enumeration', 'Admin',
name: 'user',
path: '/v2/users',
enumerate: proc { User.count },
permissions_overlap: true,
user_opts: { admin: true }
end
end
describe 'GET /v2/users' do
let(:greg) { User.make }
let(:timothy) { User.make }
before do
set_current_user(greg, admin: true)
allow(uaa_client).to receive(:usernames_for_ids).and_return({
greg.guid => 'Greg',
timothy.guid => 'Timothy'
})
end
it 'includes the usernames' do
get '/v2/users'
users = parsed_response['resources']
expect(users[0]['entity']['username']).to eq('Greg')
expect(users[1]['entity']['username']).to eq('Timothy')
end
end
describe 'GET /v2/users/:guid' do
let(:greg) { User.make }
before do
set_current_user(greg, admin: true)
allow(uaa_client).to receive(:usernames_for_ids).and_return({
greg.guid => 'Greg'
})
end
it 'includes the username' do
get "/v2/users/#{greg.guid}"
expect(parsed_response['entity']['username']).to eq('Greg')
end
end
describe 'GET /v2/users/:guid/organizations' do
let(:mgr) { User.make }
let(:user) { User.make }
let(:org) { Organization.make(manager_guids: [mgr.guid], user_guids: [user.guid]) }
before { set_current_user(user) }
it 'allows the user' do
get "/v2/users/#{user.guid}/organizations"
expect(last_response.status).to eq(200), last_response.body
end
it 'disallows a different user' do
get "/v2/users/#{mgr.guid}/organizations"
expect(last_response.status).to eq(403)
end
end
describe 'assigning org roles' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
let(:other_user) { User.make(username: 'other_user') }
let(:expected_response) do
{
'metadata' => {
'guid' => other_user.guid,
'url' => "/v2/users/#{other_user.guid}",
'created_at' => iso8601,
'updated_at' => iso8601
},
'entity' => {
'admin' => false,
'active' => false,
'default_space_guid' => nil,
'username' => 'other_user',
'spaces_url' => "/v2/users/#{other_user.guid}/spaces",
'organizations_url' => "/v2/users/#{other_user.guid}/organizations",
'managed_organizations_url' => "/v2/users/#{other_user.guid}/managed_organizations",
'billing_managed_organizations_url' => "/v2/users/#{other_user.guid}/billing_managed_organizations",
'audited_organizations_url' => "/v2/users/#{other_user.guid}/audited_organizations",
'managed_spaces_url' => "/v2/users/#{other_user.guid}/managed_spaces",
'audited_spaces_url' => "/v2/users/#{other_user.guid}/audited_spaces"
}
}
end
before do
allow(uaa_client).to receive(:usernames_for_ids).and_return({ other_user.guid => other_user.username })
end
describe 'PUT /v2/users/:guid/audited_organizations/:org_guid' do
let(:event_type) { 'audit.user.organization_auditor_add' }
before do
set_current_user(user)
org.add_user(other_user)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds and creates an appropriate audit event and creates the generated org role a guid' do
put "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
expect(last_response.status).to eq(201)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
created_role = OrganizationAuditor.find(user_id: other_user.id, organization_id: org.id)
expect(created_role.guid).to be_a_guid
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
put "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
expect(last_response.status).to eq(201)
expect(org.auditors).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
end
context 'as an org user' do
before do
org.add_user(user)
end
it 'fails and does not create an audit event' do
put "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
expect(last_response.status).to eq(403)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).to be_nil
end
end
end
describe 'PUT /v2/users/:guid/managed_organizations/:org_guid' do
let(:event_type) { 'audit.user.organization_manager_add' }
before do
set_current_user(user)
org.add_user(other_user)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds and creates an appropriate audit event creates the org role guid' do
put "/v2/users/#{other_user.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to eq(201)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
created_role = OrganizationManager.find(user_id: other_user.id, organization_id: org.id)
expect(created_role.guid).to be_a_guid
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/managed_organizations/#{org.guid}"
put "/v2/users/#{other_user.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to eq(201)
expect(org.managers).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
end
context 'as an org user' do
before do
org.add_user(user)
end
it 'fails and does not create an audit event' do
put "/v2/users/#{other_user.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to eq(403)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).to be_nil
end
end
end
describe 'PUT /v2/users/:guid/billing_managed_organizations/:org_guid' do
let(:event_type) { 'audit.user.organization_billing_manager_add' }
before do
set_current_user(user)
org.add_user(other_user)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds and creates an appropriate audit event and creates the org role guid' do
put "/v2/users/#{other_user.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to eq(201)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
created_role = OrganizationBillingManager.find(user_id: other_user.id, organization_id: org.id)
expect(created_role.guid).to be_a_guid
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/billing_managed_organizations/#{org.guid}"
put "/v2/users/#{other_user.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to eq(201)
expect(org.billing_managers).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
end
context 'as an org user' do
before do
org.add_user(user)
end
it 'fails and does not create an audit event' do
put "/v2/users/#{other_user.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to eq(403)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).to be_nil
end
end
end
describe 'PUT /v2/users/:guid/organizations/:org_guid' do
let(:event_type) { 'audit.user.organization_user_add' }
before do
set_current_user(user)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds and creates an appropriate audit event and creates the org role guid' do
put "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(201)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
created_role = OrganizationUser.find(user_id: other_user.id, organization_id: org.id)
expect(created_role.guid).to be_a_guid
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
put "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(201)
expect(org.users).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
end
context 'as an org user' do
before do
org.add_user(user)
end
it 'fails and does not create an audit event' do
put "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(403)
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).to be_nil
end
end
end
end
describe 'DELETE /v2/users/:guid/audited_organizations/:org_guid' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
let(:event_type) { 'audit.user.organization_auditor_remove' }
before do
set_current_user(user)
org.add_auditor(user)
allow(uaa_client).to receive(:usernames_for_ids).and_return({ user.guid => user.username })
end
context 'when acting on behalf of the current user' do
it 'succeeds' do
delete "/v2/users/#{user.guid}/audited_organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{user.guid}/audited_organizations/#{org.guid}"
event = Event.find(type: event_type, actee: user.guid)
expect(event).not_to be_nil
end
end
context 'when acting on another user' do
let(:other_user) { User.make }
before do
org.add_auditor(other_user)
end
it 'fails with 403' do
delete "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
end
context 'as a manager' do
context 'when acting on another user' do
let(:other_user) { User.make }
before do
org.add_manager(user)
org.add_auditor(other_user)
allow(uaa_client).to receive(:usernames_for_ids).and_return({ other_user.guid => other_user.username })
end
it 'succeeds' do
delete "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{other_user.guid}/audited_organizations/#{org.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
end
end
end
end
describe 'DELETE /v2/users/:guid/audited_spaces/:space_guid' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
let(:event_type) { 'audit.user.space_auditor_remove' }
let(:other_user) { User.make }
before do
set_current_user(user)
org.add_user(user)
org.add_auditor(user)
space.add_auditor(user)
allow(uaa_client).to receive(:usernames_for_ids).and_return({
user.guid => user.username,
other_user.guid => other_user.username
})
end
context 'when acting on behalf of the current user' do
it 'succeeds' do
delete "/v2/users/#{user.guid}/audited_spaces/#{space.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{user.guid}/audited_spaces/#{space.guid}"
event = Event.find(type: event_type, actee: user.guid)
expect(event).not_to be_nil
end
end
context 'when acting on another user' do
before do
org.add_user(other_user)
org.add_auditor(other_user)
space.add_auditor(other_user)
end
it 'fails with 403' do
delete "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
end
context 'as a manager' do
context 'when acting on another user' do
before do
org.add_manager(user)
space.add_manager(user)
org.add_user(other_user)
org.add_auditor(other_user)
space.add_auditor(other_user)
end
it 'succeeds' do
delete "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
end
end
end
end
describe 'DELETE /v2/users/:guid/billing_managed_organizations/:org_guid' do
let(:space) { Space.make }
let(:user) { User.make }
let(:billing_manager) { User.make }
let(:org) { space.organization }
let(:event_type) { 'audit.user.organization_billing_manager_remove' }
before do
org.add_user user
org.add_billing_manager billing_manager
allow(uaa_client).to receive(:usernames_for_ids).and_return({})
org.save
end
describe 'removing the last billing manager' do
context 'as an admin' do
before do
set_current_user(user)
set_current_user_as_admin
end
it 'is allowed' do
delete "/v2/users/#{billing_manager.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{billing_manager.guid}/billing_managed_organizations/#{org.guid}"
event = Event.find(type: event_type, actee: billing_manager.guid)
expect(event).not_to be_nil
end
end
context 'as the billing manager' do
before { set_current_user(billing_manager) }
it 'removing yourself is not allowed' do
delete "/v2/users/#{billing_manager.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to be(403)
expect(decoded_response['code']).to eq(30_005)
end
end
end
describe 'when there are other billing managers' do
let(:other_billing_manager) { User.make }
before do
org.add_billing_manager other_billing_manager
set_current_user billing_manager
end
describe 'removing oneself' do
it 'is allowed' do
set_current_user(billing_manager)
delete "/v2/users/#{billing_manager.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{billing_manager.guid}/billing_managed_organizations/#{org.guid}"
event = Event.find(type: event_type, actee: billing_manager.guid)
expect(event).not_to be_nil
end
end
describe 'removing other billing manager' do
it 'is not allowed' do
set_current_user(billing_manager)
delete "/v2/users/#{other_billing_manager.guid}/billing_managed_organizations/#{org.guid}"
expect(last_response.status).to be(403)
expect(decoded_response['code']).to eq(10_003)
end
end
end
end
describe 'DELETE /v2/users/:guid/managed_organizations/:org_guid' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:org_manager) { User.make(username: 'org manager') }
let(:event_type) { 'audit.user.organization_manager_remove' }
before do
org.add_user org_manager
org.add_manager org_manager
allow(uaa_client).to receive(:usernames_for_ids).and_return({
org_manager.guid => org_manager.username
})
end
describe 'removing the last org manager' do
context 'as an admin' do
let(:admin) { User.make(username: 'admin') }
before do
set_current_user admin
set_current_user_as_admin
allow(uaa_client).to receive(:usernames_for_ids).and_return({
org_manager.guid => org_manager.username
})
end
it 'is allowed' do
delete "/v2/users/#{org_manager.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{org_manager.guid}/managed_organizations/#{org.guid}"
event = Event.find(type: event_type, actee: org_manager.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('org manager')
end
end
context 'as the lone org manager' do
it 'is not allowed' do
set_current_user(org_manager)
delete "/v2/users/#{org_manager.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to be(403)
expect(decoded_response['code']).to eq(30_004)
end
end
end
describe 'when there are other managers' do
before { org.add_manager User.make }
describe 'removing oneself' do
before { set_current_user(org_manager) }
it 'is allowed' do
delete "/v2/users/#{org_manager.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{org_manager.guid}/managed_organizations/#{org.guid}"
event = Event.find(type: event_type, actee: org_manager.guid)
expect(event).not_to be_nil
end
end
context 'as a non-admin non-manager' do
let(:user) { User.make }
before do
org.add_user user
set_current_user user
end
it 'is not allowed' do
delete "/v2/users/#{org_manager.guid}/managed_organizations/#{org.guid}"
expect(last_response.status).to be(403)
expect(decoded_response['code']).to eq(10_003)
end
end
end
end
describe 'DELETE /v2/users/:guid/organizations/:org_guid' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
let(:event_type) { 'audit.user.organization_user_remove' }
before do
set_current_user(user)
org.add_user(user)
allow(uaa_client).to receive(:usernames_for_ids).and_return({ user.guid => user.username })
end
context 'as an org user' do
it 'can not remove itself' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(30_006)
end
context 'when acting on another org user' do
let(:other_user) { User.make }
before do
org.add_user(other_user)
end
it 'fails with 403' do
delete "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
end
end
context 'as a manager' do
before do
org.add_manager(user)
end
context 'when there are other managers' do
before do
org.add_manager(User.make)
end
it 'can remove itself' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
event = Event.find(type: event_type, actee: user.guid)
expect(event).not_to be_nil
end
end
it 'cannot remove itself if it is the only manager' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(403)
end
end
context 'as a billing manager' do
before do
org.add_billing_manager(user)
end
context 'when there are other billing managers' do
before do
org.add_billing_manager(User.make)
end
it 'can remove itself' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
event = Event.find(type: event_type, actee: user.guid)
expect(event).not_to be_nil
end
end
it 'cannot remove itself if it is the only billing manager' do
delete "/v2/users/#{user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(403)
end
end
context 'as an admin' do
context 'when acting on another user' do
let(:other_user) { User.make }
before do
org.add_user other_user
set_current_user_as_admin
allow(uaa_client).to receive(:usernames_for_ids).and_return({ other_user.guid => other_user.username })
end
it 'succeeds' do
delete "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{other_user.guid}/organizations/#{org.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
end
end
end
end
describe 'DELETE /v2/users/:guid/managed_spaces/:space_guid' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
let(:other_user) { User.make(username: 'other_user') }
let(:event_type) { 'audit.user.space_manager_remove' }
before do
set_current_user(user)
allow(uaa_client).to receive(:usernames_for_ids).and_return({ other_user.guid => other_user.username })
end
context 'as a manager' do
before do
org.add_user(user)
space.add_manager(user)
end
context 'when acting on another user' do
before do
org.add_user(other_user)
space.add_manager(other_user)
end
it 'succeeds' do
delete "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
end
end
context 'when acting on oneself' do
it 'succeeds' do
delete "/v2/users/#{user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{user.guid}/managed_spaces/#{space.guid}"
event = Event.find(type: event_type, actee: user.guid)
expect(event).not_to be_nil
end
end
end
context 'as a non-manager' do
context 'when acting on another user' do
it 'fails with a 403' do
delete "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(403)
end
end
end
end
describe 'DELETE /v2/users/:guid/spaces/:space_guid' do
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
let(:event_type) { 'audit.user.space_developer_remove' }
let(:other_user) { User.make(username: 'other user') }
before do
set_current_user(user)
org.add_user(user)
space.add_developer(user)
allow(uaa_client).to receive(:usernames_for_ids).and_return({
other_user.guid => other_user.username
})
end
context 'when acting on behalf of the current user' do
it 'succeeds' do
delete "/v2/users/#{user.guid}/spaces/#{space.guid}"
expect(last_response.status).to eq(204)
expect(Space.all).to include(space)
end
it 'creates an appropriate event' do
delete "/v2/users/#{user.guid}/spaces/#{space.guid}"
event = Event.find(type: event_type, actee: user.guid)
expect(event).not_to be_nil
end
end
context 'when acting on another user' do
before do
org.add_user(other_user)
space.add_developer(other_user)
end
it 'fails with 403' do
delete "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
end
context 'as a manager' do
context 'when acting on another user' do
before do
org.add_manager(user)
space.add_manager(user)
org.add_user(other_user)
space.add_developer(other_user)
end
it 'succeeds' do
delete "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
expect(last_response.status).to eq(204)
end
it 'creates an appropriate event' do
delete "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq(other_user.username)
end
end
end
end
describe 'assigning space roles' do
let(:other_user) { User.make(username: 'other_user') }
let(:space) { Space.make }
let(:org) { space.organization }
let(:user) { User.make }
before do
allow(uaa_client).to receive(:usernames_for_ids).and_return({ other_user.guid => other_user.username })
end
describe 'PUT /v2/users/:guid/audited_spaces/:space_guid' do
let(:event_type) { 'audit.user.space_auditor_add' }
let(:expected_response) do
{
'metadata' => {
'guid' => other_user.guid,
'url' => "/v2/users/#{other_user.guid}",
'created_at' => iso8601,
'updated_at' => iso8601
},
'entity' => {
'admin' => false,
'active' => false,
'default_space_guid' => nil,
'username' => 'other_user',
'spaces_url' => "/v2/users/#{other_user.guid}/spaces",
'organizations_url' => "/v2/users/#{other_user.guid}/organizations",
'managed_organizations_url' => "/v2/users/#{other_user.guid}/managed_organizations",
'billing_managed_organizations_url' => "/v2/users/#{other_user.guid}/billing_managed_organizations",
'audited_organizations_url' => "/v2/users/#{other_user.guid}/audited_organizations",
'managed_spaces_url' => "/v2/users/#{other_user.guid}/managed_spaces",
'audited_spaces_url' => "/v2/users/#{other_user.guid}/audited_spaces"
}
}
end
before do
set_current_user(user)
org.add_user(user)
org.add_manager(user)
space.add_manager(user)
org.add_user(other_user)
end
it 'fails with 403' do
put "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds' do
put "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
expect(last_response.status).to eq(201)
auditors = space.auditors
expect(auditors).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
expect(last_response.status).to eq(201)
expect(space.auditors).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
it 'creates an appropriate event' do
put "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
end
it 'creates the appropriate role with a guid' do
put "/v2/users/#{other_user.guid}/audited_spaces/#{space.guid}"
created_role = SpaceAuditor.find(user_id: other_user.id, space_id: space.id)
expect(created_role.guid).to be_a_guid
end
end
end
describe 'PUT /v2/users/:guid/managed_spaces/:space_guid' do
let(:event_type) { 'audit.user.space_manager_add' }
let(:expected_response) do
{
'metadata' => {
'guid' => other_user.guid,
'url' => "/v2/users/#{other_user.guid}",
'created_at' => iso8601,
'updated_at' => iso8601
},
'entity' => {
'admin' => false,
'active' => false,
'default_space_guid' => nil,
'username' => other_user.username,
'spaces_url' => "/v2/users/#{other_user.guid}/spaces",
'organizations_url' => "/v2/users/#{other_user.guid}/organizations",
'managed_organizations_url' => "/v2/users/#{other_user.guid}/managed_organizations",
'billing_managed_organizations_url' => "/v2/users/#{other_user.guid}/billing_managed_organizations",
'audited_organizations_url' => "/v2/users/#{other_user.guid}/audited_organizations",
'managed_spaces_url' => "/v2/users/#{other_user.guid}/managed_spaces",
'audited_spaces_url' => "/v2/users/#{other_user.guid}/audited_spaces"
}
}
end
before do
set_current_user(user)
org.add_user(user)
org.add_manager(user)
space.add_manager(user)
org.add_user(other_user)
end
it 'fails with 403' do
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds' do
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(201)
space.reload
expect(space.managers).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
it 'creates an appropriate event' do
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
end
it 'creates the appropriate role with a guid' do
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
created_role = SpaceManager.find(user_id: other_user.id, space_id: space.id)
expect(created_role.guid).to be_a_guid
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(201)
space.reload
expect(space.managers).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
end
end
describe 'PUT /v2/users/:guid/spaces/:space_guid' do
let(:event_type) { 'audit.user.space_developer_add' }
let(:expected_response) do
{
'metadata' => {
'guid' => other_user.guid,
'url' => "/v2/users/#{other_user.guid}",
'created_at' => iso8601,
'updated_at' => iso8601
},
'entity' => {
'admin' => false,
'active' => false,
'default_space_guid' => nil,
'username' => 'other_user',
'spaces_url' => "/v2/users/#{other_user.guid}/spaces",
'organizations_url' => "/v2/users/#{other_user.guid}/organizations",
'managed_organizations_url' => "/v2/users/#{other_user.guid}/managed_organizations",
'billing_managed_organizations_url' => "/v2/users/#{other_user.guid}/billing_managed_organizations",
'audited_organizations_url' => "/v2/users/#{other_user.guid}/audited_organizations",
'managed_spaces_url' => "/v2/users/#{other_user.guid}/managed_spaces",
'audited_spaces_url' => "/v2/users/#{other_user.guid}/audited_spaces"
}
}
end
before do
set_current_user(user)
org.add_user(user)
org.add_manager(user)
space.add_manager(user)
org.add_user(other_user)
end
it 'fails with 403' do
put "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
expect(last_response.status).to eq(403)
expect(decoded_response['code']).to eq(10_003)
end
context 'as an admin' do
before do
set_current_user_as_admin
end
it 'succeeds' do
put "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
expect(last_response.status).to eq(201)
space.reload
expect(space.developers).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
it 'creates an appropriate event' do
put "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
event = Event.find(type: event_type, actee: other_user.guid)
expect(event).not_to be_nil
expect(event.actee_name).to eq('other_user')
end
it 'creates the appropriate role with a guid' do
put "/v2/users/#{other_user.guid}/spaces/#{space.guid}"
created_role = SpaceDeveloper.find(user_id: other_user.id, space_id: space.id)
expect(created_role.guid).to be_a_guid
end
context 'when the role already exists' do
it 'behaves idempotently by succeeding' do
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
put "/v2/users/#{other_user.guid}/managed_spaces/#{space.guid}"
expect(last_response.status).to eq(201)
space.reload
expect(space.managers).to include(other_user)
expect(decoded_response).to be_a_response_like(expected_response)
end
end
end
end
end
end
end