app/messages/role_create_message.rb
require 'messages/metadata_base_message'
require 'models/helpers/role_types'
module VCAP::CloudController
class RoleCreateMessage < BaseMessage
register_allowed_keys %i[type relationships]
validates_with NoAdditionalKeysValidator
validates_with RelationshipValidator
validates :type,
inclusion: {
in: VCAP::CloudController::RoleTypes::ALL_ROLES,
message: "must be one of the allowed types #{VCAP::CloudController::RoleTypes::ALL_ROLES}"
}
delegate :space_guid, :user_guid, :organization_guid, :username, :user_origin, to: :relationships_message
def relationships_message
@relationships_message ||= Relationships.new(type, relationships&.deep_symbolize_keys)
end
class Relationships < BaseMessage
attr_reader :type
register_allowed_keys %i[space user organization]
def initialize(role_type, params)
@type = role_type
super(params)
end
def has_user_validation_errors?
errors[:username].any? || errors[:user_origin].any? || errors[:user].any?
end
def has_org_or_space_validation_errors?
errors[:base].any? || errors[:space].any? || errors[:organization].any?
end
validates_with NoAdditionalKeysValidator
validates :user, presence: true
validate :user_input_combinations
validate :organization_or_space_input_combinations
validates :space, presence: true, allow_nil: false, to_one_relationship: true, if: -> { !has_org_or_space_validation_errors? && organization.nil? }
validates :organization, presence: true, to_one_relationship: true, if: -> { !has_org_or_space_validation_errors? && space.nil? }
validates :user, to_one_relationship: true, if: -> { !has_user_validation_errors? && has_user_guid? }
validates :username, string: true, if: -> { !has_user_validation_errors? && has_username? }
validates :user_origin, string: true, allow_nil: true, if: -> { !has_user_validation_errors? && has_user_origin? }
def username
HashUtils.dig(user, :data, :username)
end
def user_origin
HashUtils.dig(user, :data, :origin)
end
def user_guid
HashUtils.dig(user, :data, :guid)
end
def space_guid
HashUtils.dig(space, :data, :guid)
end
def organization_guid
HashUtils.dig(organization, :data, :guid)
end
private
%i[user space organization].each do |symbol|
define_method "#{symbol}_data" do
HashUtils.dig(send(symbol), :data)
end
end
def has_user_guid?
return false unless user_data && user_data.is_a?(Hash)
user_data.key?(:guid)
end
def has_username?
return false unless user_data && user_data.is_a?(Hash)
user_data.key?(:username)
end
def has_user_origin?
return false unless user_data && user_data.is_a?(Hash)
user_data.key?(:origin)
end
def user_input_combinations
errors.add(:username, 'cannot be specified when identifying user by guid') if has_user_guid? && has_username?
errors.add(:user_origin, 'cannot be specified when identifying user by guid') if has_user_guid? && has_user_origin?
errors.add(:user_origin, 'cannot be specified without specifying the username') if !has_username? && has_user_origin?
return unless !has_username? && !has_user_guid?
errors.add(:user, 'must have a username or guid specified')
end
def organization_or_space_input_combinations
errors.add(:base, 'must specify either a space or an organization.') if space_data.nil? && organization_data.nil?
errors.add(:space, "cannot be provided with the organization role type: '#{type}'.") if space_data && VCAP::CloudController::RoleTypes::ORGANIZATION_ROLES.include?(type)
errors.add(:organization, "cannot be provided with the space role type: '#{type}'.") if organization_data && VCAP::CloudController::RoleTypes::SPACE_ROLES.include?(type)
return unless space_data && organization_data
errors.add(:base, 'cannot specify both an organization and a space.')
end
end
end
end