mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
MDL-53412 search: Correctly handle Solr over SSL
This commit is contained in:
parent
7adc7ef14f
commit
5dc4624ced
@ -55,6 +55,11 @@ class engine extends \core_search\engine {
|
||||
*/
|
||||
protected $client = null;
|
||||
|
||||
/**
|
||||
* @var \curl Direct curl object.
|
||||
*/
|
||||
protected $curl = null;
|
||||
|
||||
/**
|
||||
* @var array Fields that can be highlighted.
|
||||
*/
|
||||
@ -417,11 +422,10 @@ class engine extends \core_search\engine {
|
||||
'login' => !empty($this->config->server_username) ? $this->config->server_username : '',
|
||||
'password' => !empty($this->config->server_password) ? $this->config->server_password : '',
|
||||
'port' => !empty($this->config->server_port) ? $this->config->server_port : '',
|
||||
'issecure' => !empty($this->config->secure) ? $this->config->secure : '',
|
||||
'secure' => !empty($this->config->secure) ? true : false,
|
||||
'ssl_cert' => !empty($this->config->ssl_cert) ? $this->config->ssl_cert : '',
|
||||
'ssl_cert_only' => !empty($this->config->ssl_cert_only) ? $this->config->ssl_cert_only : '',
|
||||
'ssl_key' => !empty($this->config->ssl_key) ? $this->config->ssl_key : '',
|
||||
'ssl_password' => !empty($this->config->ssl_keypassword) ? $this->config->ssl_keypassword : '',
|
||||
'ssl_keypassword' => !empty($this->config->ssl_keypassword) ? $this->config->ssl_keypassword : '',
|
||||
'ssl_cainfo' => !empty($this->config->ssl_cainfo) ? $this->config->ssl_cainfo : '',
|
||||
'ssl_capath' => !empty($this->config->ssl_capath) ? $this->config->ssl_capath : '',
|
||||
);
|
||||
@ -434,4 +438,70 @@ class engine extends \core_search\engine {
|
||||
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a curl object for conntecting to solr.
|
||||
*
|
||||
* @return \curl
|
||||
*/
|
||||
public function get_curl_object() {
|
||||
if (!is_null($this->curl)) {
|
||||
return $this->curl;
|
||||
}
|
||||
|
||||
$this->curl = new \curl();
|
||||
|
||||
$options = array();
|
||||
// Build the SSL options. Based on pecl-solr and general testing.
|
||||
if (!empty($this->config->secure)) {
|
||||
if (!empty($this->config->ssl_cert)) {
|
||||
$options['CURLOPT_SSLCERT'] = $this->config->ssl_cert;
|
||||
$options['CURLOPT_SSLCERTTYPE'] = 'PEM';
|
||||
}
|
||||
|
||||
if (!empty($this->config->ssl_key)) {
|
||||
$options['CURLOPT_SSLKEY'] = $this->config->ssl_key;
|
||||
$options['CURLOPT_SSLKEYTYPE'] = 'PEM';
|
||||
}
|
||||
|
||||
if (!empty($this->config->ssl_keypassword)) {
|
||||
$options['CURLOPT_KEYPASSWD'] = $this->config->ssl_keypassword;
|
||||
}
|
||||
|
||||
if (!empty($this->config->ssl_cainfo)) {
|
||||
$options['CURLOPT_CAINFO'] = $this->config->ssl_cainfo;
|
||||
}
|
||||
|
||||
if (!empty($this->config->ssl_capath)) {
|
||||
$options['CURLOPT_CAPATH'] = $this->config->ssl_capath;
|
||||
}
|
||||
}
|
||||
|
||||
$this->curl->setopt($options);
|
||||
|
||||
if (!empty($this->config->server_username) && !empty($this->config->server_password)) {
|
||||
$authorization = $this->config->server_username . ':' . $this->config->server_password;
|
||||
$this->curl->setHeader('Authorization', 'Basic ' . base64_encode($authorization));
|
||||
}
|
||||
|
||||
return $this->curl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Moodle url object for the server connection.
|
||||
*
|
||||
* @param string $path The solr path to append.
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_connection_url($path) {
|
||||
// Must use the proper protocol, or SSL will fail.
|
||||
$protocol = !empty($this->config->secure) ? 'https' : 'http';
|
||||
$url = $protocol . '://' . rtrim($this->config->server_hostname, '/');
|
||||
if (!empty($this->config->server_port)) {
|
||||
$url .= ':' . $this->config->server_port;
|
||||
}
|
||||
$url .= '/solr/' . $this->config->indexname . '/' . ltrim($path, '/');
|
||||
|
||||
return new \moodle_url($url);
|
||||
}
|
||||
}
|
||||
|
@ -52,16 +52,10 @@ class schema {
|
||||
protected $curl = null;
|
||||
|
||||
/**
|
||||
* The URL.
|
||||
* @var string
|
||||
* An engine instance.
|
||||
* @var engine
|
||||
*/
|
||||
protected $url = null;
|
||||
|
||||
/**
|
||||
* The schema URL.
|
||||
* @var string
|
||||
*/
|
||||
protected $schemaurl = null;
|
||||
protected $engine = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -78,23 +72,11 @@ class schema {
|
||||
throw new \moodle_exception('missingconfig', 'search_solr');
|
||||
}
|
||||
|
||||
$this->curl = new \curl();
|
||||
$this->engine = new engine();
|
||||
$this->curl = $this->engine->get_curl_object();
|
||||
|
||||
// HTTP headers.
|
||||
$this->curl->setHeader('Content-type: application/json');
|
||||
if (!empty($this->config->server_username) && !empty($this->config->server_password)) {
|
||||
$authorization = $this->config->server_username . ':' . $this->config->server_password;
|
||||
$this->curl->setHeader('Authorization', 'Basic ' . base64_encode($authorization));
|
||||
}
|
||||
|
||||
$this->url = rtrim($this->config->server_hostname, '/');
|
||||
if (!empty($this->config->server_port)) {
|
||||
$this->url .= ':' . $this->config->server_port;
|
||||
}
|
||||
$this->url .= '/solr/' . $this->config->indexname;
|
||||
$this->schemaurl = $this->url . '/schema';
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,7 +121,8 @@ class schema {
|
||||
protected function check_index() {
|
||||
|
||||
// Check that the server is available and the index exists.
|
||||
$result = $this->curl->get($this->url . '/select?wt=json');
|
||||
$url = $this->engine->get_connection_url('/select?wt=json');
|
||||
$result = $this->curl->get($url);
|
||||
if ($this->curl->error) {
|
||||
throw new \moodle_exception('connectionerror', 'search_solr');
|
||||
}
|
||||
@ -167,6 +150,8 @@ class schema {
|
||||
$this->validate_fields($fields, false);
|
||||
}
|
||||
|
||||
$url = $this->engine->get_connection_url('/schema');
|
||||
|
||||
// Add all fields.
|
||||
foreach ($fields as $fieldname => $data) {
|
||||
|
||||
@ -183,7 +168,7 @@ class schema {
|
||||
'indexed' => $data['indexed']
|
||||
)
|
||||
);
|
||||
$results = $this->curl->post($this->schemaurl, json_encode($params));
|
||||
$results = $this->curl->post($url, json_encode($params));
|
||||
|
||||
// We only validate if we are interested on it.
|
||||
if ($checkexisting) {
|
||||
@ -209,7 +194,8 @@ class schema {
|
||||
global $CFG;
|
||||
|
||||
foreach ($fields as $fieldname => $data) {
|
||||
$results = $this->curl->get($this->schemaurl . '/fields/' . $fieldname);
|
||||
$url = $this->engine->get_connection_url('/schema/fields/' . $fieldname);
|
||||
$results = $this->curl->get($url);
|
||||
|
||||
if ($this->curl->error) {
|
||||
throw new \moodle_exception('errorcreatingschema', 'search_solr', '', $this->curl->error);
|
||||
|
@ -63,11 +63,9 @@ $string['solrsslcainfo'] = 'SSL CA certificates name';
|
||||
$string['solrsslcainfo_desc'] = 'File name holding one or more CA certificates to verify peer with';
|
||||
$string['solrsslcapath'] = 'SSL CA certificates path';
|
||||
$string['solrsslcapath_desc'] = 'Directory path holding multiple CA certificates to verify peer with';
|
||||
$string['solrsslcert'] = 'SSL key & certificate';
|
||||
$string['solrsslcert_desc'] = 'File name to a PEM-formatted private key + private certificate (concatenated in that order)';
|
||||
$string['solrsslcertonly'] = 'SSL certificate';
|
||||
$string['solrsslcertonly_desc'] = 'File name to a PEM-formatted private certificate only';
|
||||
$string['solrsslcert'] = 'SSL certificate';
|
||||
$string['solrsslcert_desc'] = 'File name to a PEM-formatted private certificate';
|
||||
$string['solrsslkey'] = 'SSL key';
|
||||
$string['solrsslkey_desc'] = 'File name to a PEM-formatted private key';
|
||||
$string['solrsslkeypassword'] = 'SSL Key password';
|
||||
$string['solrsslkeypassword'] = 'SSL key password';
|
||||
$string['solrsslkeypassword_desc'] = 'Password for PEM-formatted private key file';
|
||||
|
@ -42,7 +42,6 @@ if ($ADMIN->fulltree) {
|
||||
$settings->add(new admin_setting_configtext('search_solr/server_password', new lang_string('solrauthpassword', 'search_solr'), '', '', PARAM_RAW));
|
||||
$settings->add(new admin_setting_configtext('search_solr/server_timeout', new lang_string('solrhttpconnectiontimeout', 'search_solr'), new lang_string('solrhttpconnectiontimeout_desc', 'search_solr'), 30, PARAM_INT));
|
||||
$settings->add(new admin_setting_configtext('search_solr/ssl_cert', new lang_string('solrsslcert', 'search_solr'), new lang_string('solrsslcert_desc', 'search_solr'), '', PARAM_RAW));
|
||||
$settings->add(new admin_setting_configtext('search_solr/ssl_cert_only', new lang_string('solrsslcertonly', 'search_solr'), new lang_string('solrsslcertonly_desc', 'search_solr'), '', PARAM_RAW));
|
||||
$settings->add(new admin_setting_configtext('search_solr/ssl_key', new lang_string('solrsslkey', 'search_solr'), new lang_string('solrsslkey_desc', 'search_solr'), '', PARAM_RAW));
|
||||
$settings->add(new admin_setting_configtext('search_solr/ssl_keypassword', new lang_string('solrsslkeypassword', 'search_solr'), new lang_string('solrsslkeypassword_desc', 'search_solr'), '', PARAM_RAW));
|
||||
$settings->add(new admin_setting_configtext('search_solr/ssl_cainfo', new lang_string('solrsslcainfo', 'search_solr'), new lang_string('solrsslcainfo_desc', 'search_solr'), '', PARAM_RAW));
|
||||
|
@ -25,6 +25,10 @@
|
||||
* Optional params:
|
||||
* - define('TEST_SEARCH_SOLR_USERNAME', '');
|
||||
* - define('TEST_SEARCH_SOLR_PASSWORD', '');
|
||||
* - define('TEST_SEARCH_SOLR_SSLCERT', '');
|
||||
* - define('TEST_SEARCH_SOLR_SSLKEY', '');
|
||||
* - define('TEST_SEARCH_SOLR_KEYPASSWORD', '');
|
||||
* - define('TEST_SEARCH_SOLR_CAINFOCERT', '');
|
||||
*
|
||||
* @package core_search
|
||||
* @category phpunit
|
||||
@ -71,13 +75,31 @@ class search_solr_engine_testcase extends advanced_testcase {
|
||||
set_config('indexname', TEST_SEARCH_SOLR_INDEXNAME, 'search_solr');
|
||||
|
||||
if (defined('TEST_SEARCH_SOLR_USERNAME')) {
|
||||
set_config('server_username', TEST_SEARCH_SOLR_USERNAME);
|
||||
set_config('server_username', TEST_SEARCH_SOLR_USERNAME, 'search_solr');
|
||||
}
|
||||
|
||||
if (defined('TEST_SEARCH_SOLR_PASSWORD')) {
|
||||
set_config('server_password', TEST_SEARCH_SOLR_PASSWORD);
|
||||
set_config('server_password', TEST_SEARCH_SOLR_PASSWORD, 'search_solr');
|
||||
}
|
||||
|
||||
if (defined('TEST_SEARCH_SOLR_SSLCERT')) {
|
||||
set_config('secure', true, 'search_solr');
|
||||
set_config('ssl_cert', TEST_SEARCH_SOLR_SSLCERT, 'search_solr');
|
||||
}
|
||||
|
||||
if (defined('TEST_SEARCH_SOLR_SSLKEY')) {
|
||||
set_config('ssl_key', TEST_SEARCH_SOLR_SSLKEY, 'search_solr');
|
||||
}
|
||||
|
||||
if (defined('TEST_SEARCH_SOLR_KEYPASSWORD')) {
|
||||
set_config('ssl_keypassword', TEST_SEARCH_SOLR_KEYPASSWORD, 'search_solr');
|
||||
}
|
||||
|
||||
if (defined('TEST_SEARCH_SOLR_CAINFOCERT')) {
|
||||
set_config('ssl_cainfo', TEST_SEARCH_SOLR_CAINFOCERT, 'search_solr');
|
||||
}
|
||||
|
||||
|
||||
// Inject search solr engine into the testable core search as we need to add the mock
|
||||
// search component to it.
|
||||
$searchengine = new \search_solr\engine();
|
||||
|
Loading…
x
Reference in New Issue
Block a user