partial_template_name }}) * * @param Array $partial_templates A collection of filterable partial templates * @return Array an associative array keyed by name of the partial templates */ public function get_partial_templates($partial_templates) { ob_start(); ?> {{#> updraft_s3_apikeysetting}} {{api_key_setting_default_label}} {{/updraft_s3_apikeysetting}} __('To create a new IAM sub-user and access key that has access only to this bucket, upgrade to Premium.', 'updraftplus'), 'api_key_setting_premium_label' => __('If you have an AWS admin user, then you can use this wizard to quickly create a new AWS (IAM) user with access to only this bucket (rather than your whole account)', 'updraftplus'), 'input_storage_class_label' => __('Storage class', 'updraftplus'), 'input_storage_class_aria' => __('Read more about storage classes', 'updraftplus'), 'input_storage_class_text' => __('(Read more)', 'updraftplus'), 'input_storage_class_option_labels' => array( 'STANDARD' => __('Standard', 'updraftplus'), 'STANDARD_IA' => __('Standard (infrequent access)', 'updraftplus'), 'INTELLIGENT_TIERING' => __('Intelligent Tiering', 'updraftplus'), ), 'input_server_encryption_label' => __('Server-side encryption', 'updraftplus'), 'input_server_encryption_aria' => __('Read more about server-side encryption', 'updraftplus'), 'input_server_encryption_text' => __('(Read more)', 'updraftplus'), 'input_server_encryption_title' => __("Check this box to use Amazon's server-side encryption", 'updraftplus'), 'updraftplus_current_clean_url' => esc_url(UpdraftPlus::get_current_clean_url()), 'updraftplus_premium_url' => $updraftplus->get_url('premium'), ); } /** * WordPress filter updraft_s3_storageclass * * @param String $class - suggested storage class * @param Object $storage - storage object * @param Array $opts - options * * @return String - filtered value */ public function storageclass($class, $storage, $opts) { if (((is_a($storage, 'UpdraftPlus_S3') || is_a($storage, 'UpdraftPlus_S3_Compat')) && is_array($opts) && !empty($opts['rrs']) && in_array($opts['rrs'], array('STANDARD', 'STANDARD_IA', 'INTELLIGENT_TIERING')))) $class = $opts['rrs']; return $class; } /** * This method gives template string to the page for the extra storage options. * * @param Object $existing_partial_template_str - partial template string to which this outputted template appended * * @return String - the partial template, ready for substitutions to be carried out */ public function extra_storage_options_configuration_template($existing_partial_template_str) { ob_start(); ?> {{! Any value in the below template should be escaped using double curly braces, so please make sure no value is an raw format that is triple-stashed }} {{input_storage_class_label}}:
{{input_storage_class_text}} {{input_server_encryption_label}}:
{{input_server_encryption_text}} {{api_key_setting_premium_label}} newuser_go(array(), stripslashes_deep($data))); die; } /** * Create a new user * * @param Array $initial_value - present because this method is used as a WP filter * @param Array $settings_values - various keys indicating the access and desired bucket details * * @return Array - results (with keys dependent upon the outcome) */ public function newuser_go($initial_value = array(), $settings_values = array()) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Unused parameter is present because the method is used as a WP filter. if (empty($settings_values['adminaccesskey'])) { return array('e' => 1, 'm' => __('You need to enter an admin access key', 'updraftplus')); } if (empty($settings_values['adminsecret'])) { return array('e' => 1, 'm' => __('You need to enter an admin secret key', 'updraftplus')); } if (empty($settings_values['newuser'])) { return array('e' => 1, 'm' => __('You need to enter a new IAM username', 'updraftplus')); } if (empty($settings_values['bucket'])) { return array('e' => 1, 'm' => __('You need to enter a bucket', 'updraftplus')); } if (empty($settings_values['region'])) $settings_values['region'] = 'us-east-1'; if (empty($settings_values['rrs'])) $settings_values['rrs'] = false; $allow_download = empty($settings_values['allowdownload']) ? false : true; $allow_delete = empty($settings_values['allowdelete']) ? false : true; global $updraftplus; updraft_try_include_file('methods/s3.php', 'include_once'); $method = new UpdraftPlus_BackupModule_s3; $useservercerts = !empty($settings_values['useservercerts']); $disableverify = !empty($settings_values['disableverify']); $nossl = !empty($settings_values['nossl']); $adminaccesskey = $settings_values['adminaccesskey']; $adminsecret = $settings_values['adminsecret']; $region = $settings_values['region']; $return_error = false; try { $storage = $method->getS3($adminaccesskey, $adminsecret, $useservercerts, $disableverify, $nossl); if (!is_a($storage, 'UpdraftPlus_S3_Compat') && !is_a($storage, 'UpdraftPlus_S3')) { $msg = __('Cannot create new AWS user, since an unknown AWS toolkit is being used.', 'updraftplus'); $updraftplus->log('Cannot create new AWS user, since an unknown AWS toolkit is being used.'); $updraftplus->log($msg, 'error'); $return_error = array('e' => 1, 'm' => __('Error:', 'updraftplus').' '.$msg); } } catch (AuthenticationError $e) { $updraftplus->log('AWS authentication failed ('.$e->getMessage().')'); $updraftplus->log(__('AWS authentication failed', 'updraftplus').' ('.$e->getMessage().')', 'error'); $return_error = array('e' => 1, 'm' => __('Error:', 'updraftplus').' '.$e->getMessage()); } catch (Exception $e) { $return_error = array('e' => 1, 'm' => __('Error:', 'updraftplus').' '.$e->getMessage()); } if (is_array($return_error)) return $return_error; // Get the bucket $path = $settings_values['bucket']; if (preg_match("#^/*([^/]+)/(.*)$#", $path, $bmatches)) { $bucket = $bmatches[1]; $path = trailingslashit($bmatches[2]); } else { $bucket = $path; $path = ""; } $location = @$storage->getBucketLocation($bucket);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the method. if ($location) { $bucket_exists = true; } if (!isset($bucket_exists)) { $storage->useDNSBucketName(true); $gb = @$storage->getBucket($bucket, null, null, 1);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the method. if (false !== $gb) { $bucket_exists = true; $location = ''; } } if (!isset($bucket_exists)) { $storage->setExceptions(true); try { $try_to_create_bucket = @$storage->putBucket($bucket, 'private', $region);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the method. } catch (Exception $e) { $try_to_create_bucket = false; $s3_error = $e->getMessage(); } $storage->setExceptions(false); if ($try_to_create_bucket) { $gb = $try_to_create_bucket; } else { $msg = __('Failure: We could not successfully access or create such a bucket.', 'updraftplus').' '.__('Please check your access credentials, and if those are correct then try another bucket name (as another AWS user may already have taken your name).', 'updraftplus'); if (isset($s3_error)) $msg .= "\n\n".sprintf(__('The error reported by %s was:', 'updraftplus'), 'S3').' '.$s3_error; return array('e' => 1, 'm' => $msg); } } // Create the new IAM user try { $response = $storage->createUser(array('Path' => '/updraftplus/', 'UserName' => $settings_values['newuser'])); } catch (Exception $e) { return array('e' => 1, 'm' => sprintf(__('IAM operation failed (%s)', 'updraftplus'), 4).' ('.$e->getMessage().') ('.get_class($e).')'); } if (403 == $response['code']) { return array('e' => 1, 'm' => __('Authorisation failed (check your credentials)', 'updraftplus')); } elseif (409 == $response['code']) { return array('e' => 1, 'm' => __('Conflict: that user already exists', 'updraftplus')); } if (empty($response['User']['UserId']) || empty($response['User']['CreateDate']) || empty($response['User']['UserName'])) { return array('e' => 1, 'm' => sprintf(__('IAM operation failed (%s)', 'updraftplus'), 5)." (".$response['error']['message'].')'); } $user = $response['User']['UserName']; // Add the User to the bucket try { $response = $storage->createAccessKey($user); } catch (Exception $e) { return array('e' => 1, 'm' => __('Operation to create user Access Key failed', 'updraftplus')); } if (empty($response['AccessKey']['UserName']) || empty($response['AccessKey']['AccessKeyId']) || empty($response['AccessKey']['SecretAccessKey'])) { return array('e' => 1, 'm' => __('Operation to create user Access Key failed', 'updraftplus').' (2)'); } $key = $response['AccessKey']['AccessKeyId']; $secret = $response['AccessKey']['SecretAccessKey']; // policy document $pol_doc = '{ "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads" ], "Resource": "arn:aws:s3:::'.$bucket.'", "Condition": {} }, { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload",'; if ($allow_delete) $pol_doc .= ' "s3:DeleteObject", "s3:DeleteObjectVersion",'; if ($allow_download) $pol_doc .= ' "s3:GetObject", "s3:GetObjectAcl", "s3:GetObjectVersion", "s3:GetObjectVersionAcl",'; $pol_doc .= ' "s3:PutObject", "s3:PutObjectAcl", "s3:PutObjectVersionAcl" ], "Resource": "arn:aws:s3:::'.$bucket.'/*", "Condition": {} }, { "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*", "Condition": {} } ] }'; try { $response = $storage->putUserPolicy(array( 'UserName' => $user, 'PolicyName' => $user.'updraftpolicy', 'PolicyDocument' => $pol_doc )); } catch (Exception $e) { return array('e' => 1, 'm' => __('Failed to apply User Policy'.$e->getMessage())); } if (!empty($response['error'])) { return array('e' => 1, 'm' => __('Failed to apply User Policy', 'updraftplus')." (".$response['error']['message'].')'); } return array( 'e' => 0, 'u' => htmlspecialchars($user), 'k' => htmlspecialchars($key), 's' => htmlspecialchars($secret), 'l' => $region, 'c' => $bucket, 'm' => htmlspecialchars(sprintf(__("Username: %s", 'updraftplus'), $user))."
".htmlspecialchars(sprintf(__("Access Key: %s", 'updraftplus'), $key))."
".htmlspecialchars(sprintf(__("Secret Key: %s", 'updraftplus'), $secret)) ); } /** * This is called both directly, and made available as an action * * @param boolean $include_form_apparatus */ public function s3_print_new_api_user_form($include_form_apparatus = true) { ?>

s3://