/** * Auto-configures an Amazon S3 Bucket's ACLs. * * @package optimizeMember\Files * @since 110926 * * @return array Array containing a true `success` element on success, else a failure array. * Failure array will contain a failure `code`, and a failure `message`. */ public static function amazon_s3_auto_configure_acls() { foreach ($GLOBALS["WS_PLUGIN__"]["optimizemember"]["o"] as $option => $option_value) { if (preg_match("/^amazon_s3_files_/", $option) && ($option = preg_replace("/^amazon_s3_files_/", "", $option))) { $s3c[$option] = $option_value; } } /**/ $cfc["distros_s3_access_id"] = $GLOBALS["WS_PLUGIN__"]["optimizemember"]["o"]["amazon_cf_files_distros_s3_access_id"]; /**/ if ($s3c["bucket"] && $s3c["access_key"] && $s3c["secret_key"]) { $s3_date = gmdate("D, d M Y H:i:s") . " GMT"; $s3_location = strtolower($s3c["bucket"]) !== $s3c["bucket"] ? "/" . $s3c["bucket"] . "/?acl" : "/?acl"; $s3_domain = strtolower($s3c["bucket"]) !== $s3c["bucket"] ? "s3.amazonaws.com" : $s3c["bucket"] . ".s3.amazonaws.com"; $s3_signature = base64_encode(c_ws_plugin__optimizemember_files_in::amazon_s3_sign("GET\n\n\n" . $s3_date . "\n/" . $s3c["bucket"] . "/?acl")); $s3_args = array("method" => "GET", "redirection" => 0, "headers" => array("Host" => $s3_domain, "Date" => $s3_date, "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature)); /**/ if (($s3_response = c_ws_plugin__optimizemember_utils_urls::remote("https://" . $s3_domain . $s3_location, false, array_merge($s3_args, array("timeout" => 20)), "array")) && $s3_response["code"] === 200) { if (preg_match("/\\<Owner\\>(.+?)\\<\\/Owner\\>/is", $s3_response["body"], $s3_owner_tag) && preg_match("/\\<ID\\>(.+?)\\<\\/ID\\>/is", $s3_owner_tag[1], $s3_owner_id_tag) && (preg_match("/\\<DisplayName\\>(.*?)\\<\\/DisplayName\\>/is", $s3_owner_tag[1], $s3_owner_display_name_tag) || ($s3_owner_display_name_tag = array("-", "Owner")))) { $s3_owner = array("access_id" => trim($s3_owner_id_tag[1]), "display_name" => trim($s3_owner_display_name_tag[1])); $s3_acls_xml = '<AccessControlPolicy><Owner><ID>' . esc_html($s3_owner["access_id"]) . '</ID><DisplayName>' . esc_html($s3_owner["display_name"]) . '</DisplayName></Owner><AccessControlList><Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>' . esc_html($s3_owner["access_id"]) . '</ID><DisplayName>' . esc_html($s3_owner["display_name"]) . '</DisplayName></Grantee><Permission>FULL_CONTROL</Permission></Grant>' . ($cfc["distros_s3_access_id"] ? '<Grant><Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"><ID>' . esc_html($cfc["distros_s3_access_id"]) . '</ID><DisplayName>optimizeMember/CloudFront</DisplayName></Grantee><Permission>READ</Permission></Grant>' : '') . '</AccessControlList></AccessControlPolicy>'; $s3_signature = base64_encode(c_ws_plugin__optimizemember_files_in::amazon_s3_sign("PUT\n\napplication/xml\n" . $s3_date . "\n/" . $s3c["bucket"] . "/?acl")); $s3_args = array("method" => "PUT", "redirection" => 0, "body" => $s3_acls_xml, "headers" => array("Host" => $s3_domain, "Content-Type" => "application/xml", "Date" => $s3_date, "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature)); /**/ if (($s3_response = c_ws_plugin__optimizemember_utils_urls::remote("https://" . $s3_domain . $s3_location, false, array_merge($s3_args, array("timeout" => 20)), "array")) && $s3_response["code"] === 200) { $s3_location = strtolower($s3c["bucket"]) !== $s3c["bucket"] ? "/" . $s3c["bucket"] . "/?policy" : "/?policy"; ($s3_policy_id = md5(uniqid("optimizeMember/CloudFront:", true))) . ($s3_policy_sid = md5(uniqid("optimizeMember/CloudFront:", true))); $s3_policy_json = '{"Version":"2008-10-17","Id":"' . c_ws_plugin__optimizemember_utils_strings::esc_dq($s3_policy_id) . '","Statement":[{"Sid":"' . c_ws_plugin__optimizemember_utils_strings::esc_dq($s3_policy_sid) . '","Effect":"Allow","Principal":{"CanonicalUser":"******"distros_s3_access_id"]) . '"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::' . c_ws_plugin__optimizemember_utils_strings::esc_dq($s3c["bucket"]) . '/*"}]}'; $s3_signature = base64_encode(c_ws_plugin__optimizemember_files_in::amazon_s3_sign("PUT\n\napplication/json\n" . $s3_date . "\n/" . $s3c["bucket"] . "/?policy")); $s3_args = array("method" => "PUT", "redirection" => 0, "body" => $s3_policy_json, "headers" => array("Host" => $s3_domain, "Content-Type" => "application/json", "Date" => $s3_date, "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature)); /**/ if (!$cfc["distros_s3_access_id"] || ($s3_response = c_ws_plugin__optimizemember_utils_urls::remote("https://" . $s3_domain . $s3_location, false, array_merge($s3_args, array("timeout" => 20)), "array")) && ($s3_response["code"] === 200 || $s3_response["code"] === 204)) { $s3_location = strtolower($s3c["bucket"]) !== $s3c["bucket"] ? "/" . $s3c["bucket"] . "/crossdomain.xml" : "/crossdomain.xml"; $s3_policy_xml = trim(c_ws_plugin__optimizemember_utilities::evl(file_get_contents(dirname(dirname(__FILE__)) . "/templates/cfg-files/s2-cross-xml.php"))); $s3_signature = base64_encode(c_ws_plugin__optimizemember_files_in::amazon_s3_sign("PUT\n\ntext/xml\n" . $s3_date . "\nx-amz-acl:public-read\n/" . $s3c["bucket"] . "/crossdomain.xml")); $s3_args = array("method" => "PUT", "redirection" => 0, "body" => $s3_policy_xml, "headers" => array("Host" => $s3_domain, "Content-Type" => "text/xml", "Date" => $s3_date, "X-Amz-Acl" => "public-read", "Authorization" => "AWS " . $s3c["access_key"] . ":" . $s3_signature)); /**/ if (($s3_response = c_ws_plugin__optimizemember_utils_urls::remote("https://" . $s3_domain . $s3_location, false, array_merge($s3_args, array("timeout" => 20)), "array")) && $s3_response["code"] === 200) { return array("success" => true, "code" => null, "message" => null); } else { if (isset($s3_response["code"], $s3_response["message"])) { /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */ return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Cross-Domain Policy. %s", "s2member-admin", "s2member"), $s3_response["message"])); } else { /* Else, we use a default error code and message. */ return array("success" => false, "code" => -94, "message" => _x("Unable to update existing Amazon S3 Cross-Domain Policy. Connection failed.", "s2member-admin", "s2member")); } } } else { if (isset($s3_response["code"], $s3_response["message"])) { /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */ return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Bucket Policy. %s", "s2member-admin", "s2member"), $s3_response["message"])); } else { /* Else, we use a default error code and message. */ return array("success" => false, "code" => -95, "message" => _x("Unable to update existing Amazon S3 Bucket Policy. Connection failed.", "s2member-admin", "s2member")); } } } else { if (isset($s3_response["code"], $s3_response["message"])) { /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */ return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to update existing Amazon S3 Bucket ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"])); } else { /* Else, we use a default error code and message. */ return array("success" => false, "code" => -96, "message" => _x("Unable to update existing Amazon S3 Bucket ACLs. Connection failed.", "s2member-admin", "s2member")); } } } else { /* Else, we use a default error code and message. */ return array("success" => false, "code" => -97, "message" => _x("Unable to acquire/read existing Amazon S3 Bucket ACLs. Unexpected response.", "s2member-admin", "s2member")); } } else { if (isset($s3_response["code"], $s3_response["message"])) { /* translators: In this translation, `%s` may be filled with an English message, which comes from the Amazon S3 API call. Feel free to exclude `%s` if you like. */ return array("success" => false, "code" => $s3_response["code"], "message" => sprintf(_x("Unable to acquire existing Amazon S3 Bucket ACLs. %s", "s2member-admin", "s2member"), $s3_response["message"])); } else { /* Else, we use a default error code and message. */ return array("success" => false, "code" => -98, "message" => _x("Unable to acquire existing Amazon S3 Bucket ACLs. Connection failed.", "s2member-admin", "s2member")); } } } else { /* Else, we use a default error code and message. */ return array("success" => false, "code" => -99, "message" => _x("Unable to auto-configure existing Amazon S3 Bucket ACLs. Incomplete Amazon S3 configuration options. Missing one of: Amazon S3 Bucket, Access Key, or Secret Key.", "s2member-admin", "s2member")); } }