module Metasploit module Credential # This mixin is intended to provide all of the common validations sued by {Metasploit::Credential::Core} and # anything that mimics it's behaviour by tying together {Metasploit::Credential::Public}, {Metasploit::Credential::Private}, # and {Metasploit::Credential::Realm} objects. module CoreValidations extend ActiveSupport::Concern included do validate :minimum_presence validate :public_for_ssh_key # # Attribute Validations # # replicates 'unique_private_metasploit_credential_cores' index validates :private_id, uniqueness: { message: 'is already taken for credential cores with only a private credential', scope: [ :workspace_id, # realm_id and public_id need to be included in scope so validator uses IS NULL. :realm_id, :public_id ] }, if: '!realm.present? && !public.present? && private.present?' # replicates 'unique_public_metasploit_credential_cores' index validates :public_id, uniqueness: { message: 'is already taken for credential cores with only a public credential', scope: [ :workspace_id, # realm_id and private_id need to be included in scope so validator uses IS NULL. :realm_id, :private_id ] }, if: '!realm.present? && public.present? && !private.present?' # replicates 'unique_realmless_metasploit_credential_cores' index validates :private_id, uniqueness: { message: 'is already taken for credential cores without a credential realm', scope: [ :workspace_id, # realm_id needs to be included in scope so validator uses IS NULL. :realm_id, :public_id ] }, if: '!realm.present? && public.present? && private.present?' # replicates 'unique_publicless_metasploit_credential_cores' index validates :private_id, uniqueness: { message: 'is already taken for credential cores without a public credential', scope: [ :workspace_id, :realm_id, # public_id needs to be included in scope so validator uses IS NULL. :public_id ] }, if: 'realm.present? && !public.present? && private.present?' # replicates 'unique_privateless_metasploit_credential_cores' index validates :public_id, uniqueness: { message: 'is already taken for credential cores without a private credential', scope: [ :workspace_id, :realm_id, # private_id needs to be included in scope so validator uses IS NULL. :private_id ] }, if: 'realm.present? && public.present? && !private.present?' # replicates 'unique_complete_metasploit_credential_cores' index validates :private_id, uniqueness: { message: 'is already taken for complete credential cores', scope: [ :workspace_id, :realm_id, :public_id ] }, if: 'realm.present? && public.present? && private.present?' validates :workspace, presence: true private # Validates that at least one of {#private}, {#public}, or {#realm} is present. # # @return [void] def minimum_presence any_present = [:private, :public, :realm].any? { |attribute| send(attribute).present? } unless any_present errors.add(:base, :minimum_presence) end end # Validates that a Core's Private of type {Metasploit::Credential::SSHKey} has a {Metasploit::Credential::Public} def public_for_ssh_key if private.present? && private.type == Metasploit::Credential::SSHKey.name errors.add(:base, :public_for_ssh_key) unless public.present? end end end end end end