accounts = array(
'us' => __('US (default)', 'updraftplus'),
'uk' => __('UK', 'updraftplus')
);
$this->regions = array(
'DFW' => __('Dallas (DFW) (default)', 'updraftplus'),
'SYD' => __('Sydney (SYD)', 'updraftplus'),
'ORD' => __('Chicago (ORD)', 'updraftplus'),
'IAD' => __('Northern Virginia (IAD)', 'updraftplus'),
'HKG' => __('Hong Kong (HKG)', 'updraftplus'),
'LON' => __('London (LON)', 'updraftplus')
);
add_action('admin_footer', array($this, 'admin_footer'));
}
/**
* Compose partial template that deals with apikeysettings
*
* @param String $msg A filterable partial templates
* @return String the partial template, ready for substitutions to be carried out
*/
public function apikeysettings($msg) {
ob_start();
?>
{{api_key_setting_premium_label}}
__('Create a new API user with access to only this container (rather than your whole account)', 'updraftplus'),
'updraftplus_current_clean_url' => UpdraftPlus::get_current_clean_url(),
);
}
/**
* Calls the Rackspace API to create a new API user
*
* @param Array $use_settings - expected keys are: adminuser, adminapikey, newuser, container, newemail; also allowed are location, region
*
* @return Array - the contents depend upon the outcome. 'e' will be present (0|1) to indicate failure or success
*/
public function create_api_user($use_settings) {
if (!isset($use_settings['adminuser'])) {
return array('e' => 1, 'm' => __('You need to enter an admin username', 'updraftplus'));
}
if (empty($use_settings['adminapikey'])) {
return array('e' => 1, 'm' => __('You need to enter an admin API key', 'updraftplus'));
}
if (!isset($use_settings['newuser'])) {
return array('e' => 1, 'm' => __('You need to enter a new username', 'updraftplus'));
}
if (empty($use_settings['container'])) {
return array('e' => 1, 'm' => __('You need to enter a container', 'updraftplus'));
}
// Here, 0 == catches both 0 and false
if (empty($use_settings['newemail']) || 0 == strpos($use_settings['newemail'], '@')) {
return array('e' => 1, 'm' => __('You need to enter a valid new email address', 'updraftplus'));
}
if (empty($use_settings['location'])) $use_settings['location'] = 'us';
if (empty($use_settings['region'])) $use_settings['region'] = 'DFW';
updraft_try_include_file('methods/cloudfiles.php', 'include_once');
updraft_try_include_file('vendor/autoload.php', 'include_once');
$method = new UpdraftPlus_BackupModule_cloudfiles;
$useservercerts = !empty($use_settings['useservercerts']);
$disableverify = !empty($use_settings['disableverify']);
$auth_url = ('uk' == $use_settings['location']) ? Rackspace::UK_IDENTITY_ENDPOINT : Rackspace::US_IDENTITY_ENDPOINT;
try {
$storage = $method->get_openstack_service(
array(
'user' => $use_settings['adminuser'],
'apikey' => $use_settings['adminapikey'],
'authurl' => $auth_url,
'region' => $use_settings['region']
),
$useservercerts,
$disableverify
);
} catch (AuthenticationError $e) {
global $updraftplus;
$updraftplus->log('Cloud Files authentication failed ('.$e->getMessage().')');
$updraftplus->log(__('Cloud Files authentication failed', 'updraftplus').' ('.$e->getMessage().')', 'error');
return false;
} catch (Exception $e) {
return array('e' => 1, 'm' => __('Error:', 'updraftplus').' '.$e->getMessage());
}
// Create the container (if necessary)
// Get the container
try {
$container_object = $storage->getContainer($use_settings['container']);
} catch (Guzzle\Http\Exception\ClientErrorResponseException $e) {
$container_object = $storage->createContainer($use_settings['container']);
} catch (Exception $e) {
return array('e' => 1, 'm' => __('Cloud Files authentication failed', 'updraftplus').' ('.get_class($e).', '.$e->getMessage().')');
}
if (!is_a($container_object, 'OpenCloud\ObjectStore\Resource\Container') && !is_a($container_object, 'Container')) {
return array('e' => 1, 'm' => __('Cloud Files authentication failed', 'updraftplus').' ('.get_class($container_object).')');
}
// Create the new user
$json = json_encode(
array(
'user' => array(
'username' => $use_settings['newuser'],
'email' => $use_settings['newemail'],
'enabled' => true
)
)
);
$client = $method->get_client();
try {
$response = $client->post($auth_url.'users', array('Content-Type' => 'application/json', 'Accept' => 'application/json'), $json)->send()->json();
} catch (Guzzle\Http\Exception\ClientErrorResponseException $e) {
$response = $e->getResponse();
$code = $response->getStatusCode();
$reason = $response->getReasonPhrase();
if (403 == $code) {
return array('e' => 1, 'm' => __('Authorisation failed (check your credentials)', 'updraftplus'));
} elseif (409 == $code && 'Conflict' == $reason) {
return array('e' => 1, 'm' => __('Conflict: that user or email address already exists', 'updraftplus'));
} else {
return array('e' => 1, 'm' => sprintf(__('Cloud Files operation failed (%s)', 'updraftplus'), 5)." (".$e->getMessage().') ('.get_class($e).')');
}
} catch (Exception $e) {
return array('e' => 1, 'm' => sprintf(__('Cloud Files operation failed (%s)', 'updraftplus'), 4).' ('.$e->getMessage().') ('.get_class($e).')');
}
if (empty($response['user']['id']) || empty($response['user']['OS-KSADM:password']) || empty($response['user']['username'])) {
return array('e' => 1, 'm' => sprintf(__('Cloud Files operation failed (%s)', 'updraftplus'), 3));
}
$user = $response['user']['username'];
$pass = $response['user']['OS-KSADM:password'];
$id = $response['user']['id'];
// Add the user to the container
try {
// The 'X-Container-Write' and 'X-Container-Read' headers always override the previous ACL configurations on the existing container. We need to also include the other users who already have access to this container to ensure we don't remove their access.
$container_metadata = $container_object->getMetadata();
$container_read_users = (null !== $container_metadata->getProperty('read') && '' != $container_metadata->getProperty('read')) ? $container_metadata->getProperty('read') . ',' . $user : $user;
$container_write_users = (null !== $container_metadata->getProperty('write') && '' != $container_metadata->getProperty('write')) ? $container_metadata->getProperty('write') . ',' . $user : $user;
$headers = array('X-Container-Write' => $container_write_users, 'X-Container-Read' => $container_read_users);
$container_object->getClient()->post($container_object->getUrl(), $headers)->send();
} catch (Exception $e) {
return array('e' => 1, 'm' => sprintf(__('Cloud Files operation failed (%s)', 'updraftplus'), 1).' ('.$e->getMessage().') ('.get_class($e).')');
}
// Get an API key for the user
try {
$response = $container_object->getClient()->post($auth_url."users/$id/OS-KSADM/credentials/RAX-KSKEY:apiKeyCredentials/RAX-AUTH/reset", array())->send()->json();
if (empty($response['RAX-KSKEY:apiKeyCredentials']['apiKey'])) {
return array('e' => 1, 'm' => sprintf(__('Cloud Files operation failed (%s)', 'updraftplus'), 8));
}
$apikey = $response['RAX-KSKEY:apiKeyCredentials']['apiKey'];
} catch (Exception $e) {
return array('e' => 1, 'm' => sprintf(__('Cloud Files operation failed (%s)', 'updraftplus'), 7).' ('.$e->getMessage().') ('.get_class($e).')');
}
return array(
'e' => 0,
'u' => htmlspecialchars($user),
'p' => htmlspecialchars($pass),
'k' => htmlspecialchars($apikey),
'a' => $auth_url = ('uk' == $use_settings['location']) ? 'https://lon.auth.api.rackspacecloud.com' : 'https://auth.api.rackspacecloud.com',
'r' => $use_settings['region'],
'c' => $use_settings['container'],
'm' => htmlspecialchars(sprintf(__("Username: %s", 'updraftplus'), $user))."
".htmlspecialchars(sprintf(__("Password: %s", 'updraftplus'), $pass))."
".htmlspecialchars(sprintf(__("API Key: %s", 'updraftplus'), $apikey))
);
}
/**
* Create a new user
*
* @uses self::create_api_user()
*
* @param Array $use_settings - user settings
*/
public function newuser($use_settings = array()) {
$data = $this->create_api_user($use_settings);
echo json_encode($data);
die();
}
public function admin_footer() {
$this->modal_css();
$this->modal_html();
$this->modal_script();
}
private function modal_css() {
?>
accounts;
}
private function get_account_options() {
$selaccount = 'us';
foreach ($this->accounts as $acc => $desc) {
?>regions;
}
private function get_region_options() {
$selregion = 'DFW';
foreach ($this->regions as $reg => $desc) {
?>