Module: KeeperSecretsManager::CachingPostFunction
- Defined in:
- lib/keeper_secrets_manager/cache.rb
Overview
Caching post function for disaster recovery Wraps the normal post_function to save responses and fall back to cache on network failure Usage: KeeperSecretsManager.new(config: storage, custom_post_function: KeeperSecretsManager::CachingPostFunction)
Class Method Summary collapse
-
.call(url, transmission_key, encrypted_payload, verify_ssl_certs = true) ⇒ Dto::KSMHttpResponse
Post function that caches successful responses and falls back to cache on failure This matches the pattern used in Python, JavaScript, Java, and .NET SDKs.
-
.make_http_request(url, transmission_key, encrypted_payload, verify_ssl_certs) ⇒ Object
Make HTTP request - extracted to be testable This duplicates some logic from Core::SecretsManager#post_function because that method is an instance method.
Class Method Details
.call(url, transmission_key, encrypted_payload, verify_ssl_certs = true) ⇒ Dto::KSMHttpResponse
Post function that caches successful responses and falls back to cache on failure This matches the pattern used in Python, JavaScript, Java, and .NET SDKs
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/keeper_secrets_manager/cache.rb', line 59 def self.call(url, transmission_key, encrypted_payload, verify_ssl_certs = true) # Try network request first begin # Call the static post_function response = make_http_request(url, transmission_key, encrypted_payload, verify_ssl_certs) # On success, save to cache (transmission key + encrypted response body) if response.success? && response.data cache_data = transmission_key.key + response.data Cache.save_cache(cache_data) end response rescue StandardError => e # Network failed - try to load from cache cached_data = Cache.get_cached_data if cached_data && cached_data.bytesize > 32 # Extract cached transmission key and response data # First 32 bytes are the transmission key, rest is encrypted response cached_transmission_key = cached_data[0...32] cached_response_data = cached_data[32..-1] # Update the transmission key to match cached version transmission_key.key = cached_transmission_key # Return cached response as if it came from network Dto::KSMHttpResponse.new( status_code: 200, data: cached_response_data ) else # No cache available - re-raise the original error raise e end end end |
.make_http_request(url, transmission_key, encrypted_payload, verify_ssl_certs) ⇒ Object
Make HTTP request - extracted to be testable This duplicates some logic from Core::SecretsManager#post_function because that method is an instance method
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/keeper_secrets_manager/cache.rb', line 100 def self.make_http_request(url, transmission_key, encrypted_payload, verify_ssl_certs) require 'net/http' require 'uri' uri = URI(url) request = Net::HTTP::Post.new(uri) request['Content-Type'] = 'application/octet-stream' request['PublicKeyId'] = transmission_key.public_key_id.to_s request['TransmissionKey'] = Utils.bytes_to_base64(transmission_key.encrypted_key) request['Authorization'] = "Signature #{Utils.bytes_to_base64(encrypted_payload.signature)}" request['Content-Length'] = encrypted_payload.encrypted_payload.bytesize.to_s request.body = encrypted_payload.encrypted_payload http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true if verify_ssl_certs http.verify_mode = OpenSSL::SSL::VERIFY_PEER # Set up certificate store with system defaults store = OpenSSL::X509::Store.new store.set_default_paths http.cert_store = store else http.verify_mode = OpenSSL::SSL::VERIFY_NONE end response = http.request(request) Dto::KSMHttpResponse.new( status_code: response.code.to_i, data: response.body, http_response: response ) rescue StandardError => e raise NetworkError, "HTTP request failed: #{e.}" end |