# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/components/logger' require 'contrast/utils/object_share' require 'base64' module Contrast module Agent module Reporting # This is the class which will hold up all the Endpoints we use for the direct report from the agent. It builds # the full URLs needed for communication. module Endpoints extend Contrast::Components::Logger::InstanceMethods APP_LANGUAGE = Contrast::Utils::ObjectShare::RUBY.upcase.cs__freeze ENDPOINT_VERSION = '/v1.0'.cs__freeze NG_ENDPOINTS = { application_activity: "#{ Contrast::API.api_url }/api/ng/activity/application", application_create: "#{ Contrast::API.api_url }/api/ng/applications/create", agent_startup: "#{ Contrast::API.api_url }/api/ng/servers/" }.cs__freeze class << self # @return [String,nil] def application_startup with_rescue do "#{ application_endpoint }/startup".cs__freeze end end # @return [String,nil] def application_settings with_rescue do "#{ application_endpoint }/settings".cs__freeze end end # @return [String,nil] def application_inventory with_rescue do "#{ application_endpoint }/inventory".cs__freeze end end def application_activity with_rescue do NG_ENDPOINTS[:application_activity].cs__freeze end end # @return [String,nil] def library_usage with_rescue do "#{ application_endpoint }/library-usage".cs__freeze end end # @return [String,nil] def heartbeat with_rescue do "#{ application_endpoint }/heartbeat".cs__freeze end end # @return [String,nil] def observed_route with_rescue do "#{ route_endpoint }/observed".cs__freeze end end def server_settings with_rescue do "#{ server_endpoint }/settings".cs__freeze end end # @return [String,nil] def trace_observed with_rescue do "#{ trace_endpoint }/observed".cs__freeze end end private # Returns the URL needed to connect to endpoints in TeamServer required for application related information. # # @return [String] def application_endpoint @_application_endpoint ||= "#{ Contrast::API.api_url }/agents#{ ENDPOINT_VERSION }/applications" \ "#{ server_path_segment }#{ application_path_segment }" end # Returns the URL needed to connect to endpoints in TeamServer required for route related information. # # @return [String] def route_endpoint @_route_endpoint ||= "#{ Contrast::API.api_url }/agents#{ ENDPOINT_VERSION }/routes" \ "#{ server_path_segment }#{ application_path_segment }" end # Returns the URL needed to connect to endpoints in TeamServer required for server related information. # # @return [String] def server_endpoint @_server_endpoint ||= "#{ Contrast::API.api_url }/agents#{ ENDPOINT_VERSION }/servers" \ "#{ server_path_segment }" end # Returns the URL needed to connect to endpoints in TeamServer required for trace/finding related information. # # @return [String] def trace_endpoint @_trace_endpoint ||= "#{ Contrast::API.api_url }/agents#{ ENDPOINT_VERSION }/traces" \ "#{ server_path_segment }#{ application_path_segment }" end # The server host, path, and type; required for endpoints that are server specific. # # @return [String] def server_path_segment @_server_path_segment ||= "/#{ Base64.urlsafe_encode64(server_host_name, padding: false) }" \ "/#{ Base64.urlsafe_encode64(server_path, padding: false) }" \ "/#{ Base64.urlsafe_encode64(server_type, padding: false) }" end # The application language and name; required for endpoints that are application specific. # # @return [String] def application_path_segment @_application_path_segment ||= "/#{ Base64.urlsafe_encode64(APP_LANGUAGE, padding: false) }" \ "/#{ Base64.urlsafe_encode64(app_name, padding: false) }" end # @return [String,nil] def server_host_name return @_server_host_name unless @_server_host_name.nil? @_server_host_name = ::Contrast::APP_CONTEXT.server_name end # @return [String,nil] def server_path return @_server_path unless @_server_path.nil? @_server_path = ::Contrast::APP_CONTEXT.server_path end # @return [String,nil] def server_type return @_server_type unless @_server_type.nil? @_server_type = ::Contrast::APP_CONTEXT.server_type end # @return [String,nil] def app_name return @_app_name unless @_app_name.nil? @_app_name = ::Contrast::APP_CONTEXT.name # rubocop:disable Security/Module/Name end # @return [String,nil] def with_rescue yield rescue StandardError => e logger.debug('Endpoint failed with the following error', e) Contrast::Utils::ObjectShare::EMPTY_STRING end end end end end end