HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.32
Disabled: pcntl_fork
Upload Files
File: /wordpress/plugins/wp-cloud-client/1.1.7/src/Auth/ApiKeyAuthenticator.php
<?php

declare(strict_types=1);

namespace VPlugins\WPCloudClient\Auth;

use VPlugins\WPCloudClient\Settings\SettingsRepository;
use WP_Error;
use WP_REST_Request;

final readonly class ApiKeyAuthenticator {

	/**
	 * Construct the authenticator.
	 *
	 * @param SettingsRepository $settings Settings repository instance.
	 */
	public function __construct(
		private SettingsRepository $settings,
	) {}

	/**
	 * Validate the authentication headers on an incoming request.
	 *
	 * @param WP_REST_Request $request The incoming REST request.
	 * @return true|WP_Error True if valid, WP_Error on failure.
	 */
	public function validate( WP_REST_Request $request ): true|WP_Error {
		$apiKey = $request->get_header( 'x_wpcc_api_key' );
		$siteId = $request->get_header( 'x_wpcc_site_id' );

		if ( ! $apiKey || ! $siteId ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			error_log( 'WP Cloud Client: authentication failed — missing required headers.' );
			return new WP_Error(
				'wpcc_missing_auth_headers',
				__( 'Missing required authentication headers: X-WPCC-API-Key, X-WPCC-Site-ID.', 'wp-cloud-client' ),
				[ 'status' => 401 ],
			);
		}

		// Validate Site ID.
		// hash_equals() used for constant-time comparison to prevent timing attacks.
		$configuredSiteId = $this->settings->getSiteId();
		if ( ! $configuredSiteId || ! hash_equals( $configuredSiteId, $siteId ) ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			error_log( 'WP Cloud Client: authentication failed — invalid site ID.' );
			return new WP_Error(
				'wpcc_invalid_site_id',
				__( 'Invalid site ID.', 'wp-cloud-client' ),
				[ 'status' => 401 ],
			);
		}

		// Validate API Key.
		// hash_equals() used for constant-time comparison to prevent timing attacks.
		$configuredApiKey = $this->settings->getApiKey();
		if ( ! $configuredApiKey || ! hash_equals( $configuredApiKey, $apiKey ) ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			error_log( 'WP Cloud Client: authentication failed — invalid API key.' );
			return new WP_Error(
				'wpcc_invalid_api_key',
				__( 'Invalid API key.', 'wp-cloud-client' ),
				[ 'status' => 401 ],
			);
		}

		return true;
	}
}