View source
<?php
class SearchApiAcquiaApi {
const REQUEST_TIMEOUT = 5;
private $subscription;
private $apiKey;
private $host;
private $appUuid;
public function getSubscription() {
return $this->subscription;
}
private function __construct($subscription, $api_key, $host, $app_uuid) {
$this->subscription = $subscription;
$this->apiKey = $api_key;
$this->host = $host;
$this->appUuid = $app_uuid;
}
public static function get($subscription, $api_key, $host, $uuid) {
if (empty($subscription) || empty($api_key) || empty($host) || empty($uuid)) {
throw new InvalidArgumentException('Please provide API credentials for Acquia Search.');
}
return new self($subscription, $api_key, $host, $uuid);
}
public static function getFromSettings() {
$subscription = acquia_agent_settings('acquia_identifier');
$api_key = acquia_agent_settings('acquia_key');
$host = variable_get('acquia_search_api_host', 'https://api.sr-prod02.acquia.com');
$uuid = variable_get('acquia_uuid', acquia_agent_settings('acquia_subscription_data')['uuid']);
if (empty($subscription) || empty($api_key) || empty($host) || empty($uuid)) {
throw new InvalidArgumentException('Please provide API credentials for Acquia Search.');
}
return new self($subscription, $api_key, $host, $uuid);
}
public function getIndexes() {
$query = [
'network_id' => $this->subscription,
];
$nonce = SearchApiAcquiaCrypt::randomBytes(24);
$config_path = '/v2/index/configure';
$auth_string = sprintf('id=%s&nonce=%s&realm=search&version=2.0', $this->appUuid, $nonce);
$host = preg_replace('(^https?://)', '', $this->host);
$req_params = [
'GET',
$host,
$config_path,
drupal_http_build_query($query),
$auth_string,
REQUEST_TIME,
];
$headers = [
'Authorization' => $this
->calculateAuthHeader($this->apiKey, $req_params, $auth_string),
'X-Authorization-Timestamp' => REQUEST_TIME,
];
$url = url($this->host . $config_path, [
'https' => TRUE,
'query' => $query,
]);
$options = [
'headers' => $headers,
'timeout' => self::REQUEST_TIMEOUT,
];
$response = drupal_http_request($url, $options);
if ($response->code > 300 || !isset($response->data)) {
$error_message = t("Couldn't connect to Solr. Reason: @reason. Status code: @code. Request: @request", [
'@reason' => $response->status_message,
'@code' => $response->code,
'@request' => $response->request,
]);
watchdog('acquia_search_solr', $error_message, [], WATCHDOG_ERROR);
return [];
}
return $this
->processResponse($response->data);
}
public function getPreferredCoreService() {
$ah_env = $_SERVER['AH_SITE_ENVIRONMENT'] ?? '';
global $databases;
$options = Database::getConnection()
->getConnectionOptions();
$ah_db_name = $options['database'] ?? '';
$ah_db_role = $this
->getDatabaseRole($databases, $ah_db_name);
$sites_folder_name = substr(conf_path(), strrpos(conf_path(), '/') + 1);
$available_indexes = $this
->getIndexes();
$subscription = $this
->getSubscription();
return new SearchApiAcquiaPreferredCore($subscription, $ah_env, $sites_folder_name, $ah_db_role, $available_indexes);
}
public function getDatabaseRole(array $databases, string $ah_db_name) {
$filter = function ($role) {
return $role !== 'default';
};
$databases = array_filter($databases, $filter, ARRAY_FILTER_USE_KEY);
foreach ($databases as $database_role => $databases_list) {
if ($databases_list['default']['database'] == $ah_db_name) {
$database_role = $this
->sanitizeDatabaseRoleName($database_role);
return $database_role;
}
}
return '';
}
protected function processResponse($data) {
$result = [];
$indexes = json_decode($data, TRUE);
if (is_array($indexes)) {
foreach ($indexes as $index) {
$result[$index['key']] = [
'host' => $index['host'],
'index_id' => $index['key'],
'data' => $index,
];
}
}
return $result;
}
private function calculateAuthHeader($key, array $params, $auth_string) {
$auth_string = str_replace([
'&',
'=',
], [
'",',
'="',
], $auth_string);
$key = base64_decode($key, TRUE);
$signature_base_string = implode(PHP_EOL, $params);
$digest = hash_hmac('sha256', $signature_base_string, $key, TRUE);
$signature = base64_encode($digest);
$header = sprintf('acquia-http-hmac %s ",signature="%s"', $auth_string, $signature);
return $header;
}
protected function sanitizeDatabaseRoleName(string $database_role) {
$pattern = '/[^a-zA-Z0-9_]+/';
$database_role = preg_replace($pattern, '', $database_role);
return $database_role;
}
}