Class: ApiKeys::Services::Authenticator
- Inherits:
-
Object
- Object
- ApiKeys::Services::Authenticator
- Extended by:
- Logging
- Defined in:
- lib/api_keys/services/authenticator.rb
Overview
Authenticates an incoming request by extracting and verifying an API key.
Defined Under Namespace
Classes: Result
Constant Summary collapse
- MAX_TOKEN_BYTESIZE =
512- MAX_BCRYPT_CANDIDATES =
32- MAX_KNOWN_PREFIXES =
1_024- TOKEN_CACHE_NAMESPACE =
"api_keys:v2:token"- KNOWN_PREFIXES_CACHE_KEY =
"api_keys:v2:known_prefixes"
Class Method Summary collapse
-
.call(request) ⇒ ApiKeys::Services::Authenticator::Result
Authenticates the request.
- .clear_known_prefixes_cache ⇒ Object
Class Method Details
.call(request) ⇒ ApiKeys::Services::Authenticator::Result
Authenticates the request.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 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 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/api_keys/services/authenticator.rb', line 45 def self.call(request) request_uuid = request.uuid if request.respond_to?(:uuid) log_debug "[ApiKeys Auth] Authentication started for request #{request_uuid || '[unknown]'}" config = ApiKeys.configuration # === HTTPS Check (Production Only) === if production_environment? && config.https_only_production unless secure_request?(request) = "[ApiKeys Security] API key authentication attempted over insecure HTTP connection in production." log_warn if config.https_strict_mode log_warn "[ApiKeys Security] Strict mode enabled: Aborting authentication." return Result.failure(error_code: :insecure_connection, message: "API requests must be made over HTTPS in production.") end end end # === End HTTPS Check === token = extract_token(request, config) unless token log_debug "[ApiKeys Auth] Token extraction failed." return Result.failure(error_code: :missing_token, message: "API token is missing") end unless valid_token?(token) log_debug "[ApiKeys Auth] Rejected a malformed API token." return Result.failure(error_code: :invalid_token, message: "API token is invalid") end log_debug "[ApiKeys Auth] Token extracted successfully. Verifying..." # Pass the original token AND config to find_and_verify_key api_key = find_and_verify_key(token, config) result = if (configuration_failure = check_key_type_configuration(api_key, config) || check_environment_configuration(api_key, config)) configuration_failure elsif api_key&.active? log_debug "[ApiKeys Auth] Verification successful. Key ID: #{api_key.id}" # Check environment isolation if enabled env_check_result = check_environment_isolation(api_key, config) if env_check_result env_check_result # Return failure result else # TODO: Optionally update last_used_at and requests_count Result.success(api_key) end elsif api_key&.revoked? log_debug "[ApiKeys Auth] Verification failed: Key revoked. Key ID: #{api_key.id}" Result.failure(error_code: :revoked_key, message: "API key has been revoked") elsif api_key&.expired? log_debug "[ApiKeys Auth] Verification failed: Key expired. Key ID: #{api_key.id}" Result.failure(error_code: :expired_key, message: "API key has expired") else # Not found, mismatch, or inactive log_debug "[ApiKeys Auth] Verification failed: Token invalid or key not found." Result.failure(error_code: :invalid_token, message: "API token is invalid") end log_debug "[ApiKeys Auth] Authentication finished. Success: #{result.success?}; error code: #{result.error_code || 'none'}" result end |
.clear_known_prefixes_cache ⇒ Object
278 279 280 281 282 283 284 285 |
# File 'lib/api_keys/services/authenticator.rb', line 278 def self.clear_known_prefixes_cache cache = rails_cache return unless cache cache.delete(KNOWN_PREFIXES_CACHE_KEY) rescue StandardError => error log_warn "[ApiKeys Auth] Cache delete failed (#{error.class}); continuing safely." end |