app/controllers/runtime/users_controller.rb
module VCAP::CloudController
class UsersController < RestController::ModelController
def self.dependencies
%i[
username_populating_collection_renderer
uaa_username_lookup_client
username_populating_object_renderer
user_event_repository
]
end
define_attributes do
attribute :guid, String, exclude_in: :update
attribute :admin, Message::Boolean, default: false
to_many :spaces
to_many :organizations
to_many :managed_organizations
to_many :billing_managed_organizations
to_many :audited_organizations
to_many :managed_spaces
to_many :audited_spaces
to_one :default_space, optional_in: [:create]
end
query_parameters :space_guid, :organization_guid,
:managed_organization_guid,
:billing_managed_organization_guid,
:audited_organization_guid,
:managed_space_guid,
:audited_space_guid
def self.translate_validation_exception(e, attributes)
guid_errors = e.errors.on(:guid)
if guid_errors && guid_errors.include?(:unique)
CloudController::Errors::ApiError.new_from_details('UaaIdTaken', attributes['guid'])
else
CloudController::Errors::ApiError.new_from_details('UserInvalid', e.errors.full_messages)
end
end
def delete(guid)
do_delete(find_guid_and_validate_access(:delete, guid))
end
def inject_dependencies(dependencies)
super
@object_renderer = dependencies[:username_populating_object_renderer]
@uaa_username_lookup_client = dependencies.fetch(:uaa_username_lookup_client)
@collection_renderer = dependencies[:username_populating_collection_renderer]
@user_event_repository = dependencies.fetch(:user_event_repository)
end
delete "#{path_guid}/spaces/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :developers, id, Space)
end
delete "#{path_guid}/managed_spaces/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :managers, id, Space)
end
delete "#{path_guid}/audited_spaces/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :auditors, id, Space)
end
delete "#{path_guid}/organizations/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :users, id, Organization)
end
delete "#{path_guid}/managed_organizations/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :managers, id, Organization)
end
delete "#{path_guid}/billing_managed_organizations/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :billing_managers, id, Organization)
end
delete "#{path_guid}/audited_organizations/:other_id" do |api, id, other_id|
api.dispatch(:remove_related, other_id, :auditors, id, Organization)
end
put "#{path_guid}/audited_spaces/:space_guid" do |api, id, space_guid|
api.dispatch(:add_space_role, id, :audited_spaces, space_guid)
end
put "#{path_guid}/managed_spaces/:space_guid" do |api, id, space_guid|
api.dispatch(:add_space_role, id, :managed_spaces, space_guid)
end
put "#{path_guid}/spaces/:space_guid" do |api, id, space_guid|
api.dispatch(:add_space_role, id, :spaces, space_guid)
end
put "#{path_guid}/organizations/:org_guid" do |api, id, org_guid|
api.dispatch(:add_organization_role, id, :organizations, org_guid)
end
put "#{path_guid}/audited_organizations/:org_guid" do |api, id, org_guid|
api.dispatch(:add_organization_role, id, :audited_organizations, org_guid)
end
put "#{path_guid}/managed_organizations/:org_guid" do |api, id, org_guid|
api.dispatch(:add_organization_role, id, :managed_organizations, org_guid)
end
put "#{path_guid}/billing_managed_organizations/:org_guid" do |api, id, org_guid|
api.dispatch(:add_organization_role, id, :billing_managed_organizations, org_guid)
end
define_messages
define_routes
# related_guid should map back to other_id
def remove_related(related_guid, name, user_guid, find_model=model)
response = super
user = User.first(guid: user_guid)
user.username = @uaa_username_lookup_client.usernames_for_ids([user.guid])[user.guid] || ''
if find_model == Space
@user_event_repository.record_space_role_remove(Space.first(guid: related_guid), user, "space_#{name.to_s.singularize}", UserAuditInfo.from_context(SecurityContext))
elsif find_model == Organization
@user_event_repository.record_organization_role_remove(Organization.first(guid: related_guid), user, "organization_#{name.to_s.singularize}",
UserAuditInfo.from_context(SecurityContext))
end
response
end
def add_space_role(user_guid, relationship, space_guid)
space = Space.first(guid: space_guid)
user = User.first(guid: user_guid)
user.username = @uaa_username_lookup_client.usernames_for_ids([user.guid])[user.guid] || ''
@request_attrs = { 'space' => space_guid, verb: 'add', relation: relationship, related_guid: space_guid }
before_update(user)
user.db.transaction do
read_validation = :read_related_object_for_update
validate_access(read_validation, user, request_attrs)
if relationship.eql?(:audited_spaces)
SpaceAuditor.find_or_create(user_id: user.id, space_id: space.id)
elsif relationship.eql?(:managed_spaces)
SpaceManager.find_or_create(user_id: user.id, space_id: space.id)
else
SpaceDeveloper.find_or_create(user_id: user.id, space_id: space.id)
end
end
after_update(user)
if relationship.eql?(:audited_spaces)
@user_event_repository.record_space_role_add(space, user, RoleTypes::SPACE_AUDITOR, UserAuditInfo.from_context(SecurityContext))
elsif relationship.eql?(:managed_spaces)
@user_event_repository.record_space_role_add(space, user, RoleTypes::SPACE_MANAGER, UserAuditInfo.from_context(SecurityContext))
else
@user_event_repository.record_space_role_add(space, user, RoleTypes::SPACE_DEVELOPER, UserAuditInfo.from_context(SecurityContext))
end
[HTTP::CREATED, object_renderer.render_json(self.class, user, @opts)]
end
def add_organization_role(user_guid, relationship, org_guid)
organization = Organization.first(guid: org_guid)
user = User.first(guid: user_guid)
user.username = @uaa_username_lookup_client.usernames_for_ids([user.guid])[user.guid] || ''
@request_attrs = { 'organization' => org_guid, verb: 'add', relation: relationship, related_guid: org_guid }
before_update(user)
user.db.transaction do
read_validation = :read_related_object_for_update
validate_access(read_validation, user, request_attrs)
if relationship.eql?(:billing_managed_organizations)
OrganizationBillingManager.find_or_create(user_id: user.id, organization_id: organization.id)
elsif relationship.eql?(:audited_organizations)
OrganizationAuditor.find_or_create(user_id: user.id, organization_id: organization.id)
elsif relationship.eql?(:managed_organizations)
OrganizationManager.find_or_create(user_id: user.id, organization_id: organization.id)
else
OrganizationUser.find_or_create(user_id: user.id, organization_id: organization.id)
end
end
after_update(user)
if relationship.eql?(:billing_managed_organizations)
@user_event_repository.record_organization_role_add(Organization.first(guid: org_guid), user, RoleTypes::ORGANIZATION_BILLING_MANAGER,
UserAuditInfo.from_context(SecurityContext))
elsif relationship.eql?(:audited_organizations)
@user_event_repository.record_organization_role_add(Organization.first(guid: org_guid), user, RoleTypes::ORGANIZATION_AUDITOR, UserAuditInfo.from_context(SecurityContext))
elsif relationship.eql?(:managed_organizations)
@user_event_repository.record_organization_role_add(Organization.first(guid: org_guid), user, RoleTypes::ORGANIZATION_MANAGER, UserAuditInfo.from_context(SecurityContext))
else
@user_event_repository.record_organization_role_add(Organization.first(guid: org_guid), user, RoleTypes::ORGANIZATION_USER, UserAuditInfo.from_context(SecurityContext))
end
[HTTP::CREATED, object_renderer.render_json(self.class, user, @opts)]
end
end
end