mirror of
https://github.com/moodle/moodle.git
synced 2025-04-20 07:56:06 +02:00
Merge branch 'MDL-78511-master2' of https://github.com/raortegar/moodle
This commit is contained in:
commit
d1024fae70
@ -29,7 +29,7 @@ use tool_mfa\local\form\revoke_factor_form;
|
||||
|
||||
require_login(null, false);
|
||||
if (isguestuser()) {
|
||||
throw new require_login_exception('Guests are not allowed here.');
|
||||
throw new require_login_exception('error:isguestuser', 'tool_mfa');
|
||||
}
|
||||
|
||||
$action = optional_param('action', '', PARAM_ALPHANUMEXT);
|
||||
@ -85,6 +85,7 @@ switch ($action) {
|
||||
$form->is_validated();
|
||||
|
||||
if ($form->is_cancelled()) {
|
||||
$factorobject->setup_factor_form_is_cancelled($factorid);
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ interface object_factor {
|
||||
* Defines setup_factor form definition page for particular factor.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
public function setup_factor_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm;
|
||||
@ -74,7 +74,7 @@ interface object_factor {
|
||||
* Defines setup_factor form definition page after form data has been set.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
public function setup_factor_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm;
|
||||
@ -92,7 +92,7 @@ interface object_factor {
|
||||
* Defines login form definition page for particular factor.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
public function login_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm;
|
||||
@ -101,7 +101,7 @@ interface object_factor {
|
||||
* Defines login form definition page after form data has been set.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
* @throws \coding_exception
|
||||
*/
|
||||
public function login_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm;
|
||||
@ -115,6 +115,21 @@ interface object_factor {
|
||||
*/
|
||||
public function login_form_validation(array $data): array;
|
||||
|
||||
/**
|
||||
* Setups in given factor when the form is cancelled
|
||||
*
|
||||
* @param int $factorid
|
||||
* @return void
|
||||
*/
|
||||
public function setup_factor_form_is_cancelled(int $factorid): void;
|
||||
|
||||
/**
|
||||
* Setup submit button string in given factor
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function setup_factor_form_submit_button_string(): ?string;
|
||||
|
||||
/**
|
||||
* Setups given factor and adds it to user's active factors list.
|
||||
* Returns true if factor has been successfully added, otherwise false.
|
||||
|
@ -152,7 +152,7 @@ abstract class object_factor_base implements object_factor {
|
||||
* Dummy implementation. Should be overridden in child class.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function setup_factor_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
return $mform;
|
||||
@ -164,7 +164,7 @@ abstract class object_factor_base implements object_factor {
|
||||
* Dummy implementation. Should be overridden in child class.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function setup_factor_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
return $mform;
|
||||
@ -183,6 +183,28 @@ abstract class object_factor_base implements object_factor {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups in given factor when the form is cancelled
|
||||
*
|
||||
* Dummy implementation. Should be overridden in child class.
|
||||
*
|
||||
* @param int $factorid
|
||||
* @return void
|
||||
*/
|
||||
public function setup_factor_form_is_cancelled(int $factorid): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup submit button string in given factor
|
||||
*
|
||||
* Dummy implementation. Should be overridden in child class.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function setup_factor_form_submit_button_string(): ?string {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups given factor and adds it to user's active factors list.
|
||||
* Returns true if factor has been successfully added, otherwise false.
|
||||
@ -232,7 +254,7 @@ abstract class object_factor_base implements object_factor {
|
||||
* Dummy implementation. Should be overridden in child class.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function login_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
return $mform;
|
||||
@ -244,7 +266,7 @@ abstract class object_factor_base implements object_factor {
|
||||
* Dummy implementation. Should be overridden in child class.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function login_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
return $mform;
|
||||
|
@ -71,7 +71,7 @@ class setup_factor_form extends \moodleform {
|
||||
$factor = \tool_mfa\plugininfo\factor::get_factor($factorname);
|
||||
$mform = $factor->setup_factor_form_definition_after_data($mform);
|
||||
$this->xss_whitelist_static_form_elements($mform);
|
||||
$this->add_action_buttons();
|
||||
$this->add_action_buttons(true, $factor->setup_factor_form_submit_button_string());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +49,7 @@ class factor extends object_factor_base {
|
||||
* E-Mail Factor implementation.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform Form to inject global elements into.
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function login_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
$this->generate_and_email_code();
|
||||
|
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Admin setting for AWS regions.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Dmitrii Metelkin <dmitriim@catalyst-au.net>
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace factor_sms;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot . '/lib/adminlib.php');
|
||||
|
||||
/**
|
||||
* Admin setting for a list of AWS regions.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class admin_settings_aws_region extends \admin_setting_configtext {
|
||||
|
||||
/**
|
||||
* Return part of form with setting.
|
||||
*
|
||||
* @param mixed $data array or string depending on setting
|
||||
* @param string $query
|
||||
* @return string
|
||||
*/
|
||||
public function output_html($data, $query='') {
|
||||
global $CFG, $OUTPUT;
|
||||
|
||||
$default = $this->get_defaultsetting();
|
||||
$options = [];
|
||||
$all = require_once($CFG->dirroot . '/lib/aws-sdk/src/data/endpoints.json.php');
|
||||
$ends = $all['partitions'][0]['regions'];
|
||||
if ($ends) {
|
||||
foreach ($ends as $key => $value) {
|
||||
$options[] = [
|
||||
'value' => $key,
|
||||
'label' => $key . ' - ' . $value['description'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$context = [
|
||||
'list' => $this->get_full_name(),
|
||||
'name' => $this->get_full_name(),
|
||||
'id' => $this->get_id(),
|
||||
'value' => $data,
|
||||
'size' => $this->size,
|
||||
'options' => $options,
|
||||
];
|
||||
$element = $OUTPUT->render_from_template('factor_sms/setting_aws_region', $context);
|
||||
return format_admin_setting($this, $this->visiblename, $element, $this->description, true, '', $default, $query);
|
||||
}
|
||||
}
|
62
admin/tool/mfa/factor/sms/classes/event/sms_sent.php
Normal file
62
admin/tool/mfa/factor/sms/classes/event/sms_sent.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace factor_sms\event;
|
||||
|
||||
/**
|
||||
* Event for a sent SMS
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Alex Morris <alex.morris@catalyst.net.nz>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class sms_sent extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init sms sent event
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['crud'] = 'r';
|
||||
$this->data['edulevel'] = self::LEVEL_OTHER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns non-localised event description with id's for admin use only.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description(): string {
|
||||
|
||||
$content = [
|
||||
'userid' => $this->other['userid'],
|
||||
'debuginfo' => is_array($this->other['debug']) ? json_encode($this->other['debug']) : $this->other['debug'],
|
||||
];
|
||||
|
||||
return get_string('event:smssentdescription', 'factor_sms', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* Override in subclass, we can not make it static and abstract at the same time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name(): string {
|
||||
return get_string('event:smssent', 'factor_sms');
|
||||
}
|
||||
}
|
457
admin/tool/mfa/factor/sms/classes/factor.php
Normal file
457
admin/tool/mfa/factor/sms/classes/factor.php
Normal file
@ -0,0 +1,457 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace factor_sms;
|
||||
|
||||
use moodle_url;
|
||||
use stdClass;
|
||||
use tool_mfa\local\factor\object_factor_base;
|
||||
|
||||
/**
|
||||
* SMS Factor implementation.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @subpackage tool_mfa
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class factor extends object_factor_base {
|
||||
|
||||
/** @var string Factor icon */
|
||||
protected $icon = 'fa-commenting-o';
|
||||
|
||||
/**
|
||||
* Defines login form definition page for SMS Factor.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function login_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
$mform->addElement(new \tool_mfa\local\form\verification_field());
|
||||
$mform->setType('verificationcode', PARAM_ALPHANUM);
|
||||
return $mform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines login form definition page after form data has been set.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform Form to inject global elements into.
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function login_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
$this->generate_and_sms_code();
|
||||
|
||||
// Disable the form check prompt.
|
||||
$mform->disable_form_change_checker();
|
||||
return $mform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements login form validation for SMS Factor.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function login_form_validation(array $data): array {
|
||||
$return = [];
|
||||
|
||||
if (!$this->check_verification_code($data['verificationcode'])) {
|
||||
$return['verificationcode'] = get_string('error:wrongverification', 'factor_sms');
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string for setup button on preferences page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_setup_string(): string {
|
||||
return get_string('setupfactorbutton', 'factor_sms');
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines setup_factor form definition page for SMS Factor.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function setup_factor_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
global $OUTPUT, $USER, $DB;
|
||||
|
||||
if (!empty(
|
||||
$phonenumber = $DB->get_field('tool_mfa', 'label', ['factor' => $this->name, 'userid' => $USER->id, 'revoked' => 0])
|
||||
)) {
|
||||
redirect(
|
||||
new \moodle_url('/admin/tool/mfa/user_preferences.php'),
|
||||
get_string('factorsetup', 'tool_mfa', $phonenumber),
|
||||
null,
|
||||
\core\output\notification::NOTIFY_SUCCESS);
|
||||
}
|
||||
|
||||
$mform->addElement('html', $OUTPUT->heading(get_string('setupfactor', 'factor_sms'), 2));
|
||||
|
||||
if (empty($this->get_phonenumber())) {
|
||||
$mform->addElement('hidden', 'verificationcode', 0);
|
||||
$mform->setType('verificationcode', PARAM_ALPHANUM);
|
||||
|
||||
// Add field for phone number setup.
|
||||
$mform->addElement('text', 'phonenumber', get_string('addnumber', 'factor_sms'),
|
||||
[
|
||||
'autocomplete' => 'tel',
|
||||
'inputmode' => 'tel',
|
||||
]);
|
||||
$mform->setType('phonenumber', PARAM_TEXT);
|
||||
|
||||
// HTML to display a message about the phone number.
|
||||
$message = \html_writer::tag('div', '', ['class' => 'col-md-3']);
|
||||
$message .= \html_writer::tag(
|
||||
'div', \html_writer::tag('p', get_string('phonehelp', 'factor_sms')), ['class' => 'col-md-9']);
|
||||
$mform->addElement('html', \html_writer::tag('div', $message, ['class' => 'row']));
|
||||
}
|
||||
|
||||
return $mform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines setup_factor form definition page after form data has been set.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function setup_factor_form_definition_after_data(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
global $OUTPUT;
|
||||
|
||||
$phonenumber = $this->get_phonenumber();
|
||||
if (empty($phonenumber)) {
|
||||
return $mform;
|
||||
}
|
||||
|
||||
$duration = get_config('factor_sms', 'duration');
|
||||
$code = $this->secretmanager->create_secret($duration, true);
|
||||
if (!empty($code)) {
|
||||
$this->sms_verification_code($code, $phonenumber);
|
||||
}
|
||||
$message = get_string('logindesc', 'factor_sms', '<b>' . $phonenumber . '</b><br/>');
|
||||
$message .= get_string('editphonenumberinfo', 'factor_sms');
|
||||
$mform->addElement('html', \html_writer::tag('p', $OUTPUT->notification($message, 'success')));
|
||||
|
||||
$mform->addElement(new \tool_mfa\local\form\verification_field());
|
||||
$mform->setType('verificationcode', PARAM_ALPHANUM);
|
||||
|
||||
$editphonenumber = \html_writer::link(
|
||||
new \moodle_url('/admin/tool/mfa/factor/sms/editphonenumber.php', ['sesskey' => sesskey()]),
|
||||
get_string('editphonenumber', 'factor_sms'),
|
||||
['class' => 'btn btn-secondary', 'type' => 'button']);
|
||||
|
||||
$mform->addElement('html', \html_writer::tag('div', $editphonenumber, ['class' => 'float-sm-left col-md-4']));
|
||||
|
||||
// Disable the form check prompt.
|
||||
$mform->disable_form_change_checker();
|
||||
|
||||
return $mform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the phone number from the current session or from the user profile data.
|
||||
* @return string|null
|
||||
*/
|
||||
private function get_phonenumber(): ?string {
|
||||
global $SESSION, $USER, $DB;
|
||||
|
||||
if (!empty($SESSION->tool_mfa_sms_number)) {
|
||||
return $SESSION->tool_mfa_sms_number;
|
||||
}
|
||||
$phonenumber = $DB->get_field('tool_mfa', 'label', ['factor' => $this->name, 'userid' => $USER->id, 'revoked' => 0]);
|
||||
if (!empty($phonenumber)) {
|
||||
return $phonenumber;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of errors, where array key = field id and array value = error text.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function setup_factor_form_validation(array $data): array {
|
||||
$errors = [];
|
||||
|
||||
// Phone number validation.
|
||||
if (!empty($data["phonenumber"]) && empty(helper::is_valid_phonenumber($data["phonenumber"]))) {
|
||||
$errors['phonenumber'] = get_string('error:wrongphonenumber', 'factor_sms');
|
||||
|
||||
} else if (!empty($this->get_phonenumber())) {
|
||||
// Code validation.
|
||||
if (empty($data["verificationcode"])) {
|
||||
$errors['verificationcode'] = get_string('error:emptyverification', 'factor_sms');
|
||||
} else if ($this->secretmanager->validate_secret($data['verificationcode']) !== $this->secretmanager::VALID) {
|
||||
$errors['verificationcode'] = get_string('error:wrongverification', 'factor_sms');
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset values of the session data of the given factor.
|
||||
*
|
||||
* @param int $factorid
|
||||
* @return void
|
||||
*/
|
||||
public function setup_factor_form_is_cancelled(int $factorid): void {
|
||||
global $SESSION;
|
||||
if (!empty($SESSION->tool_mfa_sms_number)) {
|
||||
unset($SESSION->tool_mfa_sms_number);
|
||||
}
|
||||
// Clean temp secrets code.
|
||||
$secretmanager = new \tool_mfa\local\secret_manager('sms');
|
||||
$secretmanager->cleanup_temp_secrets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup submit button string in given factor
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function setup_factor_form_submit_button_string(): ?string {
|
||||
global $SESSION;
|
||||
if (!empty($SESSION->tool_mfa_sms_number)) {
|
||||
return get_string('setupsubmitcode', 'factor_sms');
|
||||
}
|
||||
return get_string('setupsubmitphone', 'factor_sms');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an instance of the factor for a user, from form data.
|
||||
*
|
||||
* @param stdClass $data
|
||||
* @return stdClass|null the factor record, or null.
|
||||
*/
|
||||
public function setup_user_factor(stdClass $data): ?stdClass {
|
||||
global $DB, $SESSION, $USER;
|
||||
|
||||
// Handle phone number submission.
|
||||
if (empty($SESSION->tool_mfa_sms_number)) {
|
||||
$SESSION->tool_mfa_sms_number = !empty($data->phonenumber) ? $data->phonenumber : '';
|
||||
|
||||
$addurl = new \moodle_url('/admin/tool/mfa/action.php', [
|
||||
'action' => 'setup',
|
||||
'factor' => 'sms',
|
||||
]);
|
||||
redirect($addurl);
|
||||
}
|
||||
|
||||
// If the user somehow gets here through form resubmission.
|
||||
// We dont want two phones active.
|
||||
if ($DB->record_exists('tool_mfa', ['userid' => $USER->id, 'factor' => $this->name, 'revoked' => 0])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$time = time();
|
||||
$label = $this->get_phonenumber();
|
||||
|
||||
$row = new \stdClass();
|
||||
$row->userid = $USER->id;
|
||||
$row->factor = $this->name;
|
||||
$row->secret = '';
|
||||
$row->label = $label;
|
||||
$row->timecreated = $time;
|
||||
$row->createdfromip = $USER->lastip;
|
||||
$row->timemodified = $time;
|
||||
$row->lastverified = $time;
|
||||
$row->revoked = 0;
|
||||
|
||||
$id = $DB->insert_record('tool_mfa', $row);
|
||||
$record = $DB->get_record('tool_mfa', ['id' => $id]);
|
||||
$this->create_event_after_factor_setup($USER);
|
||||
|
||||
// Remove session phone number.
|
||||
unset($SESSION->tool_mfa_sms_number);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all user factors of given type.
|
||||
*
|
||||
* @param stdClass $user the user to check against.
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_user_factors(stdClass $user): array {
|
||||
global $DB;
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM {tool_mfa}
|
||||
WHERE userid = ?
|
||||
AND factor = ?
|
||||
AND label IS NOT NULL
|
||||
AND revoked = 0';
|
||||
|
||||
return $DB->get_records_sql($sql, [$user->id, $this->name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information about factor availability.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled(): bool {
|
||||
if (empty(get_config('factor_sms', 'gateway'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$class = '\factor_sms\local\smsgateway\\' . get_config('factor_sms', 'gateway');
|
||||
if (!call_user_func($class . '::is_gateway_enabled')) {
|
||||
return false;
|
||||
}
|
||||
return parent::is_enabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if a factor requires input from the user to verify.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_input(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if factor needs to be setup by user and has setup_form.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_setup(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if the setup buttons should be shown on the preferences page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function show_setup_buttons(): bool {
|
||||
global $DB, $USER;
|
||||
|
||||
// If there is already a factor setup, don't allow multiple (for now).
|
||||
$record = $DB->get_record('tool_mfa',
|
||||
['userid' => $USER->id, 'factor' => $this->name, 'secret' => '', 'revoked' => 0]);
|
||||
|
||||
return empty($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if factor class has factor records that might be revoked.
|
||||
* It means that user can revoke factor record from their profile.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_revoke(): bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates and sms' the code for login to the user, stores codes in DB.
|
||||
*
|
||||
* @return int|null the instance ID being used.
|
||||
*/
|
||||
private function generate_and_sms_code(): ?int {
|
||||
global $DB, $USER;
|
||||
|
||||
$duration = get_config('factor_sms', 'duration');
|
||||
$instance = $DB->get_record('tool_mfa', ['factor' => $this->name, 'userid' => $USER->id, 'revoked' => 0]);
|
||||
if (empty($instance)) {
|
||||
return null;
|
||||
}
|
||||
$secret = $this->secretmanager->create_secret($duration, false);
|
||||
// There is a new code that needs to be sent.
|
||||
if (!empty($secret)) {
|
||||
// Grab the singleton SMS record.
|
||||
$this->sms_verification_code($secret, $instance->label);
|
||||
}
|
||||
return $instance->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sends an SMS code to the user based on the phonenumber provided.
|
||||
*
|
||||
* @param int $secret the secret to send.
|
||||
* @param string|null $phonenumber the phonenumber to send the verification code to.
|
||||
* @return void
|
||||
*/
|
||||
private function sms_verification_code(int $secret, ?string $phonenumber): void {
|
||||
global $CFG, $SITE;
|
||||
|
||||
// Here we should get the information, then construct the message.
|
||||
$url = new moodle_url($CFG->wwwroot);
|
||||
$content = [
|
||||
'fullname' => $SITE->fullname,
|
||||
'url' => $url->get_host(),
|
||||
'code' => $secret,
|
||||
];
|
||||
$message = get_string('smsstring', 'factor_sms', $content);
|
||||
|
||||
$class = '\factor_sms\local\smsgateway\\' . get_config('factor_sms', 'gateway');
|
||||
$gateway = new $class();
|
||||
$gateway->send_sms_message($message, $phonenumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies entered code against stored DB record.
|
||||
*
|
||||
* @param string $enteredcode
|
||||
* @return bool
|
||||
*/
|
||||
private function check_verification_code(string $enteredcode): bool {
|
||||
return ($this->secretmanager->validate_secret($enteredcode) === \tool_mfa\local\secret_manager::VALID) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all possible states for a user.
|
||||
*
|
||||
* @param \stdClass $user
|
||||
*/
|
||||
public function possible_states(\stdClass $user): array {
|
||||
return [
|
||||
\tool_mfa\plugininfo\factor::STATE_PASS,
|
||||
\tool_mfa\plugininfo\factor::STATE_NEUTRAL,
|
||||
\tool_mfa\plugininfo\factor::STATE_FAIL,
|
||||
\tool_mfa\plugininfo\factor::STATE_UNKNOWN,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the login description associated with this factor.
|
||||
* Override for factors that have a user input.
|
||||
*
|
||||
* @return string The login option.
|
||||
*/
|
||||
public function get_login_desc(): string {
|
||||
|
||||
$phonenumber = $this->get_phonenumber();
|
||||
|
||||
if (empty($phonenumber)) {
|
||||
return get_string('errorsmssent', 'factor_sms');
|
||||
} else {
|
||||
return get_string('logindesc', 'factor_' . $this->name, $phonenumber);
|
||||
}
|
||||
}
|
||||
}
|
67
admin/tool/mfa/factor/sms/classes/helper.php
Normal file
67
admin/tool/mfa/factor/sms/classes/helper.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace factor_sms;
|
||||
|
||||
/**
|
||||
* Helper class for shared sms gateway functions
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Alex Morris <alex.morris@catalyst.net.nz>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class helper {
|
||||
|
||||
/**
|
||||
* This function internationalises a number to E.164 standard.
|
||||
* https://46elks.com/kb/e164
|
||||
*
|
||||
* @param string $phonenumber the phone number to format.
|
||||
* @return string the formatted phone number.
|
||||
*/
|
||||
public static function format_number(string $phonenumber): string {
|
||||
// Remove all whitespace, dashes and brackets.
|
||||
$phonenumber = preg_replace('/[ \(\)-]/', '', $phonenumber);
|
||||
|
||||
// Number is already in international format. Do nothing.
|
||||
if (str_starts_with ($phonenumber, '+')) {
|
||||
return $phonenumber;
|
||||
}
|
||||
|
||||
// Strip leading 0 if found.
|
||||
if (str_starts_with ($phonenumber, '0')) {
|
||||
$phonenumber = substr($phonenumber, 1);
|
||||
}
|
||||
|
||||
// Prepend country code.
|
||||
$countrycode = get_config('factor_sms', 'countrycode');
|
||||
$phonenumber = !empty($countrycode) ? '+' . $countrycode . $phonenumber : $phonenumber;
|
||||
|
||||
return $phonenumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate phone number with E.164 format. https://en.wikipedia.org/wiki/E.164
|
||||
*
|
||||
* @param string $phonenumber from the given user input
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_valid_phonenumber(string $phonenumber) : bool {
|
||||
$phonenumber = self::format_number($phonenumber);
|
||||
return (preg_match("/^\+[1-9]\d{1,14}$/", $phonenumber)) ? true : false;
|
||||
}
|
||||
}
|
100
admin/tool/mfa/factor/sms/classes/local/aws_helper.php
Normal file
100
admin/tool/mfa/factor/sms/classes/local/aws_helper.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* AWS helper class. Contains useful functions when interacting with the SDK.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace factor_sms\local;
|
||||
|
||||
use Aws\CommandInterface;
|
||||
use Aws\AwsClient;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* This class contains functions that help plugins to interact with the AWS SDK.
|
||||
*
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class aws_helper {
|
||||
|
||||
/**
|
||||
* This creates a proxy string suitable for use with the AWS SDK.
|
||||
*
|
||||
* @return string the string to use for proxy settings.
|
||||
*/
|
||||
public static function get_proxy_string(): string {
|
||||
global $CFG;
|
||||
$proxy = '';
|
||||
if (empty($CFG->proxytype)) {
|
||||
return $proxy;
|
||||
}
|
||||
if ($CFG->proxytype === 'SOCKS5') {
|
||||
// If it is a SOCKS proxy, append the protocol info.
|
||||
$protocol = 'socks5://';
|
||||
} else {
|
||||
$protocol = '';
|
||||
}
|
||||
if (!empty($CFG->proxyhost)) {
|
||||
$proxy = $CFG->proxyhost;
|
||||
if (!empty($CFG->proxyport)) {
|
||||
$proxy .= ':'. $CFG->proxyport;
|
||||
}
|
||||
if (!empty($CFG->proxyuser) && !empty($CFG->proxypassword)) {
|
||||
$proxy = $protocol . $CFG->proxyuser . ':' . $CFG->proxypassword . '@' . $proxy;
|
||||
}
|
||||
}
|
||||
return $proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the provided AWS client to route traffic via the moodle proxy for any hosts not excluded.
|
||||
*
|
||||
* @param AwsClient $client
|
||||
* @return AwsClient
|
||||
*/
|
||||
public static function configure_client_proxy(AwsClient $client): AwsClient {
|
||||
$client->getHandlerList()->appendBuild(self::add_proxy_when_required(), 'proxy_bypass');
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a middleware higher order function to wrap the handler and append proxy configuration based on target.
|
||||
*
|
||||
* @return callable Middleware high order callable.
|
||||
*/
|
||||
protected static function add_proxy_when_required(): callable {
|
||||
return function (callable $fn) {
|
||||
return function (CommandInterface $command, ?RequestInterface $request = null) use ($fn) {
|
||||
if (isset($request)) {
|
||||
$target = (string) $request->getUri();
|
||||
if (!is_proxybypass($target)) {
|
||||
$command['@http']['proxy'] = self::get_proxy_string();
|
||||
}
|
||||
}
|
||||
|
||||
$promise = $fn($command, $request);
|
||||
return $promise;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
62
admin/tool/mfa/factor/sms/classes/local/client_factory.php
Normal file
62
admin/tool/mfa/factor/sms/classes/local/client_factory.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* AWS Client factory. Retrieves a client with moodle specific HTTP configuration.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright 2022 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace factor_sms\local;
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* AWS Client factory. Retrieves a client with moodle specific HTTP configuration.
|
||||
*
|
||||
* @copyright 2022 Catalyst IT
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class client_factory {
|
||||
/**
|
||||
* Get an AWS client with moodle specific HTTP configuration.
|
||||
*
|
||||
* @param string $class Fully qualified AWS classname e.g. \Aws\S3\S3Client
|
||||
* @param array $opts array of constructor options for AWS Client.
|
||||
* @return AwsClient
|
||||
*/
|
||||
public static function get_client(string $class, array $opts): AwsClient {
|
||||
// Modify the opts to add HTTP timeouts.
|
||||
if (empty($opts['http'])) {
|
||||
$opts['http'] = ['connect_timeout' => HOURSECS];
|
||||
} else if (!array_key_exists('connect_timeout', $opts['http'])) {
|
||||
// Try not to override existing settings.
|
||||
$opts['http']['connect_timeout'] = HOURSECS;
|
||||
}
|
||||
|
||||
// Blindly trust the call here. If it exceptions, the raw message is the most useful.
|
||||
$client = new $class($opts);
|
||||
if (!$client instanceof \Aws\AwsClient) {
|
||||
throw new \moodle_exception('clientnotfound', 'factor_sms');
|
||||
}
|
||||
|
||||
// Now we can configure the proxy with the routing aware middleware.
|
||||
return aws_helper::configure_client_proxy($client);
|
||||
}
|
||||
}
|
156
admin/tool/mfa/factor/sms/classes/local/smsgateway/aws_sns.php
Normal file
156
admin/tool/mfa/factor/sms/classes/local/smsgateway/aws_sns.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace factor_sms\local\smsgateway;
|
||||
|
||||
use factor_sms\admin_settings_aws_region;
|
||||
use factor_sms\event\sms_sent;
|
||||
use factor_sms\local\aws_helper;
|
||||
|
||||
/**
|
||||
* AWS SNS SMS Gateway class
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class aws_sns implements gateway_interface {
|
||||
|
||||
/**
|
||||
* Create an instance of this class.
|
||||
*/
|
||||
public function __construct() {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/aws-sdk/src/functions.php');
|
||||
require_once($CFG->libdir . '/guzzlehttp/guzzle/src/functions_include.php');
|
||||
require_once($CFG->libdir . '/guzzlehttp/promises/src/functions_include.php');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message using the AWS SNS API
|
||||
*
|
||||
* @param string $messagecontent the content to send in the SMS message.
|
||||
* @param string $phonenumber the destination for the message.
|
||||
* @return bool true on message send success
|
||||
*/
|
||||
public function send_sms_message(string $messagecontent, string $phonenumber): bool {
|
||||
global $SITE, $USER;
|
||||
|
||||
$config = get_config('factor_sms');
|
||||
|
||||
// Setup client params and instantiate client.
|
||||
$params = [
|
||||
'version' => 'latest',
|
||||
'region' => $config->api_region,
|
||||
'http' => ['proxy' => aws_helper::get_proxy_string()],
|
||||
];
|
||||
if (!$config->usecredchain) {
|
||||
$params['credentials'] = [
|
||||
'key' => $config->api_key,
|
||||
'secret' => $config->api_secret,
|
||||
];
|
||||
}
|
||||
$client = new \Aws\Sns\SnsClient($params);
|
||||
|
||||
// Transform the phone number to international standard.
|
||||
$phonenumber = \factor_sms\helper::format_number($phonenumber);
|
||||
|
||||
// Setup the sender information.
|
||||
$senderid = $SITE->shortname;
|
||||
// Remove spaces and non-alphanumeric characters from ID.
|
||||
$senderid = preg_replace("/[^A-Za-z0-9]/", '', trim($senderid));
|
||||
// We have to truncate the senderID to 11 chars.
|
||||
$senderid = substr($senderid, 0, 11);
|
||||
|
||||
if (defined('BEHAT_SITE_RUNNING')) {
|
||||
// Fake SMS sending in behat.
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// These messages need to be transactional.
|
||||
$client->SetSMSAttributes([
|
||||
'attributes' => [
|
||||
'DefaultSMSType' => 'Transactional',
|
||||
'DefaultSenderID' => $senderid,
|
||||
],
|
||||
]);
|
||||
|
||||
// Actually send the message.
|
||||
$result = $client->publish([
|
||||
'Message' => $messagecontent,
|
||||
'PhoneNumber' => $phonenumber,
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'relateduserid' => null,
|
||||
'context' => \context_user::instance($USER->id),
|
||||
'other' => [
|
||||
'userid' => $USER->id,
|
||||
'debug' => [
|
||||
'messageid' => $result->get('MessageId'),
|
||||
],
|
||||
],
|
||||
];
|
||||
$event = sms_sent::create($data);
|
||||
$event->trigger();
|
||||
|
||||
return true;
|
||||
} catch (\Aws\Exception\AwsException $e) {
|
||||
throw new \moodle_exception('errorawsconection', 'factor_sms', '', $e->getAwsErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add gateway specific settings to the SMS factor settings page.
|
||||
*
|
||||
* @param \admin_settingpage $settings
|
||||
* @return void
|
||||
*/
|
||||
public static function add_settings(\admin_settingpage $settings): void {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/admin/tool/mfa/factor/sms/classes/admin_settings_aws_region.php');
|
||||
$settings->add(new \admin_setting_configcheckbox('factor_sms/usecredchain',
|
||||
get_string('settings:aws:usecredchain', 'factor_sms'), '', 0));
|
||||
|
||||
if (!get_config('factor_sms', 'usecredchain')) {
|
||||
// AWS Settings.
|
||||
$settings->add(new \admin_setting_configtext('factor_sms/api_key',
|
||||
get_string('settings:aws:key', 'factor_sms'),
|
||||
get_string('settings:aws:key_help', 'factor_sms'), ''));
|
||||
|
||||
$settings->add(new \admin_setting_configpasswordunmask('factor_sms/api_secret',
|
||||
get_string('settings:aws:secret', 'factor_sms'),
|
||||
get_string('settings:aws:secret_help', 'factor_sms'), ''));
|
||||
}
|
||||
|
||||
$settings->add(new admin_settings_aws_region('factor_sms/api_region',
|
||||
get_string('settings:aws:region', 'factor_sms'),
|
||||
get_string('settings:aws:region_help', 'factor_sms'),
|
||||
'ap-southeast-2'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the gateway is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_gateway_enabled(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* SMS Gateway interface
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace factor_sms\local\smsgateway;
|
||||
|
||||
interface gateway_interface {
|
||||
|
||||
/**
|
||||
* Sends an SMS message
|
||||
*
|
||||
* @param string $messagecontent the content to send in the SMS message.
|
||||
* @param string $phonenumber the destination for the message.
|
||||
* @return bool true on message send success
|
||||
*/
|
||||
public function send_sms_message(string $messagecontent, string $phonenumber): bool;
|
||||
|
||||
/**
|
||||
* Add gateway specific settings to the SMS factor settings page.
|
||||
*
|
||||
* @param \admin_settingpage $settings
|
||||
* @return void
|
||||
*/
|
||||
public static function add_settings(\admin_settingpage $settings): void;
|
||||
|
||||
/**
|
||||
* Returns whether or not the gateway is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_gateway_enabled(): bool;
|
||||
}
|
40
admin/tool/mfa/factor/sms/classes/privacy/provider.php
Normal file
40
admin/tool/mfa/factor/sms/classes/privacy/provider.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace factor_sms\privacy;
|
||||
|
||||
use core_privacy\local\metadata\null_provider;
|
||||
|
||||
/**
|
||||
* Privacy provider.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements null_provider {
|
||||
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason(): string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
44
admin/tool/mfa/factor/sms/editphonenumber.php
Normal file
44
admin/tool/mfa/factor/sms/editphonenumber.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Edit phonenumber redirect
|
||||
*
|
||||
* @package factor_sms
|
||||
* @copyright 2023 Raquel Ortega <raquel.ortega@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '../../../../../../config.php');
|
||||
|
||||
require_login(null, false);
|
||||
if (isguestuser()) {
|
||||
throw new require_login_exception('error:isguestuser', 'tool_mfa');
|
||||
}
|
||||
|
||||
$sesskey = optional_param('sesskey', false, PARAM_TEXT);
|
||||
require_sesskey();
|
||||
|
||||
// Remove session phone number.
|
||||
unset($SESSION->tool_mfa_sms_number);
|
||||
// Clean temp secrets code.
|
||||
$secretmanager = new \tool_mfa\local\secret_manager('sms');
|
||||
$secretmanager->cleanup_temp_secrets();
|
||||
|
||||
redirect(new \moodle_url('/admin/tool/mfa/action.php', [
|
||||
'action' => 'setup',
|
||||
'factor' => 'sms',
|
||||
]));
|
70
admin/tool/mfa/factor/sms/lang/en/factor_sms.php
Normal file
70
admin/tool/mfa/factor/sms/lang/en/factor_sms.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Language strings.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['action:revoke'] = 'Revoke mobile phone number';
|
||||
$string['addnumber'] = 'Mobile number';
|
||||
$string['clientnotfound'] = 'AWS Service client not found. Client must be fully qualified classname e.g. \Aws\S3\S3Client';
|
||||
$string['editphonenumber'] = 'Edit phone number';
|
||||
$string['editphonenumberinfo'] = "If you didn't get the code or entered the wrong number, please edit number and try again.";
|
||||
$string['errorawsconection'] = 'Error connecting to AWS server: {$a}';
|
||||
$string['errorsmssent'] = 'Error sending a SMS message containing your verification code.';
|
||||
$string['error:emptyverification'] = 'Empty code. Try again.';
|
||||
$string['error:wrongphonenumber'] = 'The phone number you provided is not in a valid format.';
|
||||
$string['error:wrongverification'] = 'Wrong code. Try again.';
|
||||
$string['event:smssent'] = 'SMS Message sent';
|
||||
$string['event:smssentdescription'] = 'The user with id {$a->userid} had a verification code sent to them via SMS <br> Information: {$a->debuginfo}';
|
||||
$string['info'] = '<p>Setup Mobile phone to receive authentication code.</p>';
|
||||
$string['logindesc'] = 'We\'ve just sent an SMS containing a 6-digit code to your mobile number: {$a}';
|
||||
$string['loginoption'] = 'Have a code sent to you mobile phone';
|
||||
$string['loginskip'] = "I didn't receive a code";
|
||||
$string['loginsubmit'] = 'Continue';
|
||||
$string['logintitle'] = 'Enter the verification code sent to your mobile';
|
||||
$string['phonehelp'] = 'Enter your mobile number (including country code) to receive a verification code.';
|
||||
$string['pluginname'] = 'SMS Mobile phone';
|
||||
$string['privacy:metadata'] = 'The mobile phone SMS factor plugin does not store any personal data';
|
||||
$string['settings:aws'] = 'AWS SNS';
|
||||
$string['settings:aws:key'] = 'Key';
|
||||
$string['settings:aws:key_help'] = 'Amazon API key credential.';
|
||||
$string['settings:aws:region'] = 'Region';
|
||||
$string['settings:aws:region_help'] = 'Amazon API gateway region.';
|
||||
$string['settings:aws:secret'] = 'Secret';
|
||||
$string['settings:aws:secret_help'] = 'Amazon API secret credential.';
|
||||
$string['settings:aws:usecredchain'] = 'Use the default credential provider chain to find AWS credentials';
|
||||
$string['settings:countrycode'] = 'Country number code';
|
||||
$string['settings:countrycode_help'] = 'The calling code without the leading + as a default if users do not enter an international number with a + prefix.
|
||||
|
||||
See this link for a list of calling codes: {$a}';
|
||||
$string['settings:duration'] = 'Validity duration';
|
||||
$string['settings:duration_help'] = 'The period of time that the code is valid.';
|
||||
$string['settings:gateway'] = 'SMS Gateway';
|
||||
$string['settings:gateway_help'] = 'The SMS provider you wish to send messages via';
|
||||
$string['setupfactor'] = 'SMS Setup';
|
||||
$string['setupfactorbutton'] = 'Setup SMS';
|
||||
$string['setupsubmitcode'] = 'Save';
|
||||
$string['setupsubmitphone'] = 'Send code';
|
||||
$string['smsstring'] = '{$a->code} is your {$a->fullname} one-time security code.
|
||||
|
||||
@{$a->url} #{$a->code}';
|
||||
$string['summarycondition'] = 'Using an SMS one-time security code';
|
66
admin/tool/mfa/factor/sms/settings.php
Normal file
66
admin/tool/mfa/factor/sms/settings.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Settings
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG, $OUTPUT;
|
||||
|
||||
$enabled = new admin_setting_configcheckbox('factor_sms/enabled',
|
||||
new lang_string('settings:enablefactor', 'tool_mfa'),
|
||||
new lang_string('settings:enablefactor_help', 'tool_mfa'), 0);
|
||||
$enabled->set_updatedcallback(function () {
|
||||
\tool_mfa\manager::do_factor_action('sms', get_config('factor_sms', 'enabled') ? 'enable' : 'disable');
|
||||
});
|
||||
$settings->add($enabled);
|
||||
|
||||
$settings->add(new admin_setting_configtext('factor_sms/weight',
|
||||
new lang_string('settings:weight', 'tool_mfa'),
|
||||
new lang_string('settings:weight_help', 'tool_mfa'), 100, PARAM_INT));
|
||||
|
||||
$settings->add(new admin_setting_configduration('factor_sms/duration',
|
||||
get_string('settings:duration', 'tool_mfa'),
|
||||
get_string('settings:duration_help', 'tool_mfa'), 30 * MINSECS, MINSECS));
|
||||
|
||||
$codeslink = 'https://en.wikipedia.org/wiki/List_of_country_calling_codes';
|
||||
$link = \html_writer::link($codeslink, $codeslink);
|
||||
|
||||
$settings->add(new admin_setting_configtext('factor_sms/countrycode',
|
||||
get_string('settings:countrycode', 'factor_sms'),
|
||||
get_string('settings:countrycode_help', 'factor_sms', $link), '', PARAM_INT));
|
||||
|
||||
$gateways = [
|
||||
'aws_sns' => get_string('settings:aws', 'factor_sms'),
|
||||
];
|
||||
|
||||
$settings->add(new admin_setting_configselect('factor_sms/gateway',
|
||||
get_string('settings:gateway', 'factor_sms'),
|
||||
get_string('settings:gateway_help', 'factor_sms'),
|
||||
'aws_sns', $gateways));
|
||||
|
||||
if (empty(get_config('factor_sms', 'gateway'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$class = '\factor_sms\local\smsgateway\\' . get_config('factor_sms', 'gateway');
|
||||
call_user_func($class . '::add_settings', $settings);
|
@ -0,0 +1,50 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template factor_sms/setting_aws_region
|
||||
|
||||
Admin aws region setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* list - form list name
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* value - element value
|
||||
* size - element size
|
||||
* options - list of data list options: label, value.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"list": "test",
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"value": "A tall, dark stranger will have more fun than you.",
|
||||
"size": "21",
|
||||
"options": [ { "label": "eu-north-1 - Europe (Stockholm)", "value": "eu-north-1" } ]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
Setting config aws region
|
||||
}}
|
||||
<div class="form-text defaultsnext">
|
||||
<input type="text" list="{{list}}" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<datalist id="{{list}}">
|
||||
{{#options}}
|
||||
<option value="{{value}}" label="{{label}}"></option>
|
||||
{{/options}}
|
||||
</datalist>
|
||||
</div>
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* factor_sms unit tests.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Mikhail Golenkov <mikhailgolenkov@catalyst-au.net>
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace factor_sms;
|
||||
|
||||
/**
|
||||
* Testcase for the list of AWS regions admin setting.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Mikhail Golenkov <mikhailgolenkov@catalyst-au.net>
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \admin_settings_aws_region_test
|
||||
*/
|
||||
class admin_settings_aws_region_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Cleanup after all tests are executed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
$admin = admin_get_root();
|
||||
$admin->purge_children(true);
|
||||
}
|
||||
/**
|
||||
* Test that output_html() method works and returns HTML string with expected content.
|
||||
*/
|
||||
public function test_output_html(): void {
|
||||
$this->resetAfterTest();
|
||||
$setting = new admin_settings_aws_region('test_aws_region',
|
||||
'Test visible name', 'Test description', 'Test default setting');
|
||||
$html = $setting->output_html('');
|
||||
$this->assertTrue(str_contains($html, 'Test visible name'));
|
||||
$this->assertTrue(str_contains($html, 'Test description'));
|
||||
$this->assertTrue(str_contains($html, 'Default: Test default setting'));
|
||||
$this->assertTrue(str_contains($html,
|
||||
'<input type="text" list="s__test_aws_region" name="s__test_aws_region" value=""'));
|
||||
$this->assertTrue(str_contains($html, '<datalist id="s__test_aws_region">'));
|
||||
$this->assertTrue(str_contains($html, '<option value="'));
|
||||
}
|
||||
}
|
61
admin/tool/mfa/factor/sms/tests/aws_helper_test.php
Normal file
61
admin/tool/mfa/factor/sms/tests/aws_helper_test.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* factor_sms unit tests.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \factor_sms\local\aws_helper
|
||||
*/
|
||||
|
||||
namespace factor_sms;
|
||||
|
||||
use factor_sms\local\aws_helper;
|
||||
|
||||
/**
|
||||
* Testcase for the AWS helper.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @covers \factor_sms\classes\local\aws_helper
|
||||
*/
|
||||
class aws_helper_test extends \advanced_testcase {
|
||||
|
||||
public function test_get_proxy_string():void {
|
||||
global $CFG;
|
||||
$this->resetAfterTest();
|
||||
// Confirm with no config an empty string is returned.
|
||||
$CFG->proxyhost = '';
|
||||
$this->assertEquals('', aws_helper::get_proxy_string());
|
||||
|
||||
// Now set some configs.
|
||||
$CFG->proxyhost = '127.0.0.1';
|
||||
$CFG->proxyuser = 'user';
|
||||
$CFG->proxypassword = 'password';
|
||||
$CFG->proxyport = '1337';
|
||||
$this->assertEquals('user:password@127.0.0.1:1337', aws_helper::get_proxy_string());
|
||||
|
||||
// Now change to SOCKS proxy.
|
||||
$CFG->proxytype = 'SOCKS5';
|
||||
$this->assertEquals('socks5://user:password@127.0.0.1:1337', aws_helper::get_proxy_string());
|
||||
}
|
||||
|
||||
}
|
55
admin/tool/mfa/factor/sms/tests/behat/behat_factor_sms.php
Normal file
55
admin/tool/mfa/factor/sms/tests/behat/behat_factor_sms.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Behat custom steps and configuration for factor_sms.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @category test
|
||||
* @copyright 2023 <raquel.ortega@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(__DIR__ . '/../../../../../../../lib/behat/behat_base.php');
|
||||
require_once(__DIR__ . '/../../../../../../../lib/behat/behat_field_manager.php');
|
||||
|
||||
/**
|
||||
* Behat custom steps and configuration for factor_sms.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @category test
|
||||
* @copyright 2023 <raquel.ortega@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_factor_sms extends behat_base {
|
||||
|
||||
/**
|
||||
* Sets the given field with a valid code created in tool_mfa_secrets table
|
||||
*
|
||||
* @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" with valid code$/
|
||||
*
|
||||
* @param string $field
|
||||
*/
|
||||
public function i_set_the_field_with_valid_code(string $field): void {
|
||||
global $DB, $USER;
|
||||
|
||||
$record = $DB->get_record('tool_mfa_secrets',
|
||||
['userid' => $USER->id, 'revoked' => '0']
|
||||
);
|
||||
$field = behat_field_manager::get_form_field_from_label($field, $this);
|
||||
$field->set_value($record->secret);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
@tool_admin_mfa
|
||||
Feature: Login user with sms authentication factor
|
||||
In order to login using SMS factor authentication
|
||||
As an user
|
||||
I need to be able to login
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And the following config values are set as admin:
|
||||
| enabled | 1 | tool_mfa |
|
||||
| lockout | 3 | tool_mfa |
|
||||
And the following config values are set as admin:
|
||||
| enabled | 1 | factor_sms |
|
||||
# Set up user SMS factor in user preferences.
|
||||
When I follow "Preferences" in the user menu
|
||||
And I click on "Multi-factor authentication preferences" "link"
|
||||
And I click on "Setup SMS" "button"
|
||||
And I set the field "Mobile number" to "+34649709233"
|
||||
And I press "Send code"
|
||||
And I set the field "Enter code" with valid code
|
||||
Then I press "Save"
|
||||
|
||||
Scenario: Revoke factor
|
||||
Given I click on "Revoke" "link"
|
||||
And I should see "Are you sure you want to revoke factor?"
|
||||
And I press "Revoke"
|
||||
And I should see "successfully revoked"
|
||||
When I log out
|
||||
And I log in as "admin"
|
||||
Then I should see "Unable to authenticate"
|
||||
|
||||
Scenario: Login user successfully with sms verification
|
||||
Given I log out
|
||||
And I log in as "admin"
|
||||
And I should see "2-step verification"
|
||||
And I should see "Enter code"
|
||||
When I set the field "Enter code" with valid code
|
||||
And I click on "Continue" "button"
|
||||
Then I am logged in as "admin"
|
||||
|
||||
Scenario: Wrong code number end of possible attempts
|
||||
Given I log out
|
||||
And I log in as "admin"
|
||||
And I should see "2-step verification"
|
||||
And I should see "Enter code"
|
||||
When I set the field "Enter code" to "555556"
|
||||
And I click on "Continue" "button"
|
||||
And I should see "Wrong code."
|
||||
And I should see "You have 2 attempts left."
|
||||
And I set the field "Enter code" to "555553"
|
||||
And I click on "Continue" "button"
|
||||
And I should see "Wrong code."
|
||||
And I should see "1 attempts left."
|
||||
And I set the field "Enter code" to "555553"
|
||||
And I click on "Continue" "button"
|
||||
Then I should see "Unable to authenticate"
|
@ -0,0 +1,49 @@
|
||||
@tool_admin_mfa
|
||||
Feature: Setup SMS factor in user preferences
|
||||
In order check the setup SMS factor verification
|
||||
As an admin
|
||||
I want to setup and enable the SMS factor for the current user
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And the following config values are set as admin:
|
||||
| enabled | 1 | tool_mfa |
|
||||
And the following config values are set as admin:
|
||||
| enabled | 1 | factor_sms |
|
||||
When I follow "Preferences" in the user menu
|
||||
And I click on "Multi-factor authentication preferences" "link"
|
||||
And I click on "Setup SMS" "button"
|
||||
|
||||
Scenario: Phone number setup form validation
|
||||
Given I set the field "Mobile number" to "++5555sss"
|
||||
And I press "Send code"
|
||||
And I should see "The phone number you provided is not in a valid format."
|
||||
And I set the field "Mobile number" to "0123456789"
|
||||
And I press "Send code"
|
||||
And I should see "The phone number you provided is not in a valid format."
|
||||
And I set the field "Mobile number" to "786-307-3615"
|
||||
And I press "Send code"
|
||||
And I should see "The phone number you provided is not in a valid format."
|
||||
When I set the field "Mobile number" to "649709233"
|
||||
And I press "Send code"
|
||||
Then I should see "The phone number you provided is not in a valid format."
|
||||
|
||||
Scenario: Edit phone number
|
||||
Given I set the field "Mobile number" to "+34649709233"
|
||||
And I press "Send code"
|
||||
And I click on "Edit phone number" "link"
|
||||
And I should see "Mobile number"
|
||||
When I set the field "Mobile number" to "+34649709232"
|
||||
And I press "Send code"
|
||||
Then I should see "Enter code"
|
||||
|
||||
Scenario: Code setup form validation
|
||||
Given I set the field "Mobile number" to "+34649709233"
|
||||
And I press "Send code"
|
||||
And I should see "Enter code"
|
||||
When I set the field "Enter code" to "555556"
|
||||
And I click on "Save" "button"
|
||||
And I should see "Wrong code. Try again"
|
||||
And I set the field "Enter code" to "ddddd5"
|
||||
And I click on "Save" "button"
|
||||
Then I should see "Wrong code. Try again"
|
166
admin/tool/mfa/factor/sms/tests/factor_test.php
Normal file
166
admin/tool/mfa/factor/sms/tests/factor_test.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace factor_sms;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for sms factor.
|
||||
*
|
||||
* @covers \factor_sms\factor
|
||||
* @package factor_sms
|
||||
* @copyright 2023 Raquel Ortega <raquel.ortega@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class factor_test extends \advanced_testcase {
|
||||
|
||||
/**
|
||||
* Data provider for test_format_number().
|
||||
*
|
||||
* @return array of different country codes and phone numbers.
|
||||
*/
|
||||
public function format_number_provider(): array {
|
||||
|
||||
return [
|
||||
'Phone number with local format' => [
|
||||
'phonenumber' => '0123456789',
|
||||
'expected' => '+34123456789',
|
||||
'countrycode' => '34',
|
||||
],
|
||||
'Phone number without international format' => [
|
||||
'phonenumber' => '123456789',
|
||||
'expected' => '+34123456789',
|
||||
'countrycode' => '34',
|
||||
],
|
||||
'Phone number with international format' => [
|
||||
'phonenumber' => '+39123456789',
|
||||
'expected' => '+39123456789',
|
||||
],
|
||||
'Phone number with spaces using international format' => [
|
||||
'phonenumber' => '+34 123 456 789',
|
||||
'expected' => '+34123456789',
|
||||
],
|
||||
'Phone number with spaces using local format with country code' => [
|
||||
'phonenumber' => '0 123 456 789',
|
||||
'expected' => '+34123456789',
|
||||
'countrycode' => '34',
|
||||
],
|
||||
'Phone number with spaces using local format without country code' => [
|
||||
'phonenumber' => '0 123 456 789',
|
||||
'expected' => '123456789',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test format number with different phones and different country codes
|
||||
* @covers \factor_sms\helper::format_number
|
||||
* @dataProvider format_number_provider
|
||||
*
|
||||
* @param string $phonenumber Phone number.
|
||||
* @param string $expected Expected value.
|
||||
* @param string|null $countrycode Country code.
|
||||
*/
|
||||
public function test_format_number(string $phonenumber, string $expected, ?string $countrycode = null): void {
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
set_config('countrycode', $countrycode, 'factor_sms');
|
||||
|
||||
$this->assertEquals($expected, \factor_sms\helper::format_number($phonenumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_is_valid__phonenumber().
|
||||
*
|
||||
* @return array with different phone numebr tests
|
||||
*/
|
||||
public function is_valid_phonenumber_provider(): array {
|
||||
return [
|
||||
['+919367788755', true],
|
||||
['8989829304', false],
|
||||
['+16308520397', true],
|
||||
['786-307-3615', false],
|
||||
['+14155552671', true],
|
||||
['+551155256325', true],
|
||||
['649709233', false],
|
||||
['+34649709233', true],
|
||||
['+aaasss', false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is valid phone number in E.164 format (https://en.wikipedia.org/wiki/E.164)
|
||||
* @covers \factor_sms\helper::is_valid_phonenumber
|
||||
* @dataProvider is_valid_phonenumber_provider
|
||||
*
|
||||
* @param string $phonenumber
|
||||
* @param bool $valid True if the given phone number is valid, false if is invalid
|
||||
*/
|
||||
public function test_is_valid_phonenumber(string $phonenumber, bool $valid): void {
|
||||
$this->resetAfterTest(true);
|
||||
if ($valid) {
|
||||
$this->assertTrue(\factor_sms\helper::is_valid_phonenumber($phonenumber));
|
||||
} else {
|
||||
$this->assertFalse(\factor_sms\helper::is_valid_phonenumber($phonenumber));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set up user factor and verification code with a random phone number
|
||||
* @covers ::setup_user_factor
|
||||
* @covers ::check_verification_code
|
||||
* @covers ::revoke_user_factor
|
||||
*/
|
||||
public function test_check_verification_code(): void {
|
||||
global $SESSION;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Create and login a user and set up the phone number.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
// Generate a fake phone number and save it in session.
|
||||
$phonenumber = '+34' . (string)random_int(100000000, 999999999);
|
||||
$SESSION->tool_mfa_sms_number = $phonenumber;
|
||||
|
||||
$smsfactor = \tool_mfa\plugininfo\factor::get_factor('sms');
|
||||
$rc = new \ReflectionClass($smsfactor::class);
|
||||
|
||||
$smsdata = [];
|
||||
$factorinstance = $smsfactor->setup_user_factor((object) $smsdata);
|
||||
|
||||
// Check if user factor was created successful.
|
||||
$this->assertNotEmpty($factorinstance);
|
||||
$this->assertEquals(1, count($smsfactor->get_active_user_factors($user)));
|
||||
|
||||
// Create the secret code.
|
||||
$secretmanager = new \tool_mfa\local\secret_manager('sms');
|
||||
$secretcode = $secretmanager->create_secret(1800, true);
|
||||
|
||||
// Check verification code.
|
||||
$rcm = $rc->getMethod('check_verification_code');
|
||||
$rcm->setAccessible(true);
|
||||
$this->assertTrue($rcm->invoke($smsfactor, $secretcode));
|
||||
|
||||
// Test that calling the revoke on the generic type revokes all.
|
||||
$smsfactor->revoke_user_factor($factorinstance->id);
|
||||
$this->assertEquals(0, count($smsfactor->get_active_user_factors($user)));
|
||||
|
||||
unset($SESSION->tool_mfa_sms_number);
|
||||
}
|
||||
}
|
32
admin/tool/mfa/factor/sms/version.php
Normal file
32
admin/tool/mfa/factor/sms/version.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin version and other meta-data are defined here.
|
||||
*
|
||||
* @package factor_sms
|
||||
* @subpackage tool_mfa
|
||||
* @author Peter Burnett <peterburnett@catalyst-au.net>
|
||||
* @copyright Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2023080300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2023042400.00; // Requires this Moodle version.
|
||||
$plugin->component = 'factor_sms'; // Full name of the plugin (used for diagnostics).
|
||||
$plugin->maturity = MATURITY_STABLE;
|
@ -341,7 +341,7 @@ class factor extends object_factor_base {
|
||||
* TOTP Factor implementation.
|
||||
*
|
||||
* @param stdClass $data
|
||||
* @return stdClass the factor record, or null.
|
||||
* @return stdClass|null the factor record, or null.
|
||||
*/
|
||||
public function setup_user_factor(stdClass $data): stdClass|null {
|
||||
global $DB, $USER;
|
||||
|
@ -242,7 +242,7 @@ class factor extends object_factor_base {
|
||||
* WebAuthn Factor implementation.
|
||||
*
|
||||
* @param \MoodleQuickForm $mform
|
||||
* @return object $mform
|
||||
* @return \MoodleQuickForm $mform
|
||||
*/
|
||||
public function setup_factor_form_definition(\MoodleQuickForm $mform): \MoodleQuickForm {
|
||||
global $PAGE, $USER, $SESSION;
|
||||
|
@ -41,6 +41,7 @@ $string['error:actionnotfound'] = 'Action \'{$a}\' not supported';
|
||||
$string['error:directaccess'] = 'This page shouldn\'t be accessed directly';
|
||||
$string['error:factornotenabled'] = 'Multi-factor authentication factor \'{$a}\' not enabled';
|
||||
$string['error:factornotfound'] = 'Multi-factor authentication factor \'{$a}\' not found';
|
||||
$string['error:isguestuser'] = 'Guests are not allowed here.';
|
||||
$string['error:notenoughfactors'] = 'Unable to authenticate';
|
||||
$string['error:reauth'] = 'We couldn\'t confirm your identity sufficiently to meet the site authentication security policy.<br>This may be due to: <br> 1) Steps being locked - please wait a few minutes and try again.
|
||||
<br> 2) Steps being failed - please double check the details for each step. <br> 3) Steps were skipped - please reload this page or try logging in again.';
|
||||
|
@ -262,4 +262,29 @@ class secret_manager_test extends \advanced_testcase {
|
||||
$reflectedsessionid->setValue($secman, 'diffsession');
|
||||
$this->assertFalse($reflectedmethod->invoke($secman, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests with cleanup temporal secrets
|
||||
*
|
||||
* @covers ::cleanup_temp_secrets
|
||||
*/
|
||||
public function test_cleanup_temp_secrets(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$secman = new \tool_mfa\local\secret_manager('mock');
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
// Create secrets.
|
||||
$secman->create_secret(1800, true);
|
||||
$secman->create_secret(1800, true);
|
||||
|
||||
// Cleanup current user secrets.
|
||||
$secman->cleanup_temp_secrets();
|
||||
|
||||
// Check there are no secrets of the current user.
|
||||
$records = $DB->get_records('tool_mfa_secrets', ['userid' => $user->id]);
|
||||
$this->assertEmpty($records);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ require_once(__DIR__ . '/../../../config.php');
|
||||
|
||||
require_login(null, false);
|
||||
if (isguestuser()) {
|
||||
throw new require_login_exception('Guests are not allowed here.');
|
||||
throw new require_login_exception('error:isguestuser', 'tool_mfa');
|
||||
}
|
||||
|
||||
$action = optional_param('action', '', PARAM_TEXT);
|
||||
|
141
lib/aws-sdk/LICENSE
Normal file
141
lib/aws-sdk/LICENSE
Normal file
@ -0,0 +1,141 @@
|
||||
# Apache License
|
||||
Version 2.0, January 2004
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
## 1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1
|
||||
through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the
|
||||
License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled
|
||||
by, or are under common control with that entity. For the purposes of this definition, "control" means
|
||||
(i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract
|
||||
or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial
|
||||
ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software
|
||||
source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form,
|
||||
including but not limited to compiled object code, generated documentation, and conversions to other media
|
||||
types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License,
|
||||
as indicated by a copyright notice that is included in or attached to the work (an example is provided in the
|
||||
Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from)
|
||||
the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent,
|
||||
as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not
|
||||
include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work
|
||||
and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any
|
||||
modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to
|
||||
Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to
|
||||
submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of
|
||||
electronic, verbal, or written communication sent to the Licensor or its representatives, including but not
|
||||
limited to communication on electronic mailing lists, source code control systems, and issue tracking systems
|
||||
that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
|
||||
received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
## 2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
|
||||
Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
## 3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||
license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such
|
||||
license applies only to those patent claims licensable by such Contributor that are necessarily infringed by
|
||||
their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such
|
||||
Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim
|
||||
or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work
|
||||
constitutes direct or contributory patent infringement, then any patent licenses granted to You under this
|
||||
License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
## 4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
2. You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent,
|
||||
trademark, and attribution notices from the Source form of the Work, excluding those notices that do
|
||||
not pertain to any part of the Derivative Works; and
|
||||
|
||||
4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that
|
||||
You distribute must include a readable copy of the attribution notices contained within such NOTICE
|
||||
file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed as part of the Derivative Works; within
|
||||
the Source form or documentation, if provided along with the Derivative Works; or, within a display
|
||||
generated by the Derivative Works, if and wherever such third-party notices normally appear. The
|
||||
contents of the NOTICE file are for informational purposes only and do not modify the License. You may
|
||||
add Your own attribution notices within Derivative Works that You distribute, alongside or as an
|
||||
addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be
|
||||
construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license
|
||||
terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative
|
||||
Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the
|
||||
conditions stated in this License.
|
||||
|
||||
## 5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by
|
||||
You to the Licensor shall be under the terms and conditions of this License, without any additional terms or
|
||||
conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate
|
||||
license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
## 6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks, service marks, or product names of
|
||||
the Licensor, except as required for reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
## 7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor
|
||||
provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
## 8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless
|
||||
required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any
|
||||
Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential
|
||||
damages of any character arising as a result of this License or out of the use or inability to use the Work
|
||||
(including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has been advised of the possibility
|
||||
of such damages.
|
||||
|
||||
## 9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||
acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole
|
||||
responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold
|
||||
each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
17
lib/aws-sdk/NOTICE
Normal file
17
lib/aws-sdk/NOTICE
Normal file
@ -0,0 +1,17 @@
|
||||
# AWS SDK for PHP
|
||||
|
||||
<http://aws.amazon.com/php>
|
||||
|
||||
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License").
|
||||
You may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
211
lib/aws-sdk/README.md
Normal file
211
lib/aws-sdk/README.md
Normal file
@ -0,0 +1,211 @@
|
||||
# AWS SDK for PHP - Version 3
|
||||
|
||||
[](https://packagist.org/packages/aws/aws-sdk-php)
|
||||
[](http://aws.amazon.com/apache-2-0/)
|
||||
[](https://gitter.im/aws/aws-sdk-php?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://codecov.io/gh/aws/aws-sdk-php)
|
||||
|
||||
The **AWS SDK for PHP** makes it easy for developers to access [Amazon Web
|
||||
Services][aws] in their PHP code, and build robust applications and software
|
||||
using services like Amazon S3, Amazon DynamoDB, Amazon Glacier, etc. You can
|
||||
get started in minutes by [installing the SDK through Composer][docs-installation]
|
||||
or by downloading a single zip or phar file from our [latest release][latest-release].
|
||||
|
||||
Jump To:
|
||||
* [Getting Started](#Getting-Started)
|
||||
* [Quick Examples](#Quick-Examples)
|
||||
* [Getting Help](#Getting-Help)
|
||||
* [Features](#Features)
|
||||
* [Contributing](#Contributing)
|
||||
* [More Resources](#Resources)
|
||||
* [Related AWS Projects](#Related-AWS-Projects)
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. **Sign up for AWS** – Before you begin, you need to
|
||||
sign up for an AWS account and retrieve your [AWS credentials][docs-signup].
|
||||
2. **Minimum requirements** – To run the SDK, your system will need to meet the
|
||||
[minimum requirements][docs-requirements], including having **PHP >= 5.5**.
|
||||
We highly recommend having it compiled with the cURL extension and cURL
|
||||
7.16.2+ compiled with a TLS backend (e.g., NSS or OpenSSL).
|
||||
3. **Install the SDK** – Using [Composer] is the recommended way to install the
|
||||
AWS SDK for PHP. The SDK is available via [Packagist] under the
|
||||
[`aws/aws-sdk-php`][install-packagist] package. If Composer is installed globally on your system, you can run the following in the base directory of your project to add the SDK as a dependency:
|
||||
```
|
||||
composer require aws/aws-sdk-php
|
||||
```
|
||||
Please see the
|
||||
[Installation section of the User Guide][docs-installation] for more
|
||||
detailed information about installing the SDK through Composer and other
|
||||
means.
|
||||
4. **Using the SDK** – The best way to become familiar with how to use the SDK
|
||||
is to read the [User Guide][docs-guide]. The
|
||||
[Getting Started Guide][docs-quickstart] will help you become familiar with
|
||||
the basic concepts.
|
||||
5. **Beta: Removing unused services** — To date, there are over 300 AWS services available for use with this SDK.
|
||||
You will likely not need them all. If you use Composer and would like to learn more about this feature,
|
||||
please read the [linked documentation][docs-script-composer].
|
||||
|
||||
|
||||
## Quick Examples
|
||||
|
||||
### Create an Amazon S3 client
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Require the Composer autoloader.
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Aws\S3\S3Client;
|
||||
|
||||
// Instantiate an Amazon S3 client.
|
||||
$s3 = new S3Client([
|
||||
'version' => 'latest',
|
||||
'region' => 'us-west-2'
|
||||
]);
|
||||
```
|
||||
|
||||
### Upload a file to Amazon S3
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Upload a publicly accessible file. The file size and type are determined by the SDK.
|
||||
try {
|
||||
$s3->putObject([
|
||||
'Bucket' => 'my-bucket',
|
||||
'Key' => 'my-object',
|
||||
'Body' => fopen('/path/to/file', 'r'),
|
||||
'ACL' => 'public-read',
|
||||
]);
|
||||
} catch (Aws\S3\Exception\S3Exception $e) {
|
||||
echo "There was an error uploading the file.\n";
|
||||
}
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
Please use these community resources for getting help. We use the GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them.
|
||||
|
||||
* Ask a question on [StackOverflow](https://stackoverflow.com/) and tag it with [`aws-php-sdk`](http://stackoverflow.com/questions/tagged/aws-php-sdk)
|
||||
* Come join the AWS SDK for PHP [gitter](https://gitter.im/aws/aws-sdk-php)
|
||||
* Open a support ticket with [AWS Support](https://console.aws.amazon.com/support/home/)
|
||||
* If it turns out that you may have found a bug, please [open an issue](https://github.com/aws/aws-sdk-php/issues/new/choose)
|
||||
|
||||
This SDK implements AWS service APIs. For general issues regarding the AWS services and their limitations, you may also take a look at the [Amazon Web Services Discussion Forums](https://forums.aws.amazon.com/).
|
||||
|
||||
|
||||
## Maintenance and support for SDK major versions
|
||||
|
||||
For information about maintenance and support for SDK major versions and their underlying dependencies, see the following in the [AWS SDKs and Tools Shared Configuration and Credentials Reference Guide](https://docs.aws.amazon.com/credref/latest/refdocs/overview.html):
|
||||
|
||||
* [AWS SDKs and Tools Maintenance Policy](https://docs.aws.amazon.com/credref/latest/refdocs/maint-policy.html)
|
||||
* [AWS SDKs and Tools Version Support Matrix](https://docs.aws.amazon.com/credref/latest/refdocs/version-support-matrix.html)
|
||||
|
||||
|
||||
### Opening Issues
|
||||
|
||||
If you encounter a bug with `aws-sdk-php` we would like to hear about it. Search the existing issues and try to make sure your problem doesn’t already exist before opening a new issue. It’s helpful if you include the version of `aws-sdk-php`, PHP version and OS you’re using. Please include a stack trace and a simple workflow to reproduce the case when appropriate, too.
|
||||
|
||||
The GitHub issues are intended for bug reports and feature requests. For help and questions with using `aws-sdk-php` please make use of the resources listed in the Getting Help section. There are limited resources available for handling issues and by keeping the list of open issues lean we can respond in a timely manner.
|
||||
|
||||
## Features
|
||||
|
||||
* Provides easy-to-use HTTP clients for all supported AWS
|
||||
[services][docs-services], [regions][docs-rande], and authentication
|
||||
protocols.
|
||||
* Is built on [Guzzle][guzzle-docs], and utilizes many of its features,
|
||||
including persistent connections, asynchronous requests, middlewares, etc.
|
||||
* Provides convenience features including easy result pagination via
|
||||
[Paginators][docs-paginators], [Waiters][docs-waiters], and simple
|
||||
[Result objects][docs-results].
|
||||
* Provides a [multipart uploader tool][docs-s3-multipart] for Amazon S3 and
|
||||
Amazon Glacier that can be paused and resumed.
|
||||
* Provides an [Amazon S3 Stream Wrapper][docs-streamwrapper], so that you can
|
||||
use PHP's native file handling functions to interact with your S3 buckets and
|
||||
objects like a local filesystem.
|
||||
* Provides an [Amazon S3 Encryption Client][docs-s3-encryption] for creating and interacting with encrypted objects in your S3 buckets.
|
||||
* Provides the [Amazon DynamoDB Session Handler][docs-ddbsh] for easily scaling
|
||||
sessions on a fast, NoSQL database.
|
||||
* Automatically uses [IAM Instance Profile Credentials][aws-iam-credentials] on
|
||||
configured Amazon EC2 instances.
|
||||
|
||||
## Contributing
|
||||
|
||||
We work hard to provide a high-quality and useful SDK for our AWS services, and we greatly value feedback and contributions from our community. Please review our [contributing guidelines](./CONTRIBUTING.md) before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution.
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
* [User Guide][docs-guide] – For both getting started and in-depth SDK usage information
|
||||
* [API Docs][docs-api] – For details about operations, parameters, and responses
|
||||
* [Blog][sdk-blog] – Tips & tricks, articles, and announcements
|
||||
* [Sample Project][sdk-sample] - A quick, sample project to help get you started
|
||||
* [Forum][sdk-forum] – Ask questions, get help, and give feedback
|
||||
* [Issues][sdk-issues] – Report issues, submit pull requests, and get involved
|
||||
(see [Apache 2.0 License][sdk-license])
|
||||
|
||||
## Related AWS Projects
|
||||
|
||||
* [AWS Service Provider for Laravel][mod-laravel]
|
||||
* [AWS SDK ZF2 Module][mod-zf2]
|
||||
* [AWS Service Provider for Silex][mod-silex]
|
||||
* [AWS SDK Bundle for Symfony][mod-symfony]
|
||||
* [Amazon SNS Message Validator for PHP][sns-validator] - SNS validator without requiring SDK
|
||||
* [Guzzle Version 7][guzzle-docs] – PHP HTTP client and framework
|
||||
* For Version 2 of the SDK (deprecated):
|
||||
* [User Guide][docs-guide-v2]
|
||||
* [API Docs][docs-api-v2]
|
||||
* [Serverless LAMP stack guide][serverless-LAMP-stack-guide] - A guide to building and deploying a serverless PHP application
|
||||
* Other [AWS SDKs & Tools][aws-tools] (e.g., js, cli, ruby, python, java, etc.)
|
||||
|
||||
[sdk-website]: http://aws.amazon.com/sdkforphp
|
||||
[sdk-forum]: https://forums.aws.amazon.com/forum.jspa?forumID=80
|
||||
[sdk-issues]: https://github.com/aws/aws-sdk-php/issues
|
||||
[sdk-license]: http://aws.amazon.com/apache2.0/
|
||||
[sdk-blog]: https://aws.amazon.com/blogs/developer/category/php/
|
||||
[sdk-sample]: http://aws.amazon.com/developers/getting-started/php
|
||||
|
||||
[install-packagist]: https://packagist.org/packages/aws/aws-sdk-php
|
||||
[latest-release]: https://github.com/aws/aws-sdk-php/releases
|
||||
|
||||
[docs-api]: http://docs.aws.amazon.com/aws-sdk-php/v3/api/index.html
|
||||
[docs-guide]: http://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/welcome.html
|
||||
[docs-api-v2]: http://docs.aws.amazon.com/aws-sdk-php/v2/api/index.html
|
||||
[docs-guide-v2]: http://docs.aws.amazon.com/aws-sdk-php/v2/guide/index.html
|
||||
[docs-contribution]: https://github.com/aws/aws-sdk-php/blob/master/CONTRIBUTING.md
|
||||
[docs-migration]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_migration.html
|
||||
[docs-signup]: https://aws.amazon.com/premiumsupport/knowledge-center/create-access-key/
|
||||
[docs-requirements]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_requirements.html
|
||||
[docs-installation]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_installation.html
|
||||
[docs-quickstart]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/welcome.html#getting-started
|
||||
[docs-paginators]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_paginators.html
|
||||
[docs-waiters]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_waiters.html
|
||||
[docs-results]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_basic-usage.html#result-objects
|
||||
[docs-exceptions]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_basic-usage.html#handling-errors
|
||||
[docs-wire-logging]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/faq.html#how-can-i-see-what-data-is-sent-over-the-wire
|
||||
[docs-ddbsh]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/service_dynamodb-session-handler.html
|
||||
[docs-services]: https://aws.amazon.com/products/
|
||||
[docs-rande]: http://docs.aws.amazon.com/general/latest/gr/rande.html
|
||||
[docs-streamwrapper]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html
|
||||
[docs-s3-transfer]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-transfer.html
|
||||
[docs-s3-multipart]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-multipart-upload.html
|
||||
[docs-s3-encryption]: https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-encryption-client.html
|
||||
[docs-script-composer]: https://github.com/aws/aws-sdk-php/tree/master/src/Script/Composer
|
||||
|
||||
[aws]: http://aws.amazon.com
|
||||
[aws-iam-credentials]: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UsingIAM.html#UsingIAMrolesWithAmazonEC2Instances
|
||||
[aws-tools]: http://aws.amazon.com/tools
|
||||
[guzzle-docs]: http://guzzlephp.org
|
||||
[composer]: http://getcomposer.org
|
||||
[packagist]: http://packagist.org
|
||||
[psr-7]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-7-http-message.md
|
||||
[psr-4]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
|
||||
[psr-1]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
|
||||
[psr-2]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
|
||||
|
||||
[mod-laravel]: https://github.com/aws/aws-sdk-php-laravel
|
||||
[mod-zf2]: https://github.com/aws/aws-sdk-php-zf2
|
||||
[mod-silex]: https://github.com/aws/aws-sdk-php-silex
|
||||
[mod-symfony]: https://github.com/aws/aws-sdk-php-symfony
|
||||
[sns-validator]: https://github.com/aws/aws-php-sns-message-validator
|
||||
[serverless-LAMP-stack-guide]: https://github.com/aws-samples/php-examples-for-aws-lambda
|
6
lib/aws-sdk/readme_moodle.txt
Normal file
6
lib/aws-sdk/readme_moodle.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Instructions to import/update aws-sdk-php library into Moodle:
|
||||
|
||||
Update aws-sdk-php library
|
||||
1. Download the latest aws-sdk-php library package from https://github.com/aws/aws-sdk-php
|
||||
2. Copy the src directory to lib/aws-sdk/src folder
|
||||
3. Copy the associated files LICENCE, README.md etc. to aws-sdk directory
|
55
lib/aws-sdk/src/ACMPCA/ACMPCAClient.php
Normal file
55
lib/aws-sdk/src/ACMPCA/ACMPCAClient.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
namespace Aws\ACMPCA;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS Certificate Manager Private Certificate Authority** service.
|
||||
* @method \Aws\Result createCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createCertificateAuthorityAsync(array $args = [])
|
||||
* @method \Aws\Result createCertificateAuthorityAuditReport(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createCertificateAuthorityAuditReportAsync(array $args = [])
|
||||
* @method \Aws\Result createPermission(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createPermissionAsync(array $args = [])
|
||||
* @method \Aws\Result deleteCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteCertificateAuthorityAsync(array $args = [])
|
||||
* @method \Aws\Result deletePermission(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deletePermissionAsync(array $args = [])
|
||||
* @method \Aws\Result deletePolicy(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deletePolicyAsync(array $args = [])
|
||||
* @method \Aws\Result describeCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise describeCertificateAuthorityAsync(array $args = [])
|
||||
* @method \Aws\Result describeCertificateAuthorityAuditReport(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise describeCertificateAuthorityAuditReportAsync(array $args = [])
|
||||
* @method \Aws\Result getCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result getCertificateAuthorityCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getCertificateAuthorityCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result getCertificateAuthorityCsr(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getCertificateAuthorityCsrAsync(array $args = [])
|
||||
* @method \Aws\Result getPolicy(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getPolicyAsync(array $args = [])
|
||||
* @method \Aws\Result importCertificateAuthorityCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importCertificateAuthorityCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result issueCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise issueCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result listCertificateAuthorities(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listCertificateAuthoritiesAsync(array $args = [])
|
||||
* @method \Aws\Result listPermissions(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listPermissionsAsync(array $args = [])
|
||||
* @method \Aws\Result listTags(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listTagsAsync(array $args = [])
|
||||
* @method \Aws\Result putPolicy(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putPolicyAsync(array $args = [])
|
||||
* @method \Aws\Result restoreCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise restoreCertificateAuthorityAsync(array $args = [])
|
||||
* @method \Aws\Result revokeCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise revokeCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result tagCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagCertificateAuthorityAsync(array $args = [])
|
||||
* @method \Aws\Result untagCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise untagCertificateAuthorityAsync(array $args = [])
|
||||
* @method \Aws\Result updateCertificateAuthority(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateCertificateAuthorityAsync(array $args = [])
|
||||
*/
|
||||
class ACMPCAClient extends AwsClient {}
|
9
lib/aws-sdk/src/ACMPCA/Exception/ACMPCAException.php
Normal file
9
lib/aws-sdk/src/ACMPCA/Exception/ACMPCAException.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\ACMPCA\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS Certificate Manager Private Certificate Authority** service.
|
||||
*/
|
||||
class ACMPCAException extends AwsException {}
|
21
lib/aws-sdk/src/ARCZonalShift/ARCZonalShiftClient.php
Normal file
21
lib/aws-sdk/src/ARCZonalShift/ARCZonalShiftClient.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Aws\ARCZonalShift;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS ARC - Zonal Shift** service.
|
||||
* @method \Aws\Result cancelZonalShift(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise cancelZonalShiftAsync(array $args = [])
|
||||
* @method \Aws\Result getManagedResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getManagedResourceAsync(array $args = [])
|
||||
* @method \Aws\Result listManagedResources(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listManagedResourcesAsync(array $args = [])
|
||||
* @method \Aws\Result listZonalShifts(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listZonalShiftsAsync(array $args = [])
|
||||
* @method \Aws\Result startZonalShift(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startZonalShiftAsync(array $args = [])
|
||||
* @method \Aws\Result updateZonalShift(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateZonalShiftAsync(array $args = [])
|
||||
*/
|
||||
class ARCZonalShiftClient extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\ARCZonalShift\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS ARC - Zonal Shift** service.
|
||||
*/
|
||||
class ARCZonalShiftException extends AwsException {}
|
157
lib/aws-sdk/src/AbstractConfigurationProvider.php
Normal file
157
lib/aws-sdk/src/AbstractConfigurationProvider.php
Normal file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
namespace Aws;
|
||||
|
||||
use GuzzleHttp\Promise;
|
||||
|
||||
/**
|
||||
* A configuration provider is a function that returns a promise that is
|
||||
* fulfilled with a configuration object. This class provides base functionality
|
||||
* usable by specific configuration provider implementations
|
||||
*/
|
||||
abstract class AbstractConfigurationProvider
|
||||
{
|
||||
const ENV_PROFILE = 'AWS_PROFILE';
|
||||
const ENV_CONFIG_FILE = 'AWS_CONFIG_FILE';
|
||||
|
||||
public static $cacheKey;
|
||||
|
||||
protected static $interfaceClass;
|
||||
protected static $exceptionClass;
|
||||
|
||||
/**
|
||||
* Wraps a config provider and saves provided configuration in an
|
||||
* instance of Aws\CacheInterface. Forwards calls when no config found
|
||||
* in cache and updates cache with the results.
|
||||
*
|
||||
* @param callable $provider Configuration provider function to wrap
|
||||
* @param CacheInterface $cache Cache to store configuration
|
||||
* @param string|null $cacheKey (optional) Cache key to use
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function cache(
|
||||
callable $provider,
|
||||
CacheInterface $cache,
|
||||
$cacheKey = null
|
||||
) {
|
||||
$cacheKey = $cacheKey ?: static::$cacheKey;
|
||||
|
||||
return function () use ($provider, $cache, $cacheKey) {
|
||||
$found = $cache->get($cacheKey);
|
||||
if ($found instanceof static::$interfaceClass) {
|
||||
return Promise\Create::promiseFor($found);
|
||||
}
|
||||
|
||||
return $provider()
|
||||
->then(function ($config) use (
|
||||
$cache,
|
||||
$cacheKey
|
||||
) {
|
||||
$cache->set($cacheKey, $config);
|
||||
return $config;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an aggregate configuration provider that invokes the provided
|
||||
* variadic providers one after the other until a provider returns
|
||||
* configuration.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function chain()
|
||||
{
|
||||
$links = func_get_args();
|
||||
if (empty($links)) {
|
||||
throw new \InvalidArgumentException('No providers in chain');
|
||||
}
|
||||
|
||||
return function () use ($links) {
|
||||
/** @var callable $parent */
|
||||
$parent = array_shift($links);
|
||||
$promise = $parent();
|
||||
while ($next = array_shift($links)) {
|
||||
$promise = $promise->otherwise($next);
|
||||
}
|
||||
return $promise;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the environment's HOME directory if available.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected static function getHomeDir()
|
||||
{
|
||||
// On Linux/Unix-like systems, use the HOME environment variable
|
||||
if ($homeDir = getenv('HOME')) {
|
||||
return $homeDir;
|
||||
}
|
||||
|
||||
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
|
||||
$homeDrive = getenv('HOMEDRIVE');
|
||||
$homePath = getenv('HOMEPATH');
|
||||
|
||||
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets default config file location from environment, falling back to aws
|
||||
* default location
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getDefaultConfigFilename()
|
||||
{
|
||||
if ($filename = getenv(self::ENV_CONFIG_FILE)) {
|
||||
return $filename;
|
||||
}
|
||||
return self::getHomeDir() . '/.aws/config';
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a config provider and caches previously provided configuration.
|
||||
*
|
||||
* @param callable $provider Config provider function to wrap.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function memoize(callable $provider)
|
||||
{
|
||||
return function () use ($provider) {
|
||||
static $result;
|
||||
static $isConstant;
|
||||
|
||||
// Constant config will be returned constantly.
|
||||
if ($isConstant) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Create the initial promise that will be used as the cached value
|
||||
if (null === $result) {
|
||||
$result = $provider();
|
||||
}
|
||||
|
||||
// Return config and set flag that provider is already set
|
||||
return $result
|
||||
->then(function ($config) use (&$isConstant) {
|
||||
$isConstant = true;
|
||||
return $config;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Reject promise with standardized exception.
|
||||
*
|
||||
* @param $msg
|
||||
* @return Promise\RejectedPromise
|
||||
*/
|
||||
protected static function reject($msg)
|
||||
{
|
||||
$exceptionClass = static::$exceptionClass;
|
||||
return new Promise\RejectedPromise(new $exceptionClass($msg));
|
||||
}
|
||||
}
|
65
lib/aws-sdk/src/AccessAnalyzer/AccessAnalyzerClient.php
Normal file
65
lib/aws-sdk/src/AccessAnalyzer/AccessAnalyzerClient.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
namespace Aws\AccessAnalyzer;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **Access Analyzer** service.
|
||||
* @method \Aws\Result applyArchiveRule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise applyArchiveRuleAsync(array $args = [])
|
||||
* @method \Aws\Result cancelPolicyGeneration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise cancelPolicyGenerationAsync(array $args = [])
|
||||
* @method \Aws\Result createAccessPreview(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createAccessPreviewAsync(array $args = [])
|
||||
* @method \Aws\Result createAnalyzer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createAnalyzerAsync(array $args = [])
|
||||
* @method \Aws\Result createArchiveRule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createArchiveRuleAsync(array $args = [])
|
||||
* @method \Aws\Result deleteAnalyzer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAnalyzerAsync(array $args = [])
|
||||
* @method \Aws\Result deleteArchiveRule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteArchiveRuleAsync(array $args = [])
|
||||
* @method \Aws\Result getAccessPreview(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAccessPreviewAsync(array $args = [])
|
||||
* @method \Aws\Result getAnalyzedResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAnalyzedResourceAsync(array $args = [])
|
||||
* @method \Aws\Result getAnalyzer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAnalyzerAsync(array $args = [])
|
||||
* @method \Aws\Result getArchiveRule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getArchiveRuleAsync(array $args = [])
|
||||
* @method \Aws\Result getFinding(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getFindingAsync(array $args = [])
|
||||
* @method \Aws\Result getGeneratedPolicy(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getGeneratedPolicyAsync(array $args = [])
|
||||
* @method \Aws\Result listAccessPreviewFindings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listAccessPreviewFindingsAsync(array $args = [])
|
||||
* @method \Aws\Result listAccessPreviews(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listAccessPreviewsAsync(array $args = [])
|
||||
* @method \Aws\Result listAnalyzedResources(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listAnalyzedResourcesAsync(array $args = [])
|
||||
* @method \Aws\Result listAnalyzers(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listAnalyzersAsync(array $args = [])
|
||||
* @method \Aws\Result listArchiveRules(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listArchiveRulesAsync(array $args = [])
|
||||
* @method \Aws\Result listFindings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listFindingsAsync(array $args = [])
|
||||
* @method \Aws\Result listPolicyGenerations(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listPolicyGenerationsAsync(array $args = [])
|
||||
* @method \Aws\Result listTagsForResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
|
||||
* @method \Aws\Result startPolicyGeneration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startPolicyGenerationAsync(array $args = [])
|
||||
* @method \Aws\Result startResourceScan(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startResourceScanAsync(array $args = [])
|
||||
* @method \Aws\Result tagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result untagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result updateArchiveRule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateArchiveRuleAsync(array $args = [])
|
||||
* @method \Aws\Result updateFindings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateFindingsAsync(array $args = [])
|
||||
* @method \Aws\Result validatePolicy(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise validatePolicyAsync(array $args = [])
|
||||
*/
|
||||
class AccessAnalyzerClient extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\AccessAnalyzer\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **Access Analyzer** service.
|
||||
*/
|
||||
class AccessAnalyzerException extends AwsException {}
|
27
lib/aws-sdk/src/Account/AccountClient.php
Normal file
27
lib/aws-sdk/src/Account/AccountClient.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Aws\Account;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS Account** service.
|
||||
* @method \Aws\Result deleteAlternateContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAlternateContactAsync(array $args = [])
|
||||
* @method \Aws\Result disableRegion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise disableRegionAsync(array $args = [])
|
||||
* @method \Aws\Result enableRegion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise enableRegionAsync(array $args = [])
|
||||
* @method \Aws\Result getAlternateContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAlternateContactAsync(array $args = [])
|
||||
* @method \Aws\Result getContactInformation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getContactInformationAsync(array $args = [])
|
||||
* @method \Aws\Result getRegionOptStatus(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRegionOptStatusAsync(array $args = [])
|
||||
* @method \Aws\Result listRegions(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listRegionsAsync(array $args = [])
|
||||
* @method \Aws\Result putAlternateContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putAlternateContactAsync(array $args = [])
|
||||
* @method \Aws\Result putContactInformation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putContactInformationAsync(array $args = [])
|
||||
*/
|
||||
class AccountClient extends AwsClient {}
|
9
lib/aws-sdk/src/Account/Exception/AccountException.php
Normal file
9
lib/aws-sdk/src/Account/Exception/AccountException.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\Account\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS Account** service.
|
||||
*/
|
||||
class AccountException extends AwsException {}
|
40
lib/aws-sdk/src/Acm/AcmClient.php
Normal file
40
lib/aws-sdk/src/Acm/AcmClient.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace Aws\Acm;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS Certificate Manager** service.
|
||||
*
|
||||
* @method \Aws\Result addTagsToCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise addTagsToCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result deleteCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result describeCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise describeCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result exportCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise exportCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result getAccountConfiguration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAccountConfigurationAsync(array $args = [])
|
||||
* @method \Aws\Result getCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result importCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result listCertificates(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listCertificatesAsync(array $args = [])
|
||||
* @method \Aws\Result listTagsForCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listTagsForCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result putAccountConfiguration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putAccountConfigurationAsync(array $args = [])
|
||||
* @method \Aws\Result removeTagsFromCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise removeTagsFromCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result renewCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise renewCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result requestCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise requestCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result resendValidationEmail(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise resendValidationEmailAsync(array $args = [])
|
||||
* @method \Aws\Result updateCertificateOptions(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateCertificateOptionsAsync(array $args = [])
|
||||
*/
|
||||
class AcmClient extends AwsClient {}
|
9
lib/aws-sdk/src/Acm/Exception/AcmException.php
Normal file
9
lib/aws-sdk/src/Acm/Exception/AcmException.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\Acm\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS Certificate Manager** service.
|
||||
*/
|
||||
class AcmException extends AwsException {}
|
195
lib/aws-sdk/src/AlexaForBusiness/AlexaForBusinessClient.php
Normal file
195
lib/aws-sdk/src/AlexaForBusiness/AlexaForBusinessClient.php
Normal file
@ -0,0 +1,195 @@
|
||||
<?php
|
||||
namespace Aws\AlexaForBusiness;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **Alexa For Business** service.
|
||||
* @method \Aws\Result approveSkill(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise approveSkillAsync(array $args = [])
|
||||
* @method \Aws\Result associateContactWithAddressBook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise associateContactWithAddressBookAsync(array $args = [])
|
||||
* @method \Aws\Result associateDeviceWithNetworkProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise associateDeviceWithNetworkProfileAsync(array $args = [])
|
||||
* @method \Aws\Result associateDeviceWithRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise associateDeviceWithRoomAsync(array $args = [])
|
||||
* @method \Aws\Result associateSkillGroupWithRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise associateSkillGroupWithRoomAsync(array $args = [])
|
||||
* @method \Aws\Result associateSkillWithSkillGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise associateSkillWithSkillGroupAsync(array $args = [])
|
||||
* @method \Aws\Result associateSkillWithUsers(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise associateSkillWithUsersAsync(array $args = [])
|
||||
* @method \Aws\Result createAddressBook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createAddressBookAsync(array $args = [])
|
||||
* @method \Aws\Result createBusinessReportSchedule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBusinessReportScheduleAsync(array $args = [])
|
||||
* @method \Aws\Result createConferenceProvider(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createConferenceProviderAsync(array $args = [])
|
||||
* @method \Aws\Result createContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createContactAsync(array $args = [])
|
||||
* @method \Aws\Result createGatewayGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createGatewayGroupAsync(array $args = [])
|
||||
* @method \Aws\Result createNetworkProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createNetworkProfileAsync(array $args = [])
|
||||
* @method \Aws\Result createProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createProfileAsync(array $args = [])
|
||||
* @method \Aws\Result createRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createRoomAsync(array $args = [])
|
||||
* @method \Aws\Result createSkillGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createSkillGroupAsync(array $args = [])
|
||||
* @method \Aws\Result createUser(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createUserAsync(array $args = [])
|
||||
* @method \Aws\Result deleteAddressBook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAddressBookAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBusinessReportSchedule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBusinessReportScheduleAsync(array $args = [])
|
||||
* @method \Aws\Result deleteConferenceProvider(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteConferenceProviderAsync(array $args = [])
|
||||
* @method \Aws\Result deleteContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteContactAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDevice(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDeviceAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDeviceUsageData(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDeviceUsageDataAsync(array $args = [])
|
||||
* @method \Aws\Result deleteGatewayGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteGatewayGroupAsync(array $args = [])
|
||||
* @method \Aws\Result deleteNetworkProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteNetworkProfileAsync(array $args = [])
|
||||
* @method \Aws\Result deleteProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteProfileAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRoomAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRoomSkillParameter(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRoomSkillParameterAsync(array $args = [])
|
||||
* @method \Aws\Result deleteSkillAuthorization(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteSkillAuthorizationAsync(array $args = [])
|
||||
* @method \Aws\Result deleteSkillGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteSkillGroupAsync(array $args = [])
|
||||
* @method \Aws\Result deleteUser(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteUserAsync(array $args = [])
|
||||
* @method \Aws\Result disassociateContactFromAddressBook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise disassociateContactFromAddressBookAsync(array $args = [])
|
||||
* @method \Aws\Result disassociateDeviceFromRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise disassociateDeviceFromRoomAsync(array $args = [])
|
||||
* @method \Aws\Result disassociateSkillFromSkillGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise disassociateSkillFromSkillGroupAsync(array $args = [])
|
||||
* @method \Aws\Result disassociateSkillFromUsers(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise disassociateSkillFromUsersAsync(array $args = [])
|
||||
* @method \Aws\Result disassociateSkillGroupFromRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise disassociateSkillGroupFromRoomAsync(array $args = [])
|
||||
* @method \Aws\Result forgetSmartHomeAppliances(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise forgetSmartHomeAppliancesAsync(array $args = [])
|
||||
* @method \Aws\Result getAddressBook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAddressBookAsync(array $args = [])
|
||||
* @method \Aws\Result getConferencePreference(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getConferencePreferenceAsync(array $args = [])
|
||||
* @method \Aws\Result getConferenceProvider(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getConferenceProviderAsync(array $args = [])
|
||||
* @method \Aws\Result getContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getContactAsync(array $args = [])
|
||||
* @method \Aws\Result getDevice(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDeviceAsync(array $args = [])
|
||||
* @method \Aws\Result getGateway(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getGatewayAsync(array $args = [])
|
||||
* @method \Aws\Result getGatewayGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getGatewayGroupAsync(array $args = [])
|
||||
* @method \Aws\Result getInvitationConfiguration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getInvitationConfigurationAsync(array $args = [])
|
||||
* @method \Aws\Result getNetworkProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getNetworkProfileAsync(array $args = [])
|
||||
* @method \Aws\Result getProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getProfileAsync(array $args = [])
|
||||
* @method \Aws\Result getRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRoomAsync(array $args = [])
|
||||
* @method \Aws\Result getRoomSkillParameter(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRoomSkillParameterAsync(array $args = [])
|
||||
* @method \Aws\Result getSkillGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getSkillGroupAsync(array $args = [])
|
||||
* @method \Aws\Result listBusinessReportSchedules(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listBusinessReportSchedulesAsync(array $args = [])
|
||||
* @method \Aws\Result listConferenceProviders(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listConferenceProvidersAsync(array $args = [])
|
||||
* @method \Aws\Result listDeviceEvents(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listDeviceEventsAsync(array $args = [])
|
||||
* @method \Aws\Result listGatewayGroups(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listGatewayGroupsAsync(array $args = [])
|
||||
* @method \Aws\Result listGateways(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listGatewaysAsync(array $args = [])
|
||||
* @method \Aws\Result listSkills(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listSkillsAsync(array $args = [])
|
||||
* @method \Aws\Result listSkillsStoreCategories(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listSkillsStoreCategoriesAsync(array $args = [])
|
||||
* @method \Aws\Result listSkillsStoreSkillsByCategory(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listSkillsStoreSkillsByCategoryAsync(array $args = [])
|
||||
* @method \Aws\Result listSmartHomeAppliances(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listSmartHomeAppliancesAsync(array $args = [])
|
||||
* @method \Aws\Result listTags(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listTagsAsync(array $args = [])
|
||||
* @method \Aws\Result putConferencePreference(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putConferencePreferenceAsync(array $args = [])
|
||||
* @method \Aws\Result putInvitationConfiguration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putInvitationConfigurationAsync(array $args = [])
|
||||
* @method \Aws\Result putRoomSkillParameter(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putRoomSkillParameterAsync(array $args = [])
|
||||
* @method \Aws\Result putSkillAuthorization(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putSkillAuthorizationAsync(array $args = [])
|
||||
* @method \Aws\Result registerAVSDevice(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise registerAVSDeviceAsync(array $args = [])
|
||||
* @method \Aws\Result rejectSkill(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise rejectSkillAsync(array $args = [])
|
||||
* @method \Aws\Result resolveRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise resolveRoomAsync(array $args = [])
|
||||
* @method \Aws\Result revokeInvitation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise revokeInvitationAsync(array $args = [])
|
||||
* @method \Aws\Result searchAddressBooks(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchAddressBooksAsync(array $args = [])
|
||||
* @method \Aws\Result searchContacts(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchContactsAsync(array $args = [])
|
||||
* @method \Aws\Result searchDevices(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchDevicesAsync(array $args = [])
|
||||
* @method \Aws\Result searchNetworkProfiles(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchNetworkProfilesAsync(array $args = [])
|
||||
* @method \Aws\Result searchProfiles(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchProfilesAsync(array $args = [])
|
||||
* @method \Aws\Result searchRooms(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchRoomsAsync(array $args = [])
|
||||
* @method \Aws\Result searchSkillGroups(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchSkillGroupsAsync(array $args = [])
|
||||
* @method \Aws\Result searchUsers(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise searchUsersAsync(array $args = [])
|
||||
* @method \Aws\Result sendAnnouncement(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise sendAnnouncementAsync(array $args = [])
|
||||
* @method \Aws\Result sendInvitation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise sendInvitationAsync(array $args = [])
|
||||
* @method \Aws\Result startDeviceSync(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startDeviceSyncAsync(array $args = [])
|
||||
* @method \Aws\Result startSmartHomeApplianceDiscovery(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startSmartHomeApplianceDiscoveryAsync(array $args = [])
|
||||
* @method \Aws\Result tagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result untagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result updateAddressBook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateAddressBookAsync(array $args = [])
|
||||
* @method \Aws\Result updateBusinessReportSchedule(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBusinessReportScheduleAsync(array $args = [])
|
||||
* @method \Aws\Result updateConferenceProvider(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateConferenceProviderAsync(array $args = [])
|
||||
* @method \Aws\Result updateContact(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateContactAsync(array $args = [])
|
||||
* @method \Aws\Result updateDevice(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDeviceAsync(array $args = [])
|
||||
* @method \Aws\Result updateGateway(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateGatewayAsync(array $args = [])
|
||||
* @method \Aws\Result updateGatewayGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateGatewayGroupAsync(array $args = [])
|
||||
* @method \Aws\Result updateNetworkProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateNetworkProfileAsync(array $args = [])
|
||||
* @method \Aws\Result updateProfile(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateProfileAsync(array $args = [])
|
||||
* @method \Aws\Result updateRoom(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateRoomAsync(array $args = [])
|
||||
* @method \Aws\Result updateSkillGroup(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateSkillGroupAsync(array $args = [])
|
||||
*/
|
||||
class AlexaForBusinessClient extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\AlexaForBusiness\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **Alexa For Business** service.
|
||||
*/
|
||||
class AlexaForBusinessException extends AwsException {}
|
83
lib/aws-sdk/src/Amplify/AmplifyClient.php
Normal file
83
lib/aws-sdk/src/Amplify/AmplifyClient.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
namespace Aws\Amplify;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS Amplify** service.
|
||||
* @method \Aws\Result createApp(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createAppAsync(array $args = [])
|
||||
* @method \Aws\Result createBackendEnvironment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBackendEnvironmentAsync(array $args = [])
|
||||
* @method \Aws\Result createBranch(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBranchAsync(array $args = [])
|
||||
* @method \Aws\Result createDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result createDomainAssociation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDomainAssociationAsync(array $args = [])
|
||||
* @method \Aws\Result createWebhook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createWebhookAsync(array $args = [])
|
||||
* @method \Aws\Result deleteApp(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAppAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBackendEnvironment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBackendEnvironmentAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBranch(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBranchAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDomainAssociation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDomainAssociationAsync(array $args = [])
|
||||
* @method \Aws\Result deleteJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteJobAsync(array $args = [])
|
||||
* @method \Aws\Result deleteWebhook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteWebhookAsync(array $args = [])
|
||||
* @method \Aws\Result generateAccessLogs(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise generateAccessLogsAsync(array $args = [])
|
||||
* @method \Aws\Result getApp(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAppAsync(array $args = [])
|
||||
* @method \Aws\Result getArtifactUrl(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getArtifactUrlAsync(array $args = [])
|
||||
* @method \Aws\Result getBackendEnvironment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendEnvironmentAsync(array $args = [])
|
||||
* @method \Aws\Result getBranch(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBranchAsync(array $args = [])
|
||||
* @method \Aws\Result getDomainAssociation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDomainAssociationAsync(array $args = [])
|
||||
* @method \Aws\Result getJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getJobAsync(array $args = [])
|
||||
* @method \Aws\Result getWebhook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getWebhookAsync(array $args = [])
|
||||
* @method \Aws\Result listApps(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listAppsAsync(array $args = [])
|
||||
* @method \Aws\Result listArtifacts(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listArtifactsAsync(array $args = [])
|
||||
* @method \Aws\Result listBackendEnvironments(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listBackendEnvironmentsAsync(array $args = [])
|
||||
* @method \Aws\Result listBranches(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listBranchesAsync(array $args = [])
|
||||
* @method \Aws\Result listDomainAssociations(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listDomainAssociationsAsync(array $args = [])
|
||||
* @method \Aws\Result listJobs(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listJobsAsync(array $args = [])
|
||||
* @method \Aws\Result listTagsForResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
|
||||
* @method \Aws\Result listWebhooks(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listWebhooksAsync(array $args = [])
|
||||
* @method \Aws\Result startDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result startJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startJobAsync(array $args = [])
|
||||
* @method \Aws\Result stopJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise stopJobAsync(array $args = [])
|
||||
* @method \Aws\Result tagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result untagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result updateApp(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateAppAsync(array $args = [])
|
||||
* @method \Aws\Result updateBranch(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBranchAsync(array $args = [])
|
||||
* @method \Aws\Result updateDomainAssociation(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDomainAssociationAsync(array $args = [])
|
||||
* @method \Aws\Result updateWebhook(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateWebhookAsync(array $args = [])
|
||||
*/
|
||||
class AmplifyClient extends AwsClient {}
|
9
lib/aws-sdk/src/Amplify/Exception/AmplifyException.php
Normal file
9
lib/aws-sdk/src/Amplify/Exception/AmplifyException.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\Amplify\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS Amplify** service.
|
||||
*/
|
||||
class AmplifyException extends AwsException {}
|
71
lib/aws-sdk/src/AmplifyBackend/AmplifyBackendClient.php
Normal file
71
lib/aws-sdk/src/AmplifyBackend/AmplifyBackendClient.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace Aws\AmplifyBackend;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AmplifyBackend** service.
|
||||
* @method \Aws\Result cloneBackend(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise cloneBackendAsync(array $args = [])
|
||||
* @method \Aws\Result createBackend(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBackendAsync(array $args = [])
|
||||
* @method \Aws\Result createBackendAPI(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBackendAPIAsync(array $args = [])
|
||||
* @method \Aws\Result createBackendAuth(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBackendAuthAsync(array $args = [])
|
||||
* @method \Aws\Result createBackendConfig(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBackendConfigAsync(array $args = [])
|
||||
* @method \Aws\Result createBackendStorage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBackendStorageAsync(array $args = [])
|
||||
* @method \Aws\Result createToken(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createTokenAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBackend(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBackendAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBackendAPI(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBackendAPIAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBackendAuth(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBackendAuthAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBackendStorage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBackendStorageAsync(array $args = [])
|
||||
* @method \Aws\Result deleteToken(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteTokenAsync(array $args = [])
|
||||
* @method \Aws\Result generateBackendAPIModels(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise generateBackendAPIModelsAsync(array $args = [])
|
||||
* @method \Aws\Result getBackend(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendAsync(array $args = [])
|
||||
* @method \Aws\Result getBackendAPI(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendAPIAsync(array $args = [])
|
||||
* @method \Aws\Result getBackendAPIModels(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendAPIModelsAsync(array $args = [])
|
||||
* @method \Aws\Result getBackendAuth(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendAuthAsync(array $args = [])
|
||||
* @method \Aws\Result getBackendJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendJobAsync(array $args = [])
|
||||
* @method \Aws\Result getBackendStorage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBackendStorageAsync(array $args = [])
|
||||
* @method \Aws\Result getToken(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getTokenAsync(array $args = [])
|
||||
* @method \Aws\Result importBackendAuth(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importBackendAuthAsync(array $args = [])
|
||||
* @method \Aws\Result importBackendStorage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importBackendStorageAsync(array $args = [])
|
||||
* @method \Aws\Result listBackendJobs(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listBackendJobsAsync(array $args = [])
|
||||
* @method \Aws\Result listS3Buckets(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listS3BucketsAsync(array $args = [])
|
||||
* @method \Aws\Result removeAllBackends(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise removeAllBackendsAsync(array $args = [])
|
||||
* @method \Aws\Result removeBackendConfig(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise removeBackendConfigAsync(array $args = [])
|
||||
* @method \Aws\Result updateBackendAPI(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBackendAPIAsync(array $args = [])
|
||||
* @method \Aws\Result updateBackendAuth(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBackendAuthAsync(array $args = [])
|
||||
* @method \Aws\Result updateBackendConfig(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBackendConfigAsync(array $args = [])
|
||||
* @method \Aws\Result updateBackendJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBackendJobAsync(array $args = [])
|
||||
* @method \Aws\Result updateBackendStorage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBackendStorageAsync(array $args = [])
|
||||
*/
|
||||
class AmplifyBackendClient extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\AmplifyBackend\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AmplifyBackend** service.
|
||||
*/
|
||||
class AmplifyBackendException extends AwsException {}
|
59
lib/aws-sdk/src/AmplifyUIBuilder/AmplifyUIBuilderClient.php
Normal file
59
lib/aws-sdk/src/AmplifyUIBuilder/AmplifyUIBuilderClient.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace Aws\AmplifyUIBuilder;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS Amplify UI Builder** service.
|
||||
* @method \Aws\Result createComponent(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createComponentAsync(array $args = [])
|
||||
* @method \Aws\Result createForm(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createFormAsync(array $args = [])
|
||||
* @method \Aws\Result createTheme(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createThemeAsync(array $args = [])
|
||||
* @method \Aws\Result deleteComponent(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteComponentAsync(array $args = [])
|
||||
* @method \Aws\Result deleteForm(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteFormAsync(array $args = [])
|
||||
* @method \Aws\Result deleteTheme(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteThemeAsync(array $args = [])
|
||||
* @method \Aws\Result exchangeCodeForToken(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise exchangeCodeForTokenAsync(array $args = [])
|
||||
* @method \Aws\Result exportComponents(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise exportComponentsAsync(array $args = [])
|
||||
* @method \Aws\Result exportForms(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise exportFormsAsync(array $args = [])
|
||||
* @method \Aws\Result exportThemes(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise exportThemesAsync(array $args = [])
|
||||
* @method \Aws\Result getCodegenJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getCodegenJobAsync(array $args = [])
|
||||
* @method \Aws\Result getComponent(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getComponentAsync(array $args = [])
|
||||
* @method \Aws\Result getForm(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getFormAsync(array $args = [])
|
||||
* @method \Aws\Result getMetadata(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getMetadataAsync(array $args = [])
|
||||
* @method \Aws\Result getTheme(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getThemeAsync(array $args = [])
|
||||
* @method \Aws\Result listCodegenJobs(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listCodegenJobsAsync(array $args = [])
|
||||
* @method \Aws\Result listComponents(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listComponentsAsync(array $args = [])
|
||||
* @method \Aws\Result listForms(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listFormsAsync(array $args = [])
|
||||
* @method \Aws\Result listThemes(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise listThemesAsync(array $args = [])
|
||||
* @method \Aws\Result putMetadataFlag(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putMetadataFlagAsync(array $args = [])
|
||||
* @method \Aws\Result refreshToken(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise refreshTokenAsync(array $args = [])
|
||||
* @method \Aws\Result startCodegenJob(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startCodegenJobAsync(array $args = [])
|
||||
* @method \Aws\Result updateComponent(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateComponentAsync(array $args = [])
|
||||
* @method \Aws\Result updateForm(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateFormAsync(array $args = [])
|
||||
* @method \Aws\Result updateTheme(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateThemeAsync(array $args = [])
|
||||
*/
|
||||
class AmplifyUIBuilderClient extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\AmplifyUIBuilder\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS Amplify UI Builder** service.
|
||||
*/
|
||||
class AmplifyUIBuilderException extends AwsException {}
|
89
lib/aws-sdk/src/Api/AbstractModel.php
Normal file
89
lib/aws-sdk/src/Api/AbstractModel.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Base class that is used by most API shapes
|
||||
*/
|
||||
abstract class AbstractModel implements \ArrayAccess
|
||||
{
|
||||
/** @var array */
|
||||
protected $definition;
|
||||
|
||||
/** @var ShapeMap */
|
||||
protected $shapeMap;
|
||||
|
||||
/** @var array */
|
||||
protected $contextParam;
|
||||
|
||||
/**
|
||||
* @param array $definition Service description
|
||||
* @param ShapeMap $shapeMap Shapemap used for creating shapes
|
||||
*/
|
||||
public function __construct(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
$this->definition = $definition;
|
||||
$this->shapeMap = $shapeMap;
|
||||
if (isset($definition['contextParam'])) {
|
||||
$this->contextParam = $definition['contextParam'];
|
||||
}
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return $this->definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->definition[$offset])
|
||||
? $this->definition[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->definition[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->definition[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->definition[$offset]);
|
||||
}
|
||||
|
||||
protected function shapeAt($key)
|
||||
{
|
||||
if (!isset($this->definition[$key])) {
|
||||
throw new \InvalidArgumentException('Expected shape definition at '
|
||||
. $key);
|
||||
}
|
||||
|
||||
return $this->shapeFor($this->definition[$key]);
|
||||
}
|
||||
|
||||
protected function shapeFor(array $definition)
|
||||
{
|
||||
return isset($definition['shape'])
|
||||
? $this->shapeMap->resolve($definition)
|
||||
: Shape::create($definition, $this->shapeMap);
|
||||
}
|
||||
}
|
244
lib/aws-sdk/src/Api/ApiProvider.php
Normal file
244
lib/aws-sdk/src/Api/ApiProvider.php
Normal file
@ -0,0 +1,244 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
use Aws\Exception\UnresolvedApiException;
|
||||
|
||||
/**
|
||||
* API providers.
|
||||
*
|
||||
* An API provider is a function that accepts a type, service, and version and
|
||||
* returns an array of API data on success or NULL if no API data can be created
|
||||
* for the provided arguments.
|
||||
*
|
||||
* You can wrap your calls to an API provider with the
|
||||
* {@see ApiProvider::resolve} method to ensure that API data is created. If the
|
||||
* API data is not created, then the resolve() method will throw a
|
||||
* {@see Aws\Exception\UnresolvedApiException}.
|
||||
*
|
||||
* use Aws\Api\ApiProvider;
|
||||
* $provider = ApiProvider::defaultProvider();
|
||||
* // Returns an array or NULL.
|
||||
* $data = $provider('api', 's3', '2006-03-01');
|
||||
* // Returns an array or throws.
|
||||
* $data = ApiProvider::resolve($provider, 'api', 'elasticfood', '2020-01-01');
|
||||
*
|
||||
* You can compose multiple providers into a single provider using
|
||||
* {@see Aws\or_chain}. This method accepts providers as arguments and
|
||||
* returns a new function that will invoke each provider until a non-null value
|
||||
* is returned.
|
||||
*
|
||||
* $a = ApiProvider::filesystem(sys_get_temp_dir() . '/aws-beta-models');
|
||||
* $b = ApiProvider::manifest();
|
||||
*
|
||||
* $c = \Aws\or_chain($a, $b);
|
||||
* $data = $c('api', 'betaservice', '2015-08-08'); // $a handles this.
|
||||
* $data = $c('api', 's3', '2006-03-01'); // $b handles this.
|
||||
* $data = $c('api', 'invalid', '2014-12-15'); // Neither handles this.
|
||||
*/
|
||||
class ApiProvider
|
||||
{
|
||||
/** @var array A map of public API type names to their file suffix. */
|
||||
private static $typeMap = [
|
||||
'api' => 'api-2',
|
||||
'paginator' => 'paginators-1',
|
||||
'waiter' => 'waiters-2',
|
||||
'docs' => 'docs-2',
|
||||
];
|
||||
|
||||
/** @var array API manifest */
|
||||
private $manifest;
|
||||
|
||||
/** @var string The directory containing service models. */
|
||||
private $modelsDir;
|
||||
|
||||
/**
|
||||
* Resolves an API provider and ensures a non-null return value.
|
||||
*
|
||||
* @param callable $provider Provider function to invoke.
|
||||
* @param string $type Type of data ('api', 'waiter', 'paginator').
|
||||
* @param string $service Service name.
|
||||
* @param string $version API version.
|
||||
*
|
||||
* @return array
|
||||
* @throws UnresolvedApiException
|
||||
*/
|
||||
public static function resolve(callable $provider, $type, $service, $version)
|
||||
{
|
||||
// Execute the provider and return the result, if there is one.
|
||||
$result = $provider($type, $service, $version);
|
||||
if (is_array($result)) {
|
||||
if (!isset($result['metadata']['serviceIdentifier'])) {
|
||||
$result['metadata']['serviceIdentifier'] = $service;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Throw an exception with a message depending on the inputs.
|
||||
if (!isset(self::$typeMap[$type])) {
|
||||
$msg = "The type must be one of: " . implode(', ', self::$typeMap);
|
||||
} elseif ($service) {
|
||||
$msg = "The {$service} service does not have version: {$version}.";
|
||||
} else {
|
||||
$msg = "You must specify a service name to retrieve its API data.";
|
||||
}
|
||||
|
||||
throw new UnresolvedApiException($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default SDK API provider.
|
||||
*
|
||||
* This provider loads pre-built manifest data from the `data` directory.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function defaultProvider()
|
||||
{
|
||||
return new self(__DIR__ . '/../data', \Aws\manifest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads API data after resolving the version to the latest, compatible,
|
||||
* available version based on the provided manifest data.
|
||||
*
|
||||
* Manifest data is essentially an associative array of service names to
|
||||
* associative arrays of API version aliases.
|
||||
*
|
||||
* [
|
||||
* ...
|
||||
* 'ec2' => [
|
||||
* 'latest' => '2014-10-01',
|
||||
* '2014-10-01' => '2014-10-01',
|
||||
* '2014-09-01' => '2014-10-01',
|
||||
* '2014-06-15' => '2014-10-01',
|
||||
* ...
|
||||
* ],
|
||||
* 'ecs' => [...],
|
||||
* 'elasticache' => [...],
|
||||
* ...
|
||||
* ]
|
||||
*
|
||||
* @param string $dir Directory containing service models.
|
||||
* @param array $manifest The API version manifest data.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function manifest($dir, array $manifest)
|
||||
{
|
||||
return new self($dir, $manifest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads API data from the specified directory.
|
||||
*
|
||||
* If "latest" is specified as the version, this provider must glob the
|
||||
* directory to find which is the latest available version.
|
||||
*
|
||||
* @param string $dir Directory containing service models.
|
||||
*
|
||||
* @return self
|
||||
* @throws \InvalidArgumentException if the provided `$dir` is invalid.
|
||||
*/
|
||||
public static function filesystem($dir)
|
||||
{
|
||||
return new self($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of valid versions for the specified service.
|
||||
*
|
||||
* @param string $service Service name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getVersions($service)
|
||||
{
|
||||
if (!isset($this->manifest)) {
|
||||
$this->buildVersionsList($service);
|
||||
}
|
||||
|
||||
if (!isset($this->manifest[$service]['versions'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_values(array_unique($this->manifest[$service]['versions']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the provider.
|
||||
*
|
||||
* @param string $type Type of data ('api', 'waiter', 'paginator').
|
||||
* @param string $service Service name.
|
||||
* @param string $version API version.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function __invoke($type, $service, $version)
|
||||
{
|
||||
// Resolve the type or return null.
|
||||
if (isset(self::$typeMap[$type])) {
|
||||
$type = self::$typeMap[$type];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve the version or return null.
|
||||
if (!isset($this->manifest)) {
|
||||
$this->buildVersionsList($service);
|
||||
}
|
||||
|
||||
if (!isset($this->manifest[$service]['versions'][$version])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$version = $this->manifest[$service]['versions'][$version];
|
||||
$path = "{$this->modelsDir}/{$service}/{$version}/{$type}.json";
|
||||
|
||||
try {
|
||||
return \Aws\load_compiled_json($path);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $modelsDir Directory containing service models.
|
||||
* @param array $manifest The API version manifest data.
|
||||
*/
|
||||
private function __construct($modelsDir, array $manifest = null)
|
||||
{
|
||||
$this->manifest = $manifest;
|
||||
$this->modelsDir = rtrim($modelsDir, '/');
|
||||
if (!is_dir($this->modelsDir)) {
|
||||
throw new \InvalidArgumentException(
|
||||
"The specified models directory, {$modelsDir}, was not found."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the versions list for the specified service by globbing the dir.
|
||||
*/
|
||||
private function buildVersionsList($service)
|
||||
{
|
||||
$dir = "{$this->modelsDir}/{$service}/";
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get versions, remove . and .., and sort in descending order.
|
||||
$results = array_diff(scandir($dir, SCANDIR_SORT_DESCENDING), ['..', '.']);
|
||||
|
||||
if (!$results) {
|
||||
$this->manifest[$service] = ['versions' => []];
|
||||
} else {
|
||||
$this->manifest[$service] = [
|
||||
'versions' => [
|
||||
'latest' => $results[0]
|
||||
]
|
||||
];
|
||||
$this->manifest[$service]['versions'] += array_combine($results, $results);
|
||||
}
|
||||
}
|
||||
}
|
124
lib/aws-sdk/src/Api/DateTimeResult.php
Normal file
124
lib/aws-sdk/src/Api/DateTimeResult.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Aws\Api;
|
||||
|
||||
use Aws\Api\Parser\Exception\ParserException;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* DateTime overrides that make DateTime work more seamlessly as a string,
|
||||
* with JSON documents, and with JMESPath.
|
||||
*/
|
||||
class DateTimeResult extends \DateTime implements \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Create a new DateTimeResult from a unix timestamp.
|
||||
* The Unix epoch (or Unix time or POSIX time or Unix
|
||||
* timestamp) is the number of seconds that have elapsed since
|
||||
* January 1, 1970 (midnight UTC/GMT).
|
||||
*
|
||||
* @return DateTimeResult
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fromEpoch($unixTimestamp)
|
||||
{
|
||||
if (!is_numeric($unixTimestamp)) {
|
||||
throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromEpoch');
|
||||
}
|
||||
|
||||
// PHP 5.5 does not support sub-second precision
|
||||
if (\PHP_VERSION_ID < 56000) {
|
||||
return new self(gmdate('c', $unixTimestamp));
|
||||
}
|
||||
|
||||
$decimalSeparator = isset(localeconv()['decimal_point']) ? localeconv()['decimal_point'] : ".";
|
||||
$formatString = "U" . $decimalSeparator . "u";
|
||||
$dateTime = DateTime::createFromFormat(
|
||||
$formatString,
|
||||
sprintf('%0.6f', $unixTimestamp),
|
||||
new DateTimeZone('UTC')
|
||||
);
|
||||
|
||||
if (false === $dateTime) {
|
||||
throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromEpoch');
|
||||
}
|
||||
|
||||
return new self(
|
||||
$dateTime->format('Y-m-d H:i:s.u'),
|
||||
new DateTimeZone('UTC')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DateTimeResult
|
||||
*/
|
||||
public static function fromISO8601($iso8601Timestamp)
|
||||
{
|
||||
if (is_numeric($iso8601Timestamp) || !is_string($iso8601Timestamp)) {
|
||||
throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromISO8601');
|
||||
}
|
||||
|
||||
return new DateTimeResult($iso8601Timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DateTimeResult from an unknown timestamp.
|
||||
*
|
||||
* @return DateTimeResult
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fromTimestamp($timestamp, $expectedFormat = null)
|
||||
{
|
||||
if (empty($timestamp)) {
|
||||
return self::fromEpoch(0);
|
||||
}
|
||||
|
||||
if (!(is_string($timestamp) || is_numeric($timestamp))) {
|
||||
throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp');
|
||||
}
|
||||
|
||||
try {
|
||||
if ($expectedFormat == 'iso8601') {
|
||||
try {
|
||||
return self::fromISO8601($timestamp);
|
||||
} catch (Exception $exception) {
|
||||
return self::fromEpoch($timestamp);
|
||||
}
|
||||
} else if ($expectedFormat == 'unixTimestamp') {
|
||||
try {
|
||||
return self::fromEpoch($timestamp);
|
||||
} catch (Exception $exception) {
|
||||
return self::fromISO8601($timestamp);
|
||||
}
|
||||
} else if (\Aws\is_valid_epoch($timestamp)) {
|
||||
return self::fromEpoch($timestamp);
|
||||
}
|
||||
return self::fromISO8601($timestamp);
|
||||
} catch (Exception $exception) {
|
||||
throw new ParserException('Invalid timestamp value passed to DateTimeResult::fromTimestamp');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the DateTimeResult as an ISO 8601 date string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->format('c');
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the date as an ISO 8601 date when serializing as JSON.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return (string) $this;
|
||||
}
|
||||
}
|
138
lib/aws-sdk/src/Api/DocModel.php
Normal file
138
lib/aws-sdk/src/Api/DocModel.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Encapsulates the documentation strings for a given service-version and
|
||||
* provides methods for extracting the desired parts related to a service,
|
||||
* operation, error, or shape (i.e., parameter).
|
||||
*/
|
||||
class DocModel
|
||||
{
|
||||
/** @var array */
|
||||
private $docs;
|
||||
|
||||
/**
|
||||
* @param array $docs
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function __construct(array $docs)
|
||||
{
|
||||
if (!extension_loaded('tidy')) {
|
||||
throw new \RuntimeException('The "tidy" PHP extension is required.');
|
||||
}
|
||||
|
||||
$this->docs = $docs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the doc model to an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->docs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves documentation about the service.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getServiceDocs()
|
||||
{
|
||||
return isset($this->docs['service']) ? $this->docs['service'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves documentation about an operation.
|
||||
*
|
||||
* @param string $operation Name of the operation
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getOperationDocs($operation)
|
||||
{
|
||||
return isset($this->docs['operations'][$operation])
|
||||
? $this->docs['operations'][$operation]
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves documentation about an error.
|
||||
*
|
||||
* @param string $error Name of the error
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getErrorDocs($error)
|
||||
{
|
||||
return isset($this->docs['shapes'][$error]['base'])
|
||||
? $this->docs['shapes'][$error]['base']
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves documentation about a shape, specific to the context.
|
||||
*
|
||||
* @param string $shapeName Name of the shape.
|
||||
* @param string $parentName Name of the parent/context shape.
|
||||
* @param string $ref Name used by the context to reference the shape.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getShapeDocs($shapeName, $parentName, $ref)
|
||||
{
|
||||
if (!isset($this->docs['shapes'][$shapeName])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$result = '';
|
||||
$d = $this->docs['shapes'][$shapeName];
|
||||
if (isset($d['refs']["{$parentName}\$${ref}"])) {
|
||||
$result = $d['refs']["{$parentName}\$${ref}"];
|
||||
} elseif (isset($d['base'])) {
|
||||
$result = $d['base'];
|
||||
}
|
||||
|
||||
if (isset($d['append'])) {
|
||||
if (!isset($d['excludeAppend'])
|
||||
|| !in_array($parentName, $d['excludeAppend'])
|
||||
) {
|
||||
$result .= $d['append'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($d['appendOnly'])
|
||||
&& in_array($parentName, $d['appendOnly']['shapes'])
|
||||
) {
|
||||
$result .= $d['appendOnly']['message'];
|
||||
}
|
||||
|
||||
return $this->clean($result);
|
||||
}
|
||||
|
||||
private function clean($content)
|
||||
{
|
||||
if (!$content) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$tidy = new \tidy();
|
||||
$tidy->parseString($content, [
|
||||
'indent' => true,
|
||||
'doctype' => 'omit',
|
||||
'output-html' => true,
|
||||
'show-body-only' => true,
|
||||
'drop-empty-paras' => true,
|
||||
'drop-font-tags' => true,
|
||||
'drop-proprietary-attributes' => true,
|
||||
'hide-comments' => true,
|
||||
'logical-emphasis' => true
|
||||
]);
|
||||
$tidy->cleanRepair();
|
||||
|
||||
return (string) $content;
|
||||
}
|
||||
}
|
95
lib/aws-sdk/src/Api/ErrorParser/AbstractErrorParser.php
Normal file
95
lib/aws-sdk/src/Api/ErrorParser/AbstractErrorParser.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace Aws\Api\ErrorParser;
|
||||
|
||||
use Aws\Api\Parser\MetadataParserTrait;
|
||||
use Aws\Api\Parser\PayloadParserTrait;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
abstract class AbstractErrorParser
|
||||
{
|
||||
use MetadataParserTrait;
|
||||
use PayloadParserTrait;
|
||||
|
||||
/**
|
||||
* @var Service
|
||||
*/
|
||||
protected $api;
|
||||
|
||||
/**
|
||||
* @param Service $api
|
||||
*/
|
||||
public function __construct(Service $api = null)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
abstract protected function payload(
|
||||
ResponseInterface $response,
|
||||
StructureShape $member
|
||||
);
|
||||
|
||||
protected function extractPayload(
|
||||
StructureShape $member,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
if ($member instanceof StructureShape) {
|
||||
// Structure members parse top-level data into a specific key.
|
||||
return $this->payload($response, $member);
|
||||
} else {
|
||||
// Streaming data is just the stream from the response body.
|
||||
return $response->getBody();
|
||||
}
|
||||
}
|
||||
|
||||
protected function populateShape(
|
||||
array &$data,
|
||||
ResponseInterface $response,
|
||||
CommandInterface $command = null
|
||||
) {
|
||||
$data['body'] = [];
|
||||
|
||||
if (!empty($command) && !empty($this->api)) {
|
||||
|
||||
// If modeled error code is indicated, check for known error shape
|
||||
if (!empty($data['code'])) {
|
||||
|
||||
$errors = $this->api->getOperation($command->getName())->getErrors();
|
||||
foreach ($errors as $key => $error) {
|
||||
|
||||
// If error code matches a known error shape, populate the body
|
||||
if ($data['code'] == $error['name']
|
||||
&& $error instanceof StructureShape
|
||||
) {
|
||||
$modeledError = $error;
|
||||
$data['body'] = $this->extractPayload(
|
||||
$modeledError,
|
||||
$response
|
||||
);
|
||||
$data['error_shape'] = $modeledError;
|
||||
|
||||
foreach ($error->getMembers() as $name => $member) {
|
||||
switch ($member['location']) {
|
||||
case 'header':
|
||||
$this->extractHeader($name, $member, $response, $data['body']);
|
||||
break;
|
||||
case 'headers':
|
||||
$this->extractHeaders($name, $member, $response, $data['body']);
|
||||
break;
|
||||
case 'statusCode':
|
||||
$this->extractStatus($name, $response, $data['body']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
52
lib/aws-sdk/src/Api/ErrorParser/JsonParserTrait.php
Normal file
52
lib/aws-sdk/src/Api/ErrorParser/JsonParserTrait.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace Aws\Api\ErrorParser;
|
||||
|
||||
use Aws\Api\Parser\PayloadParserTrait;
|
||||
use Aws\Api\StructureShape;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Provides basic JSON error parsing functionality.
|
||||
*/
|
||||
trait JsonParserTrait
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
private function genericHandler(ResponseInterface $response)
|
||||
{
|
||||
$code = (string) $response->getStatusCode();
|
||||
if ($this->api
|
||||
&& !is_null($this->api->getMetadata('awsQueryCompatible'))
|
||||
&& $response->getHeaderLine('x-amzn-query-error')
|
||||
) {
|
||||
$queryError = $response->getHeaderLine('x-amzn-query-error');
|
||||
$parts = explode(';', $queryError);
|
||||
if (isset($parts) && count($parts) == 2 && $parts[0] && $parts[1]) {
|
||||
$error_code = $parts[0];
|
||||
$error_type = $parts[1];
|
||||
}
|
||||
}
|
||||
if (!isset($error_type)) {
|
||||
$error_type = $code[0] == '4' ? 'client' : 'server';
|
||||
}
|
||||
|
||||
return [
|
||||
'request_id' => (string) $response->getHeaderLine('x-amzn-requestid'),
|
||||
'code' => isset($error_code) ? $error_code : null,
|
||||
'message' => null,
|
||||
'type' => $error_type,
|
||||
'parsed' => $this->parseJson($response->getBody(), $response)
|
||||
];
|
||||
}
|
||||
|
||||
protected function payload(
|
||||
ResponseInterface $response,
|
||||
StructureShape $member
|
||||
) {
|
||||
$jsonBody = $this->parseJson($response->getBody(), $response);
|
||||
|
||||
if ($jsonBody) {
|
||||
return $this->parser->parse($member, $jsonBody);
|
||||
}
|
||||
}
|
||||
}
|
49
lib/aws-sdk/src/Api/ErrorParser/JsonRpcErrorParser.php
Normal file
49
lib/aws-sdk/src/Api/ErrorParser/JsonRpcErrorParser.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Aws\Api\ErrorParser;
|
||||
|
||||
use Aws\Api\Parser\JsonParser;
|
||||
use Aws\Api\Service;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Parsers JSON-RPC errors.
|
||||
*/
|
||||
class JsonRpcErrorParser extends AbstractErrorParser
|
||||
{
|
||||
use JsonParserTrait;
|
||||
|
||||
private $parser;
|
||||
|
||||
public function __construct(Service $api = null, JsonParser $parser = null)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->parser = $parser ?: new JsonParser();
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
ResponseInterface $response,
|
||||
CommandInterface $command = null
|
||||
) {
|
||||
$data = $this->genericHandler($response);
|
||||
|
||||
// Make the casing consistent across services.
|
||||
if ($data['parsed']) {
|
||||
$data['parsed'] = array_change_key_case($data['parsed']);
|
||||
}
|
||||
|
||||
if (isset($data['parsed']['__type'])) {
|
||||
if (!isset($data['code'])) {
|
||||
$parts = explode('#', $data['parsed']['__type']);
|
||||
$data['code'] = isset($parts[1]) ? $parts[1] : $parts[0];
|
||||
}
|
||||
$data['message'] = isset($data['parsed']['message'])
|
||||
? $data['parsed']['message']
|
||||
: null;
|
||||
}
|
||||
|
||||
$this->populateShape($data, $response, $command);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
58
lib/aws-sdk/src/Api/ErrorParser/RestJsonErrorParser.php
Normal file
58
lib/aws-sdk/src/Api/ErrorParser/RestJsonErrorParser.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace Aws\Api\ErrorParser;
|
||||
|
||||
use Aws\Api\Parser\JsonParser;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Parses JSON-REST errors.
|
||||
*/
|
||||
class RestJsonErrorParser extends AbstractErrorParser
|
||||
{
|
||||
use JsonParserTrait;
|
||||
|
||||
private $parser;
|
||||
|
||||
public function __construct(Service $api = null, JsonParser $parser = null)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->parser = $parser ?: new JsonParser();
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
ResponseInterface $response,
|
||||
CommandInterface $command = null
|
||||
) {
|
||||
$data = $this->genericHandler($response);
|
||||
|
||||
// Merge in error data from the JSON body
|
||||
if ($json = $data['parsed']) {
|
||||
$data = array_replace($data, $json);
|
||||
}
|
||||
|
||||
// Correct error type from services like Amazon Glacier
|
||||
if (!empty($data['type'])) {
|
||||
$data['type'] = strtolower($data['type']);
|
||||
}
|
||||
|
||||
// Retrieve the error code from services like Amazon Elastic Transcoder
|
||||
if ($code = $response->getHeaderLine('x-amzn-errortype')) {
|
||||
$colon = strpos($code, ':');
|
||||
$data['code'] = $colon ? substr($code, 0, $colon) : $code;
|
||||
}
|
||||
|
||||
// Retrieve error message directly
|
||||
$data['message'] = isset($data['parsed']['message'])
|
||||
? $data['parsed']['message']
|
||||
: (isset($data['parsed']['Message'])
|
||||
? $data['parsed']['Message']
|
||||
: null);
|
||||
|
||||
$this->populateShape($data, $response, $command);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
111
lib/aws-sdk/src/Api/ErrorParser/XmlErrorParser.php
Normal file
111
lib/aws-sdk/src/Api/ErrorParser/XmlErrorParser.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
namespace Aws\Api\ErrorParser;
|
||||
|
||||
use Aws\Api\Parser\PayloadParserTrait;
|
||||
use Aws\Api\Parser\XmlParser;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Parses XML errors.
|
||||
*/
|
||||
class XmlErrorParser extends AbstractErrorParser
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
protected $parser;
|
||||
|
||||
public function __construct(Service $api = null, XmlParser $parser = null)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->parser = $parser ?: new XmlParser();
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
ResponseInterface $response,
|
||||
CommandInterface $command = null
|
||||
) {
|
||||
$code = (string) $response->getStatusCode();
|
||||
|
||||
$data = [
|
||||
'type' => $code[0] == '4' ? 'client' : 'server',
|
||||
'request_id' => null,
|
||||
'code' => null,
|
||||
'message' => null,
|
||||
'parsed' => null
|
||||
];
|
||||
|
||||
$body = $response->getBody();
|
||||
if ($body->getSize() > 0) {
|
||||
$this->parseBody($this->parseXml($body, $response), $data);
|
||||
} else {
|
||||
$this->parseHeaders($response, $data);
|
||||
}
|
||||
|
||||
$this->populateShape($data, $response, $command);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function parseHeaders(ResponseInterface $response, array &$data)
|
||||
{
|
||||
if ($response->getStatusCode() == '404') {
|
||||
$data['code'] = 'NotFound';
|
||||
}
|
||||
|
||||
$data['message'] = $response->getStatusCode() . ' '
|
||||
. $response->getReasonPhrase();
|
||||
|
||||
if ($requestId = $response->getHeaderLine('x-amz-request-id')) {
|
||||
$data['request_id'] = $requestId;
|
||||
$data['message'] .= " (Request-ID: $requestId)";
|
||||
}
|
||||
}
|
||||
|
||||
private function parseBody(\SimpleXMLElement $body, array &$data)
|
||||
{
|
||||
$data['parsed'] = $body;
|
||||
$prefix = $this->registerNamespacePrefix($body);
|
||||
|
||||
if ($tempXml = $body->xpath("//{$prefix}Code[1]")) {
|
||||
$data['code'] = (string) $tempXml[0];
|
||||
}
|
||||
|
||||
if ($tempXml = $body->xpath("//{$prefix}Message[1]")) {
|
||||
$data['message'] = (string) $tempXml[0];
|
||||
}
|
||||
|
||||
$tempXml = $body->xpath("//{$prefix}RequestId[1]");
|
||||
if (isset($tempXml[0])) {
|
||||
$data['request_id'] = (string)$tempXml[0];
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerNamespacePrefix(\SimpleXMLElement $element)
|
||||
{
|
||||
$namespaces = $element->getDocNamespaces();
|
||||
if (!isset($namespaces[''])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Account for the default namespace being defined and PHP not
|
||||
// being able to handle it :(.
|
||||
$element->registerXPathNamespace('ns', $namespaces['']);
|
||||
return 'ns:';
|
||||
}
|
||||
|
||||
protected function payload(
|
||||
ResponseInterface $response,
|
||||
StructureShape $member
|
||||
) {
|
||||
$xmlBody = $this->parseXml($response->getBody(), $response);
|
||||
$prefix = $this->registerNamespacePrefix($xmlBody);
|
||||
$errorBody = $xmlBody->xpath("//{$prefix}Error");
|
||||
|
||||
if (is_array($errorBody) && !empty($errorBody[0])) {
|
||||
return $this->parser->parse($member, $errorBody[0]);
|
||||
}
|
||||
}
|
||||
}
|
35
lib/aws-sdk/src/Api/ListShape.php
Normal file
35
lib/aws-sdk/src/Api/ListShape.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Represents a list shape.
|
||||
*/
|
||||
class ListShape extends Shape
|
||||
{
|
||||
private $member;
|
||||
|
||||
public function __construct(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
$definition['type'] = 'list';
|
||||
parent::__construct($definition, $shapeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Shape
|
||||
* @throws \RuntimeException if no member is specified
|
||||
*/
|
||||
public function getMember()
|
||||
{
|
||||
if (!$this->member) {
|
||||
if (!isset($this->definition['member'])) {
|
||||
throw new \RuntimeException('No member attribute specified');
|
||||
}
|
||||
$this->member = Shape::create(
|
||||
$this->definition['member'],
|
||||
$this->shapeMap
|
||||
);
|
||||
}
|
||||
|
||||
return $this->member;
|
||||
}
|
||||
}
|
54
lib/aws-sdk/src/Api/MapShape.php
Normal file
54
lib/aws-sdk/src/Api/MapShape.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Represents a map shape.
|
||||
*/
|
||||
class MapShape extends Shape
|
||||
{
|
||||
/** @var Shape */
|
||||
private $value;
|
||||
|
||||
/** @var Shape */
|
||||
private $key;
|
||||
|
||||
public function __construct(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
$definition['type'] = 'map';
|
||||
parent::__construct($definition, $shapeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Shape
|
||||
* @throws \RuntimeException if no value is specified
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
if (!$this->value) {
|
||||
if (!isset($this->definition['value'])) {
|
||||
throw new \RuntimeException('No value specified');
|
||||
}
|
||||
|
||||
$this->value = Shape::create(
|
||||
$this->definition['value'],
|
||||
$this->shapeMap
|
||||
);
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Shape
|
||||
*/
|
||||
public function getKey()
|
||||
{
|
||||
if (!$this->key) {
|
||||
$this->key = isset($this->definition['key'])
|
||||
? Shape::create($this->definition['key'], $this->shapeMap)
|
||||
: new Shape(['type' => 'string'], $this->shapeMap);
|
||||
}
|
||||
|
||||
return $this->key;
|
||||
}
|
||||
}
|
142
lib/aws-sdk/src/Api/Operation.php
Normal file
142
lib/aws-sdk/src/Api/Operation.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Represents an API operation.
|
||||
*/
|
||||
class Operation extends AbstractModel
|
||||
{
|
||||
private $input;
|
||||
private $output;
|
||||
private $errors;
|
||||
private $staticContextParams = [];
|
||||
private $contextParams;
|
||||
|
||||
public function __construct(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
$definition['type'] = 'structure';
|
||||
|
||||
if (!isset($definition['http']['method'])) {
|
||||
$definition['http']['method'] = 'POST';
|
||||
}
|
||||
|
||||
if (!isset($definition['http']['requestUri'])) {
|
||||
$definition['http']['requestUri'] = '/';
|
||||
}
|
||||
|
||||
if (isset($definition['staticContextParams'])) {
|
||||
$this->staticContextParams = $definition['staticContextParams'];
|
||||
}
|
||||
|
||||
parent::__construct($definition, $shapeMap);
|
||||
$this->contextParams = $this->setContextParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an associative array of the HTTP attribute of the operation:
|
||||
*
|
||||
* - method: HTTP method of the operation
|
||||
* - requestUri: URI of the request (can include URI template placeholders)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHttp()
|
||||
{
|
||||
return $this->definition['http'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the input shape of the operation.
|
||||
*
|
||||
* @return StructureShape
|
||||
*/
|
||||
public function getInput()
|
||||
{
|
||||
if (!$this->input) {
|
||||
if ($input = $this['input']) {
|
||||
$this->input = $this->shapeFor($input);
|
||||
} else {
|
||||
$this->input = new StructureShape([], $this->shapeMap);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the output shape of the operation.
|
||||
*
|
||||
* @return StructureShape
|
||||
*/
|
||||
public function getOutput()
|
||||
{
|
||||
if (!$this->output) {
|
||||
if ($output = $this['output']) {
|
||||
$this->output = $this->shapeFor($output);
|
||||
} else {
|
||||
$this->output = new StructureShape([], $this->shapeMap);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of operation error shapes.
|
||||
*
|
||||
* @return Shape[]
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
if ($this->errors === null) {
|
||||
if ($errors = $this['errors']) {
|
||||
foreach ($errors as $key => $error) {
|
||||
$errors[$key] = $this->shapeFor($error);
|
||||
}
|
||||
$this->errors = $errors;
|
||||
} else {
|
||||
$this->errors = [];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets static modeled static values used for
|
||||
* endpoint resolution.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStaticContextParams()
|
||||
{
|
||||
return $this->staticContextParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets definition of modeled dynamic values used
|
||||
* for endpoint resolution
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getContextParams()
|
||||
{
|
||||
return $this->contextParams;
|
||||
}
|
||||
|
||||
private function setContextParams()
|
||||
{
|
||||
$members = $this->getInput()->getMembers();
|
||||
$contextParams = [];
|
||||
|
||||
foreach($members as $name => $shape) {
|
||||
if (!empty($contextParam = $shape->getContextParam())) {
|
||||
$contextParams[$contextParam['name']] = [
|
||||
'shape' => $name,
|
||||
'type' => $shape->getType()
|
||||
];
|
||||
}
|
||||
}
|
||||
return $contextParams;
|
||||
}
|
||||
}
|
46
lib/aws-sdk/src/Api/Parser/AbstractParser.php
Normal file
46
lib/aws-sdk/src/Api/Parser/AbstractParser.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\CommandInterface;
|
||||
use Aws\ResultInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
abstract class AbstractParser
|
||||
{
|
||||
/** @var \Aws\Api\Service Representation of the service API*/
|
||||
protected $api;
|
||||
|
||||
/** @var callable */
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description.
|
||||
*/
|
||||
public function __construct(Service $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command Command that was executed.
|
||||
* @param ResponseInterface $response Response that was received.
|
||||
*
|
||||
* @return ResultInterface
|
||||
*/
|
||||
abstract public function __invoke(
|
||||
CommandInterface $command,
|
||||
ResponseInterface $response
|
||||
);
|
||||
|
||||
abstract public function parseMemberFromStream(
|
||||
StreamInterface $stream,
|
||||
StructureShape $member,
|
||||
$response
|
||||
);
|
||||
}
|
184
lib/aws-sdk/src/Api/Parser/AbstractRestParser.php
Normal file
184
lib/aws-sdk/src/Api/Parser/AbstractRestParser.php
Normal file
@ -0,0 +1,184 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\DateTimeResult;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Result;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
abstract class AbstractRestParser extends AbstractParser
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
/**
|
||||
* Parses a payload from a response.
|
||||
*
|
||||
* @param ResponseInterface $response Response to parse.
|
||||
* @param StructureShape $member Member to parse
|
||||
* @param array $result Result value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function payload(
|
||||
ResponseInterface $response,
|
||||
StructureShape $member,
|
||||
array &$result
|
||||
);
|
||||
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
$output = $this->api->getOperation($command->getName())->getOutput();
|
||||
$result = [];
|
||||
|
||||
if ($payload = $output['payload']) {
|
||||
$this->extractPayload($payload, $output, $response, $result);
|
||||
}
|
||||
|
||||
foreach ($output->getMembers() as $name => $member) {
|
||||
switch ($member['location']) {
|
||||
case 'header':
|
||||
$this->extractHeader($name, $member, $response, $result);
|
||||
break;
|
||||
case 'headers':
|
||||
$this->extractHeaders($name, $member, $response, $result);
|
||||
break;
|
||||
case 'statusCode':
|
||||
$this->extractStatus($name, $response, $result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$payload
|
||||
&& $response->getBody()->getSize() > 0
|
||||
&& count($output->getMembers()) > 0
|
||||
) {
|
||||
// if no payload was found, then parse the contents of the body
|
||||
$this->payload($response, $output, $result);
|
||||
}
|
||||
|
||||
return new Result($result);
|
||||
}
|
||||
|
||||
private function extractPayload(
|
||||
$payload,
|
||||
StructureShape $output,
|
||||
ResponseInterface $response,
|
||||
array &$result
|
||||
) {
|
||||
$member = $output->getMember($payload);
|
||||
|
||||
if (!empty($member['eventstream'])) {
|
||||
$result[$payload] = new EventParsingIterator(
|
||||
$response->getBody(),
|
||||
$member,
|
||||
$this
|
||||
);
|
||||
} else if ($member instanceof StructureShape) {
|
||||
// Structure members parse top-level data into a specific key.
|
||||
$result[$payload] = [];
|
||||
$this->payload($response, $member, $result[$payload]);
|
||||
} else {
|
||||
// Streaming data is just the stream from the response body.
|
||||
$result[$payload] = $response->getBody();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a single header from the response into the result.
|
||||
*/
|
||||
private function extractHeader(
|
||||
$name,
|
||||
Shape $shape,
|
||||
ResponseInterface $response,
|
||||
&$result
|
||||
) {
|
||||
$value = $response->getHeaderLine($shape['locationName'] ?: $name);
|
||||
|
||||
switch ($shape->getType()) {
|
||||
case 'float':
|
||||
case 'double':
|
||||
$value = (float) $value;
|
||||
break;
|
||||
case 'long':
|
||||
$value = (int) $value;
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
||||
break;
|
||||
case 'blob':
|
||||
$value = base64_decode($value);
|
||||
break;
|
||||
case 'timestamp':
|
||||
try {
|
||||
$value = DateTimeResult::fromTimestamp(
|
||||
$value,
|
||||
!empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null
|
||||
);
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
// If the value cannot be parsed, then do not add it to the
|
||||
// output structure.
|
||||
return;
|
||||
}
|
||||
case 'string':
|
||||
try {
|
||||
if ($shape['jsonvalue']) {
|
||||
$value = $this->parseJson(base64_decode($value), $response);
|
||||
}
|
||||
|
||||
// If value is not set, do not add to output structure.
|
||||
if (!isset($value)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
//If the value cannot be parsed, then do not add it to the
|
||||
//output structure.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$result[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a map of headers with an optional prefix from the response.
|
||||
*/
|
||||
private function extractHeaders(
|
||||
$name,
|
||||
Shape $shape,
|
||||
ResponseInterface $response,
|
||||
&$result
|
||||
) {
|
||||
// Check if the headers are prefixed by a location name
|
||||
$result[$name] = [];
|
||||
$prefix = $shape['locationName'];
|
||||
$prefixLen = $prefix !== null ? strlen($prefix) : 0;
|
||||
|
||||
foreach ($response->getHeaders() as $k => $values) {
|
||||
if (!$prefixLen) {
|
||||
$result[$name][$k] = implode(', ', $values);
|
||||
} elseif (stripos($k, $prefix) === 0) {
|
||||
$result[$name][substr($k, $prefixLen)] = implode(', ', $values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the status code of the response into the result array.
|
||||
*/
|
||||
private function extractStatus(
|
||||
$name,
|
||||
ResponseInterface $response,
|
||||
array &$result
|
||||
) {
|
||||
$result[$name] = (int) $response->getStatusCode();
|
||||
}
|
||||
}
|
54
lib/aws-sdk/src/Api/Parser/Crc32ValidatingParser.php
Normal file
54
lib/aws-sdk/src/Api/Parser/Crc32ValidatingParser.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\CommandInterface;
|
||||
use Aws\Exception\AwsException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use GuzzleHttp\Psr7;
|
||||
|
||||
/**
|
||||
* @internal Decorates a parser and validates the x-amz-crc32 header.
|
||||
*/
|
||||
class Crc32ValidatingParser extends AbstractParser
|
||||
{
|
||||
/**
|
||||
* @param callable $parser Parser to wrap.
|
||||
*/
|
||||
public function __construct(callable $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
if ($expected = $response->getHeaderLine('x-amz-crc32')) {
|
||||
$hash = hexdec(Psr7\Utils::hash($response->getBody(), 'crc32b'));
|
||||
if ($expected != $hash) {
|
||||
throw new AwsException(
|
||||
"crc32 mismatch. Expected {$expected}, found {$hash}.",
|
||||
$command,
|
||||
[
|
||||
'code' => 'ClientChecksumMismatch',
|
||||
'connection_error' => true,
|
||||
'response' => $response
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$fn = $this->parser;
|
||||
return $fn($command, $response);
|
||||
}
|
||||
|
||||
public function parseMemberFromStream(
|
||||
StreamInterface $stream,
|
||||
StructureShape $member,
|
||||
$response
|
||||
) {
|
||||
return $this->parser->parseMemberFromStream($stream, $member, $response);
|
||||
}
|
||||
}
|
340
lib/aws-sdk/src/Api/Parser/DecodingEventStreamIterator.php
Normal file
340
lib/aws-sdk/src/Api/Parser/DecodingEventStreamIterator.php
Normal file
@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use \Iterator;
|
||||
use Aws\Api\DateTimeResult;
|
||||
use GuzzleHttp\Psr7;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Aws\Api\Parser\Exception\ParserException;
|
||||
|
||||
/**
|
||||
* @internal Implements a decoder for a binary encoded event stream that will
|
||||
* decode, validate, and provide individual events from the stream.
|
||||
*/
|
||||
class DecodingEventStreamIterator implements Iterator
|
||||
{
|
||||
const HEADERS = 'headers';
|
||||
const PAYLOAD = 'payload';
|
||||
|
||||
const LENGTH_TOTAL = 'total_length';
|
||||
const LENGTH_HEADERS = 'headers_length';
|
||||
|
||||
const CRC_PRELUDE = 'prelude_crc';
|
||||
|
||||
const BYTES_PRELUDE = 12;
|
||||
const BYTES_TRAILING = 4;
|
||||
|
||||
private static $preludeFormat = [
|
||||
self::LENGTH_TOTAL => 'decodeUint32',
|
||||
self::LENGTH_HEADERS => 'decodeUint32',
|
||||
self::CRC_PRELUDE => 'decodeUint32',
|
||||
];
|
||||
|
||||
private static $lengthFormatMap = [
|
||||
1 => 'decodeUint8',
|
||||
2 => 'decodeUint16',
|
||||
4 => 'decodeUint32',
|
||||
8 => 'decodeUint64',
|
||||
];
|
||||
|
||||
private static $headerTypeMap = [
|
||||
0 => 'decodeBooleanTrue',
|
||||
1 => 'decodeBooleanFalse',
|
||||
2 => 'decodeInt8',
|
||||
3 => 'decodeInt16',
|
||||
4 => 'decodeInt32',
|
||||
5 => 'decodeInt64',
|
||||
6 => 'decodeBytes',
|
||||
7 => 'decodeString',
|
||||
8 => 'decodeTimestamp',
|
||||
9 => 'decodeUuid',
|
||||
];
|
||||
|
||||
/** @var StreamInterface Stream of eventstream shape to parse. */
|
||||
private $stream;
|
||||
|
||||
/** @var array Currently parsed event. */
|
||||
private $currentEvent;
|
||||
|
||||
/** @var int Current in-order event key. */
|
||||
private $key;
|
||||
|
||||
/** @var resource|\HashContext CRC32 hash context for event validation */
|
||||
private $hashContext;
|
||||
|
||||
/** @var int $currentPosition */
|
||||
private $currentPosition;
|
||||
|
||||
/**
|
||||
* DecodingEventStreamIterator constructor.
|
||||
*
|
||||
* @param StreamInterface $stream
|
||||
*/
|
||||
public function __construct(StreamInterface $stream)
|
||||
{
|
||||
$this->stream = $stream;
|
||||
$this->rewind();
|
||||
}
|
||||
|
||||
private function parseHeaders($headerBytes)
|
||||
{
|
||||
$headers = [];
|
||||
$bytesRead = 0;
|
||||
|
||||
while ($bytesRead < $headerBytes) {
|
||||
list($key, $numBytes) = $this->decodeString(1);
|
||||
$bytesRead += $numBytes;
|
||||
|
||||
list($type, $numBytes) = $this->decodeUint8();
|
||||
$bytesRead += $numBytes;
|
||||
|
||||
$f = self::$headerTypeMap[$type];
|
||||
list($value, $numBytes) = $this->{$f}();
|
||||
$bytesRead += $numBytes;
|
||||
|
||||
if (isset($headers[$key])) {
|
||||
throw new ParserException('Duplicate key in event headers.');
|
||||
}
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
|
||||
return [$headers, $bytesRead];
|
||||
}
|
||||
|
||||
private function parsePrelude()
|
||||
{
|
||||
$prelude = [];
|
||||
$bytesRead = 0;
|
||||
|
||||
$calculatedCrc = null;
|
||||
foreach (self::$preludeFormat as $key => $decodeFunction) {
|
||||
if ($key === self::CRC_PRELUDE) {
|
||||
$hashCopy = hash_copy($this->hashContext);
|
||||
$calculatedCrc = hash_final($this->hashContext, true);
|
||||
$this->hashContext = $hashCopy;
|
||||
}
|
||||
list($value, $numBytes) = $this->{$decodeFunction}();
|
||||
$bytesRead += $numBytes;
|
||||
|
||||
$prelude[$key] = $value;
|
||||
}
|
||||
|
||||
if (unpack('N', $calculatedCrc)[1] !== $prelude[self::CRC_PRELUDE]) {
|
||||
throw new ParserException('Prelude checksum mismatch.');
|
||||
}
|
||||
|
||||
return [$prelude, $bytesRead];
|
||||
}
|
||||
|
||||
private function parseEvent()
|
||||
{
|
||||
$event = [];
|
||||
|
||||
if ($this->stream->tell() < $this->stream->getSize()) {
|
||||
$this->hashContext = hash_init('crc32b');
|
||||
|
||||
$bytesLeft = $this->stream->getSize() - $this->stream->tell();
|
||||
list($prelude, $numBytes) = $this->parsePrelude();
|
||||
if ($prelude[self::LENGTH_TOTAL] > $bytesLeft) {
|
||||
throw new ParserException('Message length too long.');
|
||||
}
|
||||
$bytesLeft -= $numBytes;
|
||||
|
||||
if ($prelude[self::LENGTH_HEADERS] > $bytesLeft) {
|
||||
throw new ParserException('Headers length too long.');
|
||||
}
|
||||
|
||||
list(
|
||||
$event[self::HEADERS],
|
||||
$numBytes
|
||||
) = $this->parseHeaders($prelude[self::LENGTH_HEADERS]);
|
||||
|
||||
$event[self::PAYLOAD] = Psr7\Utils::streamFor(
|
||||
$this->readAndHashBytes(
|
||||
$prelude[self::LENGTH_TOTAL] - self::BYTES_PRELUDE
|
||||
- $numBytes - self::BYTES_TRAILING
|
||||
)
|
||||
);
|
||||
|
||||
$calculatedCrc = hash_final($this->hashContext, true);
|
||||
$messageCrc = $this->stream->read(4);
|
||||
if ($calculatedCrc !== $messageCrc) {
|
||||
throw new ParserException('Message checksum mismatch.');
|
||||
}
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
// Iterator Functionality
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->currentEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
$this->currentPosition = $this->stream->tell();
|
||||
if ($this->valid()) {
|
||||
$this->key++;
|
||||
$this->currentEvent = $this->parseEvent();
|
||||
}
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->stream->rewind();
|
||||
$this->key = 0;
|
||||
$this->currentPosition = 0;
|
||||
$this->currentEvent = $this->parseEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->currentPosition < $this->stream->getSize();
|
||||
}
|
||||
|
||||
// Decoding Utilities
|
||||
|
||||
private function readAndHashBytes($num)
|
||||
{
|
||||
$bytes = $this->stream->read($num);
|
||||
hash_update($this->hashContext, $bytes);
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
private function decodeBooleanTrue()
|
||||
{
|
||||
return [true, 0];
|
||||
}
|
||||
|
||||
private function decodeBooleanFalse()
|
||||
{
|
||||
return [false, 0];
|
||||
}
|
||||
|
||||
private function uintToInt($val, $size)
|
||||
{
|
||||
$signedCap = pow(2, $size - 1);
|
||||
if ($val > $signedCap) {
|
||||
$val -= (2 * $signedCap);
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
private function decodeInt8()
|
||||
{
|
||||
$val = (int)unpack('C', $this->readAndHashBytes(1))[1];
|
||||
return [$this->uintToInt($val, 8), 1];
|
||||
}
|
||||
|
||||
private function decodeUint8()
|
||||
{
|
||||
return [unpack('C', $this->readAndHashBytes(1))[1], 1];
|
||||
}
|
||||
|
||||
private function decodeInt16()
|
||||
{
|
||||
$val = (int)unpack('n', $this->readAndHashBytes(2))[1];
|
||||
return [$this->uintToInt($val, 16), 2];
|
||||
}
|
||||
|
||||
private function decodeUint16()
|
||||
{
|
||||
return [unpack('n', $this->readAndHashBytes(2))[1], 2];
|
||||
}
|
||||
|
||||
private function decodeInt32()
|
||||
{
|
||||
$val = (int)unpack('N', $this->readAndHashBytes(4))[1];
|
||||
return [$this->uintToInt($val, 32), 4];
|
||||
}
|
||||
|
||||
private function decodeUint32()
|
||||
{
|
||||
return [unpack('N', $this->readAndHashBytes(4))[1], 4];
|
||||
}
|
||||
|
||||
private function decodeInt64()
|
||||
{
|
||||
$val = $this->unpackInt64($this->readAndHashBytes(8))[1];
|
||||
return [$this->uintToInt($val, 64), 8];
|
||||
}
|
||||
|
||||
private function decodeUint64()
|
||||
{
|
||||
return [$this->unpackInt64($this->readAndHashBytes(8))[1], 8];
|
||||
}
|
||||
|
||||
private function unpackInt64($bytes)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.6.3', '<')) {
|
||||
$d = unpack('N2', $bytes);
|
||||
return [1 => $d[1] << 32 | $d[2]];
|
||||
}
|
||||
return unpack('J', $bytes);
|
||||
}
|
||||
|
||||
private function decodeBytes($lengthBytes=2)
|
||||
{
|
||||
if (!isset(self::$lengthFormatMap[$lengthBytes])) {
|
||||
throw new ParserException('Undefined variable length format.');
|
||||
}
|
||||
$f = self::$lengthFormatMap[$lengthBytes];
|
||||
list($len, $bytes) = $this->{$f}();
|
||||
return [$this->readAndHashBytes($len), $len + $bytes];
|
||||
}
|
||||
|
||||
private function decodeString($lengthBytes=2)
|
||||
{
|
||||
if (!isset(self::$lengthFormatMap[$lengthBytes])) {
|
||||
throw new ParserException('Undefined variable length format.');
|
||||
}
|
||||
$f = self::$lengthFormatMap[$lengthBytes];
|
||||
list($len, $bytes) = $this->{$f}();
|
||||
return [$this->readAndHashBytes($len), $len + $bytes];
|
||||
}
|
||||
|
||||
private function decodeTimestamp()
|
||||
{
|
||||
list($val, $bytes) = $this->decodeInt64();
|
||||
return [
|
||||
DateTimeResult::createFromFormat('U.u', $val / 1000),
|
||||
$bytes
|
||||
];
|
||||
}
|
||||
|
||||
private function decodeUuid()
|
||||
{
|
||||
$val = unpack('H32', $this->readAndHashBytes(16))[1];
|
||||
return [
|
||||
substr($val, 0, 8) . '-'
|
||||
. substr($val, 8, 4) . '-'
|
||||
. substr($val, 12, 4) . '-'
|
||||
. substr($val, 16, 4) . '-'
|
||||
. substr($val, 20, 12),
|
||||
16
|
||||
];
|
||||
}
|
||||
}
|
112
lib/aws-sdk/src/Api/Parser/EventParsingIterator.php
Normal file
112
lib/aws-sdk/src/Api/Parser/EventParsingIterator.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use \Iterator;
|
||||
use Aws\Exception\EventStreamDataException;
|
||||
use Aws\Api\Parser\Exception\ParserException;
|
||||
use Aws\Api\StructureShape;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal Implements a decoder for a binary encoded event stream that will
|
||||
* decode, validate, and provide individual events from the stream.
|
||||
*/
|
||||
class EventParsingIterator implements Iterator
|
||||
{
|
||||
/** @var StreamInterface */
|
||||
private $decodingIterator;
|
||||
|
||||
/** @var StructureShape */
|
||||
private $shape;
|
||||
|
||||
/** @var AbstractParser */
|
||||
private $parser;
|
||||
|
||||
public function __construct(
|
||||
StreamInterface $stream,
|
||||
StructureShape $shape,
|
||||
AbstractParser $parser
|
||||
) {
|
||||
$this->decodingIterator = new DecodingEventStreamIterator($stream);
|
||||
$this->shape = $shape;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function current()
|
||||
{
|
||||
return $this->parseEvent($this->decodingIterator->current());
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function key()
|
||||
{
|
||||
return $this->decodingIterator->key();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function next()
|
||||
{
|
||||
$this->decodingIterator->next();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function rewind()
|
||||
{
|
||||
$this->decodingIterator->rewind();
|
||||
}
|
||||
|
||||
#[\ReturnTypeWillChange]
|
||||
public function valid()
|
||||
{
|
||||
return $this->decodingIterator->valid();
|
||||
}
|
||||
|
||||
private function parseEvent(array $event)
|
||||
{
|
||||
if (!empty($event['headers'][':message-type'])) {
|
||||
if ($event['headers'][':message-type'] === 'error') {
|
||||
return $this->parseError($event);
|
||||
}
|
||||
if ($event['headers'][':message-type'] !== 'event') {
|
||||
throw new ParserException('Failed to parse unknown message type.');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($event['headers'][':event-type'])) {
|
||||
throw new ParserException('Failed to parse without event type.');
|
||||
}
|
||||
$eventShape = $this->shape->getMember($event['headers'][':event-type']);
|
||||
|
||||
$parsedEvent = [];
|
||||
foreach ($eventShape['members'] as $shape => $details) {
|
||||
if (!empty($details['eventpayload'])) {
|
||||
$payloadShape = $eventShape->getMember($shape);
|
||||
if ($payloadShape['type'] === 'blob') {
|
||||
$parsedEvent[$shape] = $event['payload'];
|
||||
} else {
|
||||
$parsedEvent[$shape] = $this->parser->parseMemberFromStream(
|
||||
$event['payload'],
|
||||
$payloadShape,
|
||||
null
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$parsedEvent[$shape] = $event['headers'][$shape];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
$event['headers'][':event-type'] => $parsedEvent
|
||||
];
|
||||
}
|
||||
|
||||
private function parseError(array $event)
|
||||
{
|
||||
throw new EventStreamDataException(
|
||||
$event['headers'][':error-code'],
|
||||
$event['headers'][':error-message']
|
||||
);
|
||||
}
|
||||
}
|
56
lib/aws-sdk/src/Api/Parser/Exception/ParserException.php
Normal file
56
lib/aws-sdk/src/Api/Parser/Exception/ParserException.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser\Exception;
|
||||
|
||||
use Aws\HasMonitoringEventsTrait;
|
||||
use Aws\MonitoringEventsInterface;
|
||||
use Aws\ResponseContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
class ParserException extends \RuntimeException implements
|
||||
MonitoringEventsInterface,
|
||||
ResponseContainerInterface
|
||||
{
|
||||
use HasMonitoringEventsTrait;
|
||||
|
||||
private $errorCode;
|
||||
private $requestId;
|
||||
private $response;
|
||||
|
||||
public function __construct($message = '', $code = 0, $previous = null, array $context = [])
|
||||
{
|
||||
$this->errorCode = isset($context['error_code']) ? $context['error_code'] : null;
|
||||
$this->requestId = isset($context['request_id']) ? $context['request_id'] : null;
|
||||
$this->response = isset($context['response']) ? $context['response'] : null;
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error code, if any.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getErrorCode()
|
||||
{
|
||||
return $this->errorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request ID, if any.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRequestId()
|
||||
{
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the received HTTP response if any.
|
||||
*
|
||||
* @return ResponseInterface|null
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
}
|
71
lib/aws-sdk/src/Api/Parser/JsonParser.php
Normal file
71
lib/aws-sdk/src/Api/Parser/JsonParser.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\DateTimeResult;
|
||||
use Aws\Api\Shape;
|
||||
|
||||
/**
|
||||
* @internal Implements standard JSON parsing.
|
||||
*/
|
||||
class JsonParser
|
||||
{
|
||||
public function parse(Shape $shape, $value)
|
||||
{
|
||||
if ($value === null) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
switch ($shape['type']) {
|
||||
case 'structure':
|
||||
if (isset($shape['document']) && $shape['document']) {
|
||||
return $value;
|
||||
}
|
||||
$target = [];
|
||||
foreach ($shape->getMembers() as $name => $member) {
|
||||
$locationName = $member['locationName'] ?: $name;
|
||||
if (isset($value[$locationName])) {
|
||||
$target[$name] = $this->parse($member, $value[$locationName]);
|
||||
}
|
||||
}
|
||||
if (isset($shape['union'])
|
||||
&& $shape['union']
|
||||
&& is_array($value)
|
||||
&& empty($target)
|
||||
) {
|
||||
foreach ($value as $key => $val) {
|
||||
$target['Unknown'][$key] = $val;
|
||||
}
|
||||
}
|
||||
return $target;
|
||||
|
||||
case 'list':
|
||||
$member = $shape->getMember();
|
||||
$target = [];
|
||||
foreach ($value as $v) {
|
||||
$target[] = $this->parse($member, $v);
|
||||
}
|
||||
return $target;
|
||||
|
||||
case 'map':
|
||||
$values = $shape->getValue();
|
||||
$target = [];
|
||||
foreach ($value as $k => $v) {
|
||||
$target[$k] = $this->parse($values, $v);
|
||||
}
|
||||
return $target;
|
||||
|
||||
case 'timestamp':
|
||||
return DateTimeResult::fromTimestamp(
|
||||
$value,
|
||||
!empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null
|
||||
);
|
||||
|
||||
case 'blob':
|
||||
return base64_decode($value);
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
lib/aws-sdk/src/Api/Parser/JsonRpcParser.php
Normal file
51
lib/aws-sdk/src/Api/Parser/JsonRpcParser.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Result;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal Implements JSON-RPC parsing (e.g., DynamoDB)
|
||||
*/
|
||||
class JsonRpcParser extends AbstractParser
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description
|
||||
* @param JsonParser $parser JSON body builder
|
||||
*/
|
||||
public function __construct(Service $api, JsonParser $parser = null)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->parser = $parser ?: new JsonParser();
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
$operation = $this->api->getOperation($command->getName());
|
||||
$result = null === $operation['output']
|
||||
? null
|
||||
: $this->parseMemberFromStream(
|
||||
$response->getBody(),
|
||||
$operation->getOutput(),
|
||||
$response
|
||||
);
|
||||
|
||||
return new Result($result ?: []);
|
||||
}
|
||||
|
||||
public function parseMemberFromStream(
|
||||
StreamInterface $stream,
|
||||
StructureShape $member,
|
||||
$response
|
||||
) {
|
||||
return $this->parser->parse($member, $this->parseJson($stream, $response));
|
||||
}
|
||||
}
|
90
lib/aws-sdk/src/Api/Parser/MetadataParserTrait.php
Normal file
90
lib/aws-sdk/src/Api/Parser/MetadataParserTrait.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\DateTimeResult;
|
||||
use Aws\Api\Shape;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
trait MetadataParserTrait
|
||||
{
|
||||
/**
|
||||
* Extract a single header from the response into the result.
|
||||
*/
|
||||
protected function extractHeader(
|
||||
$name,
|
||||
Shape $shape,
|
||||
ResponseInterface $response,
|
||||
&$result
|
||||
) {
|
||||
$value = $response->getHeaderLine($shape['locationName'] ?: $name);
|
||||
|
||||
switch ($shape->getType()) {
|
||||
case 'float':
|
||||
case 'double':
|
||||
$value = (float) $value;
|
||||
break;
|
||||
case 'long':
|
||||
$value = (int) $value;
|
||||
break;
|
||||
case 'boolean':
|
||||
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
||||
break;
|
||||
case 'blob':
|
||||
$value = base64_decode($value);
|
||||
break;
|
||||
case 'timestamp':
|
||||
try {
|
||||
$value = DateTimeResult::fromTimestamp(
|
||||
$value,
|
||||
!empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null
|
||||
);
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
// If the value cannot be parsed, then do not add it to the
|
||||
// output structure.
|
||||
return;
|
||||
}
|
||||
case 'string':
|
||||
if ($shape['jsonvalue']) {
|
||||
$value = $this->parseJson(base64_decode($value), $response);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$result[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a map of headers with an optional prefix from the response.
|
||||
*/
|
||||
protected function extractHeaders(
|
||||
$name,
|
||||
Shape $shape,
|
||||
ResponseInterface $response,
|
||||
&$result
|
||||
) {
|
||||
// Check if the headers are prefixed by a location name
|
||||
$result[$name] = [];
|
||||
$prefix = $shape['locationName'];
|
||||
$prefixLen = strlen($prefix);
|
||||
|
||||
foreach ($response->getHeaders() as $k => $values) {
|
||||
if (!$prefixLen) {
|
||||
$result[$name][$k] = implode(', ', $values);
|
||||
} elseif (stripos($k, $prefix) === 0) {
|
||||
$result[$name][substr($k, $prefixLen)] = implode(', ', $values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the status code of the response into the result array.
|
||||
*/
|
||||
protected function extractStatus(
|
||||
$name,
|
||||
ResponseInterface $response,
|
||||
array &$result
|
||||
) {
|
||||
$result[$name] = (int) $response->getStatusCode();
|
||||
}
|
||||
}
|
61
lib/aws-sdk/src/Api/Parser/PayloadParserTrait.php
Normal file
61
lib/aws-sdk/src/Api/Parser/PayloadParserTrait.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\Parser\Exception\ParserException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
trait PayloadParserTrait
|
||||
{
|
||||
/**
|
||||
* @param string $json
|
||||
*
|
||||
* @throws ParserException
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parseJson($json, $response)
|
||||
{
|
||||
$jsonPayload = json_decode($json, true);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new ParserException(
|
||||
'Error parsing JSON: ' . json_last_error_msg(),
|
||||
0,
|
||||
null,
|
||||
['response' => $response]
|
||||
);
|
||||
}
|
||||
|
||||
return $jsonPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $xml
|
||||
*
|
||||
* @throws ParserException
|
||||
*
|
||||
* @return \SimpleXMLElement
|
||||
*/
|
||||
protected function parseXml($xml, $response)
|
||||
{
|
||||
$priorSetting = libxml_use_internal_errors(true);
|
||||
try {
|
||||
libxml_clear_errors();
|
||||
$xmlPayload = new \SimpleXMLElement($xml);
|
||||
if ($error = libxml_get_last_error()) {
|
||||
throw new \RuntimeException($error->message);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new ParserException(
|
||||
"Error parsing XML: {$e->getMessage()}",
|
||||
0,
|
||||
$e,
|
||||
['response' => $response]
|
||||
);
|
||||
} finally {
|
||||
libxml_use_internal_errors($priorSetting);
|
||||
}
|
||||
|
||||
return $xmlPayload;
|
||||
}
|
||||
}
|
60
lib/aws-sdk/src/Api/Parser/QueryParser.php
Normal file
60
lib/aws-sdk/src/Api/Parser/QueryParser.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Result;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal Parses query (XML) responses (e.g., EC2, SQS, and many others)
|
||||
*/
|
||||
class QueryParser extends AbstractParser
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
/** @var bool */
|
||||
private $honorResultWrapper;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description
|
||||
* @param XmlParser $xmlParser Optional XML parser
|
||||
* @param bool $honorResultWrapper Set to false to disable the peeling
|
||||
* back of result wrappers from the
|
||||
* output structure.
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
XmlParser $xmlParser = null,
|
||||
$honorResultWrapper = true
|
||||
) {
|
||||
parent::__construct($api);
|
||||
$this->parser = $xmlParser ?: new XmlParser();
|
||||
$this->honorResultWrapper = $honorResultWrapper;
|
||||
}
|
||||
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
ResponseInterface $response
|
||||
) {
|
||||
$output = $this->api->getOperation($command->getName())->getOutput();
|
||||
$xml = $this->parseXml($response->getBody(), $response);
|
||||
|
||||
if ($this->honorResultWrapper && $output['resultWrapper']) {
|
||||
$xml = $xml->{$output['resultWrapper']};
|
||||
}
|
||||
|
||||
return new Result($this->parser->parse($output, $xml));
|
||||
}
|
||||
|
||||
public function parseMemberFromStream(
|
||||
StreamInterface $stream,
|
||||
StructureShape $member,
|
||||
$response
|
||||
) {
|
||||
$xml = $this->parseXml($stream, $response);
|
||||
return $this->parser->parse($member, $xml);
|
||||
}
|
||||
}
|
49
lib/aws-sdk/src/Api/Parser/RestJsonParser.php
Normal file
49
lib/aws-sdk/src/Api/Parser/RestJsonParser.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal Implements REST-JSON parsing (e.g., Glacier, Elastic Transcoder)
|
||||
*/
|
||||
class RestJsonParser extends AbstractRestParser
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description
|
||||
* @param JsonParser $parser JSON body builder
|
||||
*/
|
||||
public function __construct(Service $api, JsonParser $parser = null)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->parser = $parser ?: new JsonParser();
|
||||
}
|
||||
|
||||
protected function payload(
|
||||
ResponseInterface $response,
|
||||
StructureShape $member,
|
||||
array &$result
|
||||
) {
|
||||
$jsonBody = $this->parseJson($response->getBody(), $response);
|
||||
|
||||
if ($jsonBody) {
|
||||
$result += $this->parser->parse($member, $jsonBody);
|
||||
}
|
||||
}
|
||||
|
||||
public function parseMemberFromStream(
|
||||
StreamInterface $stream,
|
||||
StructureShape $member,
|
||||
$response
|
||||
) {
|
||||
$jsonBody = $this->parseJson($stream, $response);
|
||||
if ($jsonBody) {
|
||||
return $this->parser->parse($member, $jsonBody);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
42
lib/aws-sdk/src/Api/Parser/RestXmlParser.php
Normal file
42
lib/aws-sdk/src/Api/Parser/RestXmlParser.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\Service;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/**
|
||||
* @internal Implements REST-XML parsing (e.g., S3, CloudFront, etc...)
|
||||
*/
|
||||
class RestXmlParser extends AbstractRestParser
|
||||
{
|
||||
use PayloadParserTrait;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description
|
||||
* @param XmlParser $parser XML body parser
|
||||
*/
|
||||
public function __construct(Service $api, XmlParser $parser = null)
|
||||
{
|
||||
parent::__construct($api);
|
||||
$this->parser = $parser ?: new XmlParser();
|
||||
}
|
||||
|
||||
protected function payload(
|
||||
ResponseInterface $response,
|
||||
StructureShape $member,
|
||||
array &$result
|
||||
) {
|
||||
$result += $this->parseMemberFromStream($response->getBody(), $member, $response);
|
||||
}
|
||||
|
||||
public function parseMemberFromStream(
|
||||
StreamInterface $stream,
|
||||
StructureShape $member,
|
||||
$response
|
||||
) {
|
||||
$xml = $this->parseXml($stream, $response);
|
||||
return $this->parser->parse($member, $xml);
|
||||
}
|
||||
}
|
179
lib/aws-sdk/src/Api/Parser/XmlParser.php
Normal file
179
lib/aws-sdk/src/Api/Parser/XmlParser.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
namespace Aws\Api\Parser;
|
||||
|
||||
use Aws\Api\DateTimeResult;
|
||||
use Aws\Api\ListShape;
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Parser\Exception\ParserException;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\StructureShape;
|
||||
|
||||
/**
|
||||
* @internal Implements standard XML parsing for REST-XML and Query protocols.
|
||||
*/
|
||||
class XmlParser
|
||||
{
|
||||
public function parse(StructureShape $shape, \SimpleXMLElement $value)
|
||||
{
|
||||
return $this->dispatch($shape, $value);
|
||||
}
|
||||
|
||||
private function dispatch($shape, \SimpleXMLElement $value)
|
||||
{
|
||||
static $methods = [
|
||||
'structure' => 'parse_structure',
|
||||
'list' => 'parse_list',
|
||||
'map' => 'parse_map',
|
||||
'blob' => 'parse_blob',
|
||||
'boolean' => 'parse_boolean',
|
||||
'integer' => 'parse_integer',
|
||||
'float' => 'parse_float',
|
||||
'double' => 'parse_float',
|
||||
'timestamp' => 'parse_timestamp',
|
||||
];
|
||||
|
||||
$type = $shape['type'];
|
||||
if (isset($methods[$type])) {
|
||||
return $this->{$methods[$type]}($shape, $value);
|
||||
}
|
||||
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
private function parse_structure(
|
||||
StructureShape $shape,
|
||||
\SimpleXMLElement $value
|
||||
) {
|
||||
$target = [];
|
||||
|
||||
foreach ($shape->getMembers() as $name => $member) {
|
||||
// Extract the name of the XML node
|
||||
$node = $this->memberKey($member, $name);
|
||||
if (isset($value->{$node})) {
|
||||
$target[$name] = $this->dispatch($member, $value->{$node});
|
||||
} else {
|
||||
$memberShape = $shape->getMember($name);
|
||||
if (!empty($memberShape['xmlAttribute'])) {
|
||||
$target[$name] = $this->parse_xml_attribute(
|
||||
$shape,
|
||||
$memberShape,
|
||||
$value
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($shape['union'])
|
||||
&& $shape['union']
|
||||
&& empty($target)
|
||||
) {
|
||||
foreach ($value as $key => $val) {
|
||||
$name = $val->children()->getName();
|
||||
$target['Unknown'][$name] = $val->$name;
|
||||
}
|
||||
}
|
||||
return $target;
|
||||
}
|
||||
|
||||
private function memberKey(Shape $shape, $name)
|
||||
{
|
||||
if (null !== $shape['locationName']) {
|
||||
return $shape['locationName'];
|
||||
}
|
||||
|
||||
if ($shape instanceof ListShape && $shape['flattened']) {
|
||||
return $shape->getMember()['locationName'] ?: $name;
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function parse_list(ListShape $shape, \SimpleXMLElement $value)
|
||||
{
|
||||
$target = [];
|
||||
$member = $shape->getMember();
|
||||
|
||||
if (!$shape['flattened']) {
|
||||
$value = $value->{$member['locationName'] ?: 'member'};
|
||||
}
|
||||
|
||||
foreach ($value as $v) {
|
||||
$target[] = $this->dispatch($member, $v);
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
private function parse_map(MapShape $shape, \SimpleXMLElement $value)
|
||||
{
|
||||
$target = [];
|
||||
|
||||
if (!$shape['flattened']) {
|
||||
$value = $value->entry;
|
||||
}
|
||||
|
||||
$mapKey = $shape->getKey();
|
||||
$mapValue = $shape->getValue();
|
||||
$keyName = $shape->getKey()['locationName'] ?: 'key';
|
||||
$valueName = $shape->getValue()['locationName'] ?: 'value';
|
||||
|
||||
foreach ($value as $node) {
|
||||
$key = $this->dispatch($mapKey, $node->{$keyName});
|
||||
$value = $this->dispatch($mapValue, $node->{$valueName});
|
||||
$target[$key] = $value;
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
private function parse_blob(Shape $shape, $value)
|
||||
{
|
||||
return base64_decode((string) $value);
|
||||
}
|
||||
|
||||
private function parse_float(Shape $shape, $value)
|
||||
{
|
||||
return (float) (string) $value;
|
||||
}
|
||||
|
||||
private function parse_integer(Shape $shape, $value)
|
||||
{
|
||||
return (int) (string) $value;
|
||||
}
|
||||
|
||||
private function parse_boolean(Shape $shape, $value)
|
||||
{
|
||||
return $value == 'true';
|
||||
}
|
||||
|
||||
private function parse_timestamp(Shape $shape, $value)
|
||||
{
|
||||
if (is_string($value)
|
||||
|| is_int($value)
|
||||
|| (is_object($value)
|
||||
&& method_exists($value, '__toString'))
|
||||
) {
|
||||
return DateTimeResult::fromTimestamp(
|
||||
(string) $value,
|
||||
!empty($shape['timestampFormat']) ? $shape['timestampFormat'] : null
|
||||
);
|
||||
}
|
||||
throw new ParserException('Invalid timestamp value passed to XmlParser::parse_timestamp');
|
||||
}
|
||||
|
||||
private function parse_xml_attribute(Shape $shape, Shape $memberShape, $value)
|
||||
{
|
||||
$namespace = $shape['xmlNamespace']['uri']
|
||||
? $shape['xmlNamespace']['uri']
|
||||
: '';
|
||||
$prefix = $shape['xmlNamespace']['prefix']
|
||||
? $shape['xmlNamespace']['prefix']
|
||||
: '';
|
||||
if (!empty($prefix)) {
|
||||
$prefix .= ':';
|
||||
}
|
||||
$key = str_replace($prefix, '', $memberShape['locationName']);
|
||||
|
||||
$attributes = $value->attributes($namespace);
|
||||
return isset($attributes[$key]) ? (string) $attributes[$key] : null;
|
||||
}
|
||||
}
|
40
lib/aws-sdk/src/Api/Serializer/Ec2ParamBuilder.php
Normal file
40
lib/aws-sdk/src/Api/Serializer/Ec2ParamBuilder.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\ListShape;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Ec2ParamBuilder extends QueryParamBuilder
|
||||
{
|
||||
protected function queryName(Shape $shape, $default = null)
|
||||
{
|
||||
return ($shape['queryName']
|
||||
?: ucfirst(@$shape['locationName'] ?: ""))
|
||||
?: $default;
|
||||
}
|
||||
|
||||
protected function isFlat(Shape $shape)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function format_list(
|
||||
ListShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
&$query
|
||||
) {
|
||||
// Handle empty list serialization
|
||||
if (!$value) {
|
||||
$query[$prefix] = false;
|
||||
} else {
|
||||
$items = $shape->getMember();
|
||||
foreach ($value as $k => $v) {
|
||||
$this->format($items, $v, $prefix . '.' . ($k + 1), $query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
108
lib/aws-sdk/src/Api/Serializer/JsonBody.php
Normal file
108
lib/aws-sdk/src/Api/Serializer/JsonBody.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\TimestampShape;
|
||||
use Aws\Exception\InvalidJsonException;
|
||||
|
||||
/**
|
||||
* Formats the JSON body of a JSON-REST or JSON-RPC operation.
|
||||
* @internal
|
||||
*/
|
||||
class JsonBody
|
||||
{
|
||||
private $api;
|
||||
|
||||
public function __construct(Service $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the JSON Content-Type header for a service API
|
||||
*
|
||||
* @param Service $service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getContentType(Service $service)
|
||||
{
|
||||
if ($service->getMetadata('protocol') === 'rest-json') {
|
||||
return 'application/json';
|
||||
}
|
||||
|
||||
$jsonVersion = $service->getMetadata('jsonVersion');
|
||||
if (empty($jsonVersion)) {
|
||||
throw new \InvalidArgumentException('invalid json');
|
||||
} else {
|
||||
return 'application/x-amz-json-'
|
||||
. @number_format($service->getMetadata('jsonVersion'), 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JSON body based on an array of arguments.
|
||||
*
|
||||
* @param Shape $shape Operation being constructed
|
||||
* @param array $args Associative array of arguments
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function build(Shape $shape, array $args)
|
||||
{
|
||||
$result = json_encode($this->format($shape, $args));
|
||||
return $result == '[]' ? '{}' : $result;
|
||||
}
|
||||
|
||||
private function format(Shape $shape, $value)
|
||||
{
|
||||
switch ($shape['type']) {
|
||||
case 'structure':
|
||||
$data = [];
|
||||
if (isset($shape['document']) && $shape['document']) {
|
||||
return $value;
|
||||
}
|
||||
foreach ($value as $k => $v) {
|
||||
if ($v !== null && $shape->hasMember($k)) {
|
||||
$valueShape = $shape->getMember($k);
|
||||
$data[$valueShape['locationName'] ?: $k]
|
||||
= $this->format($valueShape, $v);
|
||||
}
|
||||
}
|
||||
if (empty($data)) {
|
||||
return new \stdClass;
|
||||
}
|
||||
return $data;
|
||||
|
||||
case 'list':
|
||||
$items = $shape->getMember();
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = $this->format($items, $v);
|
||||
}
|
||||
return $value;
|
||||
|
||||
case 'map':
|
||||
if (empty($value)) {
|
||||
return new \stdClass;
|
||||
}
|
||||
$values = $shape->getValue();
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = $this->format($values, $v);
|
||||
}
|
||||
return $value;
|
||||
|
||||
case 'blob':
|
||||
return base64_encode($value);
|
||||
|
||||
case 'timestamp':
|
||||
$timestampFormat = !empty($shape['timestampFormat'])
|
||||
? $shape['timestampFormat']
|
||||
: 'unixTimestamp';
|
||||
return TimestampShape::format($value, $timestampFormat);
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
92
lib/aws-sdk/src/Api/Serializer/JsonRpcSerializer.php
Normal file
92
lib/aws-sdk/src/Api/Serializer/JsonRpcSerializer.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\CommandInterface;
|
||||
use Aws\EndpointV2\EndpointProviderV2;
|
||||
use Aws\EndpointV2\EndpointV2SerializerTrait;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Prepares a JSON-RPC request for transfer.
|
||||
* @internal
|
||||
*/
|
||||
class JsonRpcSerializer
|
||||
{
|
||||
use EndpointV2SerializerTrait;
|
||||
|
||||
/** @var JsonBody */
|
||||
private $jsonFormatter;
|
||||
|
||||
/** @var string */
|
||||
private $endpoint;
|
||||
|
||||
/** @var Service */
|
||||
private $api;
|
||||
|
||||
/** @var string */
|
||||
private $contentType;
|
||||
|
||||
/**
|
||||
* @param Service $api Service description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
* @param JsonBody $jsonFormatter Optional JSON formatter to use
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
JsonBody $jsonFormatter = null
|
||||
) {
|
||||
$this->endpoint = $endpoint;
|
||||
$this->api = $api;
|
||||
$this->jsonFormatter = $jsonFormatter ?: new JsonBody($this->api);
|
||||
$this->contentType = JsonBody::getContentType($api);
|
||||
}
|
||||
|
||||
/**
|
||||
* When invoked with an AWS command, returns a serialization array
|
||||
* containing "method", "uri", "headers", and "body" key value pairs.
|
||||
*
|
||||
* @param CommandInterface $command Command to serialize into a request.
|
||||
* @param $endpointProvider Provider used for dynamic endpoint resolution.
|
||||
* @param $clientArgs Client arguments used for dynamic endpoint resolution.
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
$endpointProvider = null,
|
||||
$clientArgs = null
|
||||
)
|
||||
{
|
||||
$operationName = $command->getName();
|
||||
$operation = $this->api->getOperation($operationName);
|
||||
$commandArgs = $command->toArray();
|
||||
$headers = [
|
||||
'X-Amz-Target' => $this->api->getMetadata('targetPrefix') . '.' . $operationName,
|
||||
'Content-Type' => $this->contentType
|
||||
];
|
||||
|
||||
if ($endpointProvider instanceof EndpointProviderV2) {
|
||||
$this->setRequestOptions(
|
||||
$endpointProvider,
|
||||
$command,
|
||||
$operation,
|
||||
$commandArgs,
|
||||
$clientArgs,
|
||||
$headers
|
||||
);
|
||||
}
|
||||
|
||||
return new Request(
|
||||
$operation['http']['method'],
|
||||
$this->endpoint,
|
||||
$headers,
|
||||
$this->jsonFormatter->build(
|
||||
$operation->getInput(),
|
||||
$commandArgs
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
157
lib/aws-sdk/src/Api/Serializer/QueryParamBuilder.php
Normal file
157
lib/aws-sdk/src/Api/Serializer/QueryParamBuilder.php
Normal file
@ -0,0 +1,157 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\ListShape;
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\TimestampShape;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class QueryParamBuilder
|
||||
{
|
||||
private $methods;
|
||||
|
||||
protected function queryName(Shape $shape, $default = null)
|
||||
{
|
||||
if (null !== $shape['queryName']) {
|
||||
return $shape['queryName'];
|
||||
}
|
||||
|
||||
if (null !== $shape['locationName']) {
|
||||
return $shape['locationName'];
|
||||
}
|
||||
|
||||
if ($this->isFlat($shape) && !empty($shape['member']['locationName'])) {
|
||||
return $shape['member']['locationName'];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
protected function isFlat(Shape $shape)
|
||||
{
|
||||
return $shape['flattened'] === true;
|
||||
}
|
||||
|
||||
public function __invoke(StructureShape $shape, array $params)
|
||||
{
|
||||
if (!$this->methods) {
|
||||
$this->methods = array_fill_keys(get_class_methods($this), true);
|
||||
}
|
||||
|
||||
$query = [];
|
||||
$this->format_structure($shape, $params, '', $query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
protected function format(Shape $shape, $value, $prefix, array &$query)
|
||||
{
|
||||
$type = 'format_' . $shape['type'];
|
||||
if (isset($this->methods[$type])) {
|
||||
$this->{$type}($shape, $value, $prefix, $query);
|
||||
} else {
|
||||
$query[$prefix] = (string) $value;
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_structure(
|
||||
StructureShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
&$query
|
||||
) {
|
||||
if ($prefix) {
|
||||
$prefix .= '.';
|
||||
}
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
if ($shape->hasMember($k)) {
|
||||
$member = $shape->getMember($k);
|
||||
$this->format(
|
||||
$member,
|
||||
$v,
|
||||
$prefix . $this->queryName($member, $k),
|
||||
$query
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_list(
|
||||
ListShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
&$query
|
||||
) {
|
||||
// Handle empty list serialization
|
||||
if (!$value) {
|
||||
$query[$prefix] = '';
|
||||
return;
|
||||
}
|
||||
|
||||
$items = $shape->getMember();
|
||||
|
||||
if (!$this->isFlat($shape)) {
|
||||
$locationName = $shape->getMember()['locationName'] ?: 'member';
|
||||
$prefix .= ".$locationName";
|
||||
} elseif ($name = $this->queryName($items)) {
|
||||
$parts = explode('.', $prefix);
|
||||
$parts[count($parts) - 1] = $name;
|
||||
$prefix = implode('.', $parts);
|
||||
}
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
$this->format($items, $v, $prefix . '.' . ($k + 1), $query);
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_map(
|
||||
MapShape $shape,
|
||||
array $value,
|
||||
$prefix,
|
||||
array &$query
|
||||
) {
|
||||
$vals = $shape->getValue();
|
||||
$keys = $shape->getKey();
|
||||
|
||||
if (!$this->isFlat($shape)) {
|
||||
$prefix .= '.entry';
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
$keyName = '%s.%d.' . $this->queryName($keys, 'key');
|
||||
$valueName = '%s.%s.' . $this->queryName($vals, 'value');
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
$i++;
|
||||
$this->format($keys, $k, sprintf($keyName, $prefix, $i), $query);
|
||||
$this->format($vals, $v, sprintf($valueName, $prefix, $i), $query);
|
||||
}
|
||||
}
|
||||
|
||||
protected function format_blob(Shape $shape, $value, $prefix, array &$query)
|
||||
{
|
||||
$query[$prefix] = base64_encode($value);
|
||||
}
|
||||
|
||||
protected function format_timestamp(
|
||||
TimestampShape $shape,
|
||||
$value,
|
||||
$prefix,
|
||||
array &$query
|
||||
) {
|
||||
$timestampFormat = !empty($shape['timestampFormat'])
|
||||
? $shape['timestampFormat']
|
||||
: 'iso8601';
|
||||
$query[$prefix] = TimestampShape::format($value, $timestampFormat);
|
||||
}
|
||||
|
||||
protected function format_boolean(Shape $shape, $value, $prefix, array &$query)
|
||||
{
|
||||
$query[$prefix] = ($value) ? 'true' : 'false';
|
||||
}
|
||||
}
|
88
lib/aws-sdk/src/Api/Serializer/QuerySerializer.php
Normal file
88
lib/aws-sdk/src/Api/Serializer/QuerySerializer.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\CommandInterface;
|
||||
use Aws\EndpointV2\EndpointProviderV2;
|
||||
use Aws\EndpointV2\EndpointV2SerializerTrait;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Serializes a query protocol request.
|
||||
* @internal
|
||||
*/
|
||||
class QuerySerializer
|
||||
{
|
||||
use EndpointV2SerializerTrait;
|
||||
|
||||
private $endpoint;
|
||||
private $api;
|
||||
private $paramBuilder;
|
||||
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
callable $paramBuilder = null
|
||||
) {
|
||||
$this->api = $api;
|
||||
$this->endpoint = $endpoint;
|
||||
$this->paramBuilder = $paramBuilder ?: new QueryParamBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* When invoked with an AWS command, returns a serialization array
|
||||
* containing "method", "uri", "headers", and "body" key value pairs.
|
||||
*
|
||||
* @param CommandInterface $command Command to serialize into a request.
|
||||
* @param $endpointProvider Provider used for dynamic endpoint resolution.
|
||||
* @param $clientArgs Client arguments used for dynamic endpoint resolution.
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
$endpointProvider = null,
|
||||
$clientArgs = null
|
||||
)
|
||||
{
|
||||
$operation = $this->api->getOperation($command->getName());
|
||||
$body = [
|
||||
'Action' => $command->getName(),
|
||||
'Version' => $this->api->getMetadata('apiVersion')
|
||||
];
|
||||
$commandArgs = $command->toArray();
|
||||
|
||||
// Only build up the parameters when there are parameters to build
|
||||
if ($commandArgs) {
|
||||
$body += call_user_func(
|
||||
$this->paramBuilder,
|
||||
$operation->getInput(),
|
||||
$commandArgs
|
||||
);
|
||||
}
|
||||
$body = http_build_query($body, '', '&', PHP_QUERY_RFC3986);
|
||||
$headers = [
|
||||
'Content-Length' => strlen($body),
|
||||
'Content-Type' => 'application/x-www-form-urlencoded'
|
||||
];
|
||||
|
||||
if ($endpointProvider instanceof EndpointProviderV2) {
|
||||
$this->setRequestOptions(
|
||||
$endpointProvider,
|
||||
$command,
|
||||
$operation,
|
||||
$commandArgs,
|
||||
$clientArgs,
|
||||
$headers
|
||||
);
|
||||
}
|
||||
|
||||
return new Request(
|
||||
'POST',
|
||||
$this->endpoint,
|
||||
$headers,
|
||||
$body
|
||||
);
|
||||
}
|
||||
}
|
42
lib/aws-sdk/src/Api/Serializer/RestJsonSerializer.php
Normal file
42
lib/aws-sdk/src/Api/Serializer/RestJsonSerializer.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\StructureShape;
|
||||
|
||||
/**
|
||||
* Serializes requests for the REST-JSON protocol.
|
||||
* @internal
|
||||
*/
|
||||
class RestJsonSerializer extends RestSerializer
|
||||
{
|
||||
/** @var JsonBody */
|
||||
private $jsonFormatter;
|
||||
|
||||
/** @var string */
|
||||
private $contentType;
|
||||
|
||||
/**
|
||||
* @param Service $api Service API description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
* @param JsonBody $jsonFormatter Optional JSON formatter to use
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
JsonBody $jsonFormatter = null
|
||||
) {
|
||||
parent::__construct($api, $endpoint);
|
||||
$this->contentType = JsonBody::getContentType($api);
|
||||
$this->jsonFormatter = $jsonFormatter ?: new JsonBody($api);
|
||||
}
|
||||
|
||||
protected function payload(StructureShape $member, array $value, array &$opts)
|
||||
{
|
||||
$body = isset($value) ?
|
||||
((string) $this->jsonFormatter->build($member, $value))
|
||||
: "{}";
|
||||
$opts['headers']['Content-Type'] = $this->contentType;
|
||||
$opts['body'] = $body;
|
||||
}
|
||||
}
|
307
lib/aws-sdk/src/Api/Serializer/RestSerializer.php
Normal file
307
lib/aws-sdk/src/Api/Serializer/RestSerializer.php
Normal file
@ -0,0 +1,307 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\Operation;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\TimestampShape;
|
||||
use Aws\CommandInterface;
|
||||
use Aws\EndpointV2\EndpointProviderV2;
|
||||
use Aws\EndpointV2\EndpointV2SerializerTrait;
|
||||
use GuzzleHttp\Psr7;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use GuzzleHttp\Psr7\UriResolver;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* Serializes HTTP locations like header, uri, payload, etc...
|
||||
* @internal
|
||||
*/
|
||||
abstract class RestSerializer
|
||||
{
|
||||
use EndpointV2SerializerTrait;
|
||||
|
||||
/** @var Service */
|
||||
private $api;
|
||||
|
||||
/** @var Uri */
|
||||
private $endpoint;
|
||||
|
||||
/**
|
||||
* @param Service $api Service API description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
*/
|
||||
public function __construct(Service $api, $endpoint)
|
||||
{
|
||||
$this->api = $api;
|
||||
$this->endpoint = Psr7\Utils::uriFor($endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandInterface $command Command to serialize into a request.
|
||||
* @param $endpointProvider Provider used for dynamic endpoint resolution.
|
||||
* @param $clientArgs Client arguments used for dynamic endpoint resolution.
|
||||
*
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function __invoke(
|
||||
CommandInterface $command,
|
||||
$endpointProvider = null,
|
||||
$clientArgs = null
|
||||
)
|
||||
{
|
||||
$operation = $this->api->getOperation($command->getName());
|
||||
$commandArgs = $command->toArray();
|
||||
$opts = $this->serialize($operation, $commandArgs);
|
||||
$headers = isset($opts['headers']) ? $opts['headers'] : [];
|
||||
|
||||
if ($endpointProvider instanceof EndpointProviderV2) {
|
||||
$this->setRequestOptions(
|
||||
$endpointProvider,
|
||||
$command,
|
||||
$operation,
|
||||
$commandArgs,
|
||||
$clientArgs,
|
||||
$headers
|
||||
);
|
||||
$this->endpoint = new Uri($this->endpoint);
|
||||
}
|
||||
$uri = $this->buildEndpoint($operation, $commandArgs, $opts);
|
||||
|
||||
return new Request(
|
||||
$operation['http']['method'],
|
||||
$uri,
|
||||
$headers,
|
||||
isset($opts['body']) ? $opts['body'] : null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies a hash of request options for a payload body.
|
||||
*
|
||||
* @param StructureShape $member Member to serialize
|
||||
* @param array $value Value to serialize
|
||||
* @param array $opts Request options to modify.
|
||||
*/
|
||||
abstract protected function payload(
|
||||
StructureShape $member,
|
||||
array $value,
|
||||
array &$opts
|
||||
);
|
||||
|
||||
private function serialize(Operation $operation, array $args)
|
||||
{
|
||||
$opts = [];
|
||||
$input = $operation->getInput();
|
||||
|
||||
// Apply the payload trait if present
|
||||
if ($payload = $input['payload']) {
|
||||
$this->applyPayload($input, $payload, $args, $opts);
|
||||
}
|
||||
|
||||
foreach ($args as $name => $value) {
|
||||
if ($input->hasMember($name)) {
|
||||
$member = $input->getMember($name);
|
||||
$location = $member['location'];
|
||||
if (!$payload && !$location) {
|
||||
$bodyMembers[$name] = $value;
|
||||
} elseif ($location == 'header') {
|
||||
$this->applyHeader($name, $member, $value, $opts);
|
||||
} elseif ($location == 'querystring') {
|
||||
$this->applyQuery($name, $member, $value, $opts);
|
||||
} elseif ($location == 'headers') {
|
||||
$this->applyHeaderMap($name, $member, $value, $opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($bodyMembers)) {
|
||||
$this->payload($operation->getInput(), $bodyMembers, $opts);
|
||||
} else if (!isset($opts['body']) && $this->hasPayloadParam($input, $payload)) {
|
||||
$this->payload($operation->getInput(), [], $opts);
|
||||
}
|
||||
|
||||
return $opts;
|
||||
}
|
||||
|
||||
private function applyPayload(StructureShape $input, $name, array $args, array &$opts)
|
||||
{
|
||||
if (!isset($args[$name])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$m = $input->getMember($name);
|
||||
|
||||
if ($m['streaming'] ||
|
||||
($m['type'] == 'string' || $m['type'] == 'blob')
|
||||
) {
|
||||
// Streaming bodies or payloads that are strings are
|
||||
// always just a stream of data.
|
||||
$opts['body'] = Psr7\Utils::streamFor($args[$name]);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->payload($m, $args[$name], $opts);
|
||||
}
|
||||
|
||||
private function applyHeader($name, Shape $member, $value, array &$opts)
|
||||
{
|
||||
if ($member->getType() === 'timestamp') {
|
||||
$timestampFormat = !empty($member['timestampFormat'])
|
||||
? $member['timestampFormat']
|
||||
: 'rfc822';
|
||||
$value = TimestampShape::format($value, $timestampFormat);
|
||||
} elseif ($member->getType() === 'boolean') {
|
||||
$value = $value ? 'true' : 'false';
|
||||
}
|
||||
|
||||
if ($member['jsonvalue']) {
|
||||
$value = json_encode($value);
|
||||
if (empty($value) && JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new \InvalidArgumentException('Unable to encode the provided value'
|
||||
. ' with \'json_encode\'. ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
$value = base64_encode($value);
|
||||
}
|
||||
|
||||
$opts['headers'][$member['locationName'] ?: $name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This is currently only present in the Amazon S3 model.
|
||||
*/
|
||||
private function applyHeaderMap($name, Shape $member, array $value, array &$opts)
|
||||
{
|
||||
$prefix = $member['locationName'];
|
||||
foreach ($value as $k => $v) {
|
||||
$opts['headers'][$prefix . $k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
private function applyQuery($name, Shape $member, $value, array &$opts)
|
||||
{
|
||||
if ($member instanceof MapShape) {
|
||||
$opts['query'] = isset($opts['query']) && is_array($opts['query'])
|
||||
? $opts['query'] + $value
|
||||
: $value;
|
||||
} elseif ($value !== null) {
|
||||
$type = $member->getType();
|
||||
if ($type === 'boolean') {
|
||||
$value = $value ? 'true' : 'false';
|
||||
} elseif ($type === 'timestamp') {
|
||||
$timestampFormat = !empty($member['timestampFormat'])
|
||||
? $member['timestampFormat']
|
||||
: 'iso8601';
|
||||
$value = TimestampShape::format($value, $timestampFormat);
|
||||
}
|
||||
|
||||
$opts['query'][$member['locationName'] ?: $name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
private function buildEndpoint(Operation $operation, array $args, array $opts)
|
||||
{
|
||||
// Create an associative array of variable definitions used in expansions
|
||||
$varDefinitions = $this->getVarDefinitions($operation, $args);
|
||||
|
||||
$relative = preg_replace_callback(
|
||||
'/\{([^\}]+)\}/',
|
||||
function (array $matches) use ($varDefinitions) {
|
||||
$isGreedy = substr($matches[1], -1, 1) == '+';
|
||||
$k = $isGreedy ? substr($matches[1], 0, -1) : $matches[1];
|
||||
if (!isset($varDefinitions[$k])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($isGreedy) {
|
||||
return str_replace('%2F', '/', rawurlencode($varDefinitions[$k]));
|
||||
}
|
||||
|
||||
return rawurlencode($varDefinitions[$k]);
|
||||
},
|
||||
$operation['http']['requestUri']
|
||||
);
|
||||
|
||||
// Add the query string variables or appending to one if needed.
|
||||
if (!empty($opts['query'])) {
|
||||
$relative = $this->appendQuery($opts['query'], $relative);
|
||||
}
|
||||
|
||||
$path = $this->endpoint->getPath();
|
||||
|
||||
//Accounts for trailing '/' in path when custom endpoint
|
||||
//is provided to endpointProviderV2
|
||||
if ($this->api->isModifiedModel()
|
||||
&& $this->api->getServiceName() === 's3'
|
||||
) {
|
||||
if (substr($path, -1) === '/' && $relative[0] === '/') {
|
||||
$path = rtrim($path, '/');
|
||||
}
|
||||
$relative = $path . $relative;
|
||||
}
|
||||
// If endpoint has path, remove leading '/' to preserve URI resolution.
|
||||
if ($path && $relative[0] === '/') {
|
||||
$relative = substr($relative, 1);
|
||||
}
|
||||
|
||||
//Append path to endpoint when leading '//...' present
|
||||
// as uri cannot be properly resolved
|
||||
if ($this->api->isModifiedModel()
|
||||
&& strpos($relative, '//') === 0
|
||||
) {
|
||||
return new Uri($this->endpoint . $relative);
|
||||
}
|
||||
|
||||
// Expand path place holders using Amazon's slightly different URI
|
||||
// template syntax.
|
||||
return UriResolver::resolve($this->endpoint, new Uri($relative));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StructureShape $input
|
||||
*/
|
||||
private function hasPayloadParam(StructureShape $input, $payload)
|
||||
{
|
||||
if ($payload) {
|
||||
$potentiallyEmptyTypes = ['blob','string'];
|
||||
if ($this->api->getMetadata('protocol') == 'rest-xml') {
|
||||
$potentiallyEmptyTypes[] = 'structure';
|
||||
}
|
||||
$payloadMember = $input->getMember($payload);
|
||||
if (in_array($payloadMember['type'], $potentiallyEmptyTypes)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach ($input->getMembers() as $member) {
|
||||
if (!isset($member['location'])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function appendQuery($query, $endpoint)
|
||||
{
|
||||
$append = Psr7\Query::build($query);
|
||||
return $endpoint .= strpos($endpoint, '?') !== false ? "&{$append}" : "?{$append}";
|
||||
}
|
||||
|
||||
private function getVarDefinitions($command, $args)
|
||||
{
|
||||
$varDefinitions = [];
|
||||
|
||||
foreach ($command->getInput()->getMembers() as $name => $member) {
|
||||
if ($member['location'] == 'uri') {
|
||||
$varDefinitions[$member['locationName'] ?: $name] =
|
||||
isset($args[$name])
|
||||
? $args[$name]
|
||||
: null;
|
||||
}
|
||||
}
|
||||
return $varDefinitions;
|
||||
}
|
||||
}
|
48
lib/aws-sdk/src/Api/Serializer/RestXmlSerializer.php
Normal file
48
lib/aws-sdk/src/Api/Serializer/RestXmlSerializer.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\Service;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class RestXmlSerializer extends RestSerializer
|
||||
{
|
||||
/** @var XmlBody */
|
||||
private $xmlBody;
|
||||
|
||||
/**
|
||||
* @param Service $api Service API description
|
||||
* @param string $endpoint Endpoint to connect to
|
||||
* @param XmlBody $xmlBody Optional XML formatter to use
|
||||
*/
|
||||
public function __construct(
|
||||
Service $api,
|
||||
$endpoint,
|
||||
XmlBody $xmlBody = null
|
||||
) {
|
||||
parent::__construct($api, $endpoint);
|
||||
$this->xmlBody = $xmlBody ?: new XmlBody($api);
|
||||
}
|
||||
|
||||
protected function payload(StructureShape $member, array $value, array &$opts)
|
||||
{
|
||||
$opts['headers']['Content-Type'] = 'application/xml';
|
||||
$opts['body'] = $this->getXmlBody($member, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StructureShape $member
|
||||
* @param array $value
|
||||
* @return string
|
||||
*/
|
||||
private function getXmlBody(StructureShape $member, array $value)
|
||||
{
|
||||
$xmlBody = (string)$this->xmlBody->build($member, $value);
|
||||
$xmlBody = str_replace("'", "'", $xmlBody);
|
||||
$xmlBody = str_replace('\r', " ", $xmlBody);
|
||||
$xmlBody = str_replace('\n', " ", $xmlBody);
|
||||
return $xmlBody;
|
||||
}
|
||||
}
|
220
lib/aws-sdk/src/Api/Serializer/XmlBody.php
Normal file
220
lib/aws-sdk/src/Api/Serializer/XmlBody.php
Normal file
@ -0,0 +1,220 @@
|
||||
<?php
|
||||
namespace Aws\Api\Serializer;
|
||||
|
||||
use Aws\Api\MapShape;
|
||||
use Aws\Api\Service;
|
||||
use Aws\Api\Shape;
|
||||
use Aws\Api\StructureShape;
|
||||
use Aws\Api\ListShape;
|
||||
use Aws\Api\TimestampShape;
|
||||
use XMLWriter;
|
||||
|
||||
/**
|
||||
* @internal Formats the XML body of a REST-XML services.
|
||||
*/
|
||||
class XmlBody
|
||||
{
|
||||
/** @var \Aws\Api\Service */
|
||||
private $api;
|
||||
|
||||
/**
|
||||
* @param Service $api API being used to create the XML body.
|
||||
*/
|
||||
public function __construct(Service $api)
|
||||
{
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the XML body based on an array of arguments.
|
||||
*
|
||||
* @param Shape $shape Operation being constructed
|
||||
* @param array $args Associative array of arguments
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function build(Shape $shape, array $args)
|
||||
{
|
||||
$xml = new XMLWriter();
|
||||
$xml->openMemory();
|
||||
$xml->startDocument('1.0', 'UTF-8');
|
||||
$this->format($shape, $shape['locationName'] ?: $shape['name'], $args, $xml);
|
||||
$xml->endDocument();
|
||||
|
||||
return $xml->outputMemory();
|
||||
}
|
||||
|
||||
private function startElement(Shape $shape, $name, XMLWriter $xml)
|
||||
{
|
||||
$xml->startElement($name);
|
||||
|
||||
if ($ns = $shape['xmlNamespace']) {
|
||||
$xml->writeAttribute(
|
||||
isset($ns['prefix']) ? "xmlns:{$ns['prefix']}" : 'xmlns',
|
||||
$shape['xmlNamespace']['uri']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function format(Shape $shape, $name, $value, XMLWriter $xml)
|
||||
{
|
||||
// Any method mentioned here has a custom serialization handler.
|
||||
static $methods = [
|
||||
'add_structure' => true,
|
||||
'add_list' => true,
|
||||
'add_blob' => true,
|
||||
'add_timestamp' => true,
|
||||
'add_boolean' => true,
|
||||
'add_map' => true,
|
||||
'add_string' => true
|
||||
];
|
||||
|
||||
$type = 'add_' . $shape['type'];
|
||||
if (isset($methods[$type])) {
|
||||
$this->{$type}($shape, $name, $value, $xml);
|
||||
} else {
|
||||
$this->defaultShape($shape, $name, $value, $xml);
|
||||
}
|
||||
}
|
||||
|
||||
private function defaultShape(Shape $shape, $name, $value, XMLWriter $xml)
|
||||
{
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->text($value);
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_structure(
|
||||
StructureShape $shape,
|
||||
$name,
|
||||
array $value,
|
||||
\XMLWriter $xml
|
||||
) {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
|
||||
foreach ($this->getStructureMembers($shape, $value) as $k => $definition) {
|
||||
$this->format(
|
||||
$definition['member'],
|
||||
$definition['member']['locationName'] ?: $k,
|
||||
$definition['value'],
|
||||
$xml
|
||||
);
|
||||
}
|
||||
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function getStructureMembers(StructureShape $shape, array $value)
|
||||
{
|
||||
$members = [];
|
||||
|
||||
foreach ($value as $k => $v) {
|
||||
if ($v !== null && $shape->hasMember($k)) {
|
||||
$definition = [
|
||||
'member' => $shape->getMember($k),
|
||||
'value' => $v,
|
||||
];
|
||||
|
||||
if ($definition['member']['xmlAttribute']) {
|
||||
// array_unshift_associative
|
||||
$members = [$k => $definition] + $members;
|
||||
} else {
|
||||
$members[$k] = $definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $members;
|
||||
}
|
||||
|
||||
private function add_list(
|
||||
ListShape $shape,
|
||||
$name,
|
||||
array $value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$items = $shape->getMember();
|
||||
|
||||
if ($shape['flattened']) {
|
||||
$elementName = $name;
|
||||
} else {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$elementName = $items['locationName'] ?: 'member';
|
||||
}
|
||||
|
||||
foreach ($value as $v) {
|
||||
$this->format($items, $elementName, $v, $xml);
|
||||
}
|
||||
|
||||
if (!$shape['flattened']) {
|
||||
$xml->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
private function add_map(
|
||||
MapShape $shape,
|
||||
$name,
|
||||
array $value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$xmlEntry = $shape['flattened'] ? $shape['locationName'] : 'entry';
|
||||
$xmlKey = $shape->getKey()['locationName'] ?: 'key';
|
||||
$xmlValue = $shape->getValue()['locationName'] ?: 'value';
|
||||
|
||||
$this->startElement($shape, $name, $xml);
|
||||
|
||||
foreach ($value as $key => $v) {
|
||||
$this->startElement($shape, $xmlEntry, $xml);
|
||||
$this->format($shape->getKey(), $xmlKey, $key, $xml);
|
||||
$this->format($shape->getValue(), $xmlValue, $v, $xml);
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_blob(Shape $shape, $name, $value, XMLWriter $xml)
|
||||
{
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->writeRaw(base64_encode($value));
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_timestamp(
|
||||
TimestampShape $shape,
|
||||
$name,
|
||||
$value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$timestampFormat = !empty($shape['timestampFormat'])
|
||||
? $shape['timestampFormat']
|
||||
: 'iso8601';
|
||||
$xml->writeRaw(TimestampShape::format($value, $timestampFormat));
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_boolean(
|
||||
Shape $shape,
|
||||
$name,
|
||||
$value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
$this->startElement($shape, $name, $xml);
|
||||
$xml->writeRaw($value ? 'true' : 'false');
|
||||
$xml->endElement();
|
||||
}
|
||||
|
||||
private function add_string(
|
||||
Shape $shape,
|
||||
$name,
|
||||
$value,
|
||||
XMLWriter $xml
|
||||
) {
|
||||
if ($shape['xmlAttribute']) {
|
||||
$xml->writeAttribute($shape['locationName'] ?: $name, $value);
|
||||
} else {
|
||||
$this->defaultShape($shape, $name, $value, $xml);
|
||||
}
|
||||
}
|
||||
}
|
535
lib/aws-sdk/src/Api/Service.php
Normal file
535
lib/aws-sdk/src/Api/Service.php
Normal file
@ -0,0 +1,535 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Represents a web service API model.
|
||||
*/
|
||||
class Service extends AbstractModel
|
||||
{
|
||||
/** @var callable */
|
||||
private $apiProvider;
|
||||
|
||||
/** @var string */
|
||||
private $serviceName;
|
||||
|
||||
/** @var string */
|
||||
private $apiVersion;
|
||||
|
||||
/** @var array */
|
||||
private $clientContextParams = [];
|
||||
|
||||
/** @var Operation[] */
|
||||
private $operations = [];
|
||||
|
||||
/** @var array */
|
||||
private $paginators = null;
|
||||
|
||||
/** @var array */
|
||||
private $waiters = null;
|
||||
|
||||
/** @var boolean */
|
||||
private $modifiedModel = false;
|
||||
|
||||
/**
|
||||
* @param array $definition
|
||||
* @param callable $provider
|
||||
*
|
||||
* @internal param array $definition Service description
|
||||
*/
|
||||
public function __construct(array $definition, callable $provider)
|
||||
{
|
||||
static $defaults = [
|
||||
'operations' => [],
|
||||
'shapes' => [],
|
||||
'metadata' => [],
|
||||
'clientContextParams' => []
|
||||
], $defaultMeta = [
|
||||
'apiVersion' => null,
|
||||
'serviceFullName' => null,
|
||||
'serviceId' => null,
|
||||
'endpointPrefix' => null,
|
||||
'signingName' => null,
|
||||
'signatureVersion' => null,
|
||||
'protocol' => null,
|
||||
'uid' => null
|
||||
];
|
||||
|
||||
$definition += $defaults;
|
||||
$definition['metadata'] += $defaultMeta;
|
||||
$this->definition = $definition;
|
||||
$this->apiProvider = $provider;
|
||||
parent::__construct($definition, new ShapeMap($definition['shapes']));
|
||||
|
||||
if (isset($definition['metadata']['serviceIdentifier'])) {
|
||||
$this->serviceName = $this->getServiceName();
|
||||
} else {
|
||||
$this->serviceName = $this->getEndpointPrefix();
|
||||
}
|
||||
$this->apiVersion = $this->getApiVersion();
|
||||
if (isset($definition['clientContextParams'])) {
|
||||
$this->clientContextParams = $definition['clientContextParams'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a request serializer for the provided API object.
|
||||
*
|
||||
* @param Service $api API that contains a protocol.
|
||||
* @param string $endpoint Endpoint to send requests to.
|
||||
*
|
||||
* @return callable
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public static function createSerializer(Service $api, $endpoint)
|
||||
{
|
||||
static $mapping = [
|
||||
'json' => Serializer\JsonRpcSerializer::class,
|
||||
'query' => Serializer\QuerySerializer::class,
|
||||
'rest-json' => Serializer\RestJsonSerializer::class,
|
||||
'rest-xml' => Serializer\RestXmlSerializer::class
|
||||
];
|
||||
|
||||
$proto = $api->getProtocol();
|
||||
|
||||
if (isset($mapping[$proto])) {
|
||||
return new $mapping[$proto]($api, $endpoint);
|
||||
}
|
||||
|
||||
if ($proto == 'ec2') {
|
||||
return new Serializer\QuerySerializer($api, $endpoint, new Serializer\Ec2ParamBuilder());
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException(
|
||||
'Unknown protocol: ' . $api->getProtocol()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an error parser for the given protocol.
|
||||
*
|
||||
* Redundant method signature to preserve backwards compatibility.
|
||||
*
|
||||
* @param string $protocol Protocol to parse (e.g., query, json, etc.)
|
||||
*
|
||||
* @return callable
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public static function createErrorParser($protocol, Service $api = null)
|
||||
{
|
||||
static $mapping = [
|
||||
'json' => ErrorParser\JsonRpcErrorParser::class,
|
||||
'query' => ErrorParser\XmlErrorParser::class,
|
||||
'rest-json' => ErrorParser\RestJsonErrorParser::class,
|
||||
'rest-xml' => ErrorParser\XmlErrorParser::class,
|
||||
'ec2' => ErrorParser\XmlErrorParser::class
|
||||
];
|
||||
|
||||
if (isset($mapping[$protocol])) {
|
||||
return new $mapping[$protocol]($api);
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException("Unknown protocol: $protocol");
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the listeners needed to parse client models.
|
||||
*
|
||||
* @param Service $api API to create a parser for
|
||||
* @return callable
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public static function createParser(Service $api)
|
||||
{
|
||||
static $mapping = [
|
||||
'json' => Parser\JsonRpcParser::class,
|
||||
'query' => Parser\QueryParser::class,
|
||||
'rest-json' => Parser\RestJsonParser::class,
|
||||
'rest-xml' => Parser\RestXmlParser::class
|
||||
];
|
||||
|
||||
$proto = $api->getProtocol();
|
||||
if (isset($mapping[$proto])) {
|
||||
return new $mapping[$proto]($api);
|
||||
}
|
||||
|
||||
if ($proto == 'ec2') {
|
||||
return new Parser\QueryParser($api, null, false);
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException(
|
||||
'Unknown protocol: ' . $api->getProtocol()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full name of the service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceFullName()
|
||||
{
|
||||
return $this->definition['metadata']['serviceFullName'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceId()
|
||||
{
|
||||
return $this->definition['metadata']['serviceId'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API version of the service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->definition['metadata']['apiVersion'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API version of the service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getEndpointPrefix()
|
||||
{
|
||||
return $this->definition['metadata']['endpointPrefix'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the signing name used by the service.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSigningName()
|
||||
{
|
||||
return $this->definition['metadata']['signingName']
|
||||
?: $this->definition['metadata']['endpointPrefix'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceName()
|
||||
{
|
||||
return $this->definition['metadata']['serviceIdentifier'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default signature version of the service.
|
||||
*
|
||||
* Note: this method assumes "v4" when not specified in the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSignatureVersion()
|
||||
{
|
||||
return $this->definition['metadata']['signatureVersion'] ?: 'v4';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the protocol used by the service.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProtocol()
|
||||
{
|
||||
return $this->definition['metadata']['protocol'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the uid string used by the service
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUid()
|
||||
{
|
||||
return $this->definition['metadata']['uid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the description has a specific operation by name.
|
||||
*
|
||||
* @param string $name Operation to check by name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasOperation($name)
|
||||
{
|
||||
return isset($this['operations'][$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an operation by name.
|
||||
*
|
||||
* @param string $name Operation to retrieve by name
|
||||
*
|
||||
* @return Operation
|
||||
* @throws \InvalidArgumentException If the operation is not found
|
||||
*/
|
||||
public function getOperation($name)
|
||||
{
|
||||
if (!isset($this->operations[$name])) {
|
||||
if (!isset($this->definition['operations'][$name])) {
|
||||
throw new \InvalidArgumentException("Unknown operation: $name");
|
||||
}
|
||||
$this->operations[$name] = new Operation(
|
||||
$this->definition['operations'][$name],
|
||||
$this->shapeMap
|
||||
);
|
||||
} else if ($this->modifiedModel) {
|
||||
$this->operations[$name] = new Operation(
|
||||
$this->definition['operations'][$name],
|
||||
$this->shapeMap
|
||||
);
|
||||
}
|
||||
|
||||
return $this->operations[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the operations of the description.
|
||||
*
|
||||
* @return Operation[]
|
||||
*/
|
||||
public function getOperations()
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->definition['operations'] as $name => $definition) {
|
||||
$result[$name] = $this->getOperation($name);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the error shapes of the service
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrorShapes()
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->definition['shapes'] as $name => $definition) {
|
||||
if (!empty($definition['exception'])) {
|
||||
$definition['name'] = $name;
|
||||
$result[] = new StructureShape($definition, $this->getShapeMap());
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the service metadata or a specific metadata key value.
|
||||
*
|
||||
* @param string|null $key Key to retrieve or null to retrieve all metadata
|
||||
*
|
||||
* @return mixed Returns the result or null if the key is not found
|
||||
*/
|
||||
public function getMetadata($key = null)
|
||||
{
|
||||
if (!$key) {
|
||||
return $this['metadata'];
|
||||
}
|
||||
|
||||
if (isset($this->definition['metadata'][$key])) {
|
||||
return $this->definition['metadata'][$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an associative array of available paginator configurations where
|
||||
* the key is the name of the paginator, and the value is the paginator
|
||||
* configuration.
|
||||
*
|
||||
* @return array
|
||||
* @unstable The configuration format of paginators may change in the future
|
||||
*/
|
||||
public function getPaginators()
|
||||
{
|
||||
if (!isset($this->paginators)) {
|
||||
$res = call_user_func(
|
||||
$this->apiProvider,
|
||||
'paginator',
|
||||
$this->serviceName,
|
||||
$this->apiVersion
|
||||
);
|
||||
$this->paginators = isset($res['pagination'])
|
||||
? $res['pagination']
|
||||
: [];
|
||||
}
|
||||
|
||||
return $this->paginators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the service has a paginator by name.
|
||||
*
|
||||
* @param string $name Name of the paginator.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPaginator($name)
|
||||
{
|
||||
return isset($this->getPaginators()[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a paginator by name.
|
||||
*
|
||||
* @param string $name Paginator to retrieve by name. This argument is
|
||||
* typically the operation name.
|
||||
* @return array
|
||||
* @throws \UnexpectedValueException if the paginator does not exist.
|
||||
* @unstable The configuration format of paginators may change in the future
|
||||
*/
|
||||
public function getPaginatorConfig($name)
|
||||
{
|
||||
static $defaults = [
|
||||
'input_token' => null,
|
||||
'output_token' => null,
|
||||
'limit_key' => null,
|
||||
'result_key' => null,
|
||||
'more_results' => null,
|
||||
];
|
||||
|
||||
if ($this->hasPaginator($name)) {
|
||||
return $this->paginators[$name] + $defaults;
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException("There is no {$name} "
|
||||
. "paginator defined for the {$this->serviceName} service.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an associative array of available waiter configurations where the
|
||||
* key is the name of the waiter, and the value is the waiter
|
||||
* configuration.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getWaiters()
|
||||
{
|
||||
if (!isset($this->waiters)) {
|
||||
$res = call_user_func(
|
||||
$this->apiProvider,
|
||||
'waiter',
|
||||
$this->serviceName,
|
||||
$this->apiVersion
|
||||
);
|
||||
$this->waiters = isset($res['waiters'])
|
||||
? $res['waiters']
|
||||
: [];
|
||||
}
|
||||
|
||||
return $this->waiters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the service has a waiter by name.
|
||||
*
|
||||
* @param string $name Name of the waiter.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasWaiter($name)
|
||||
{
|
||||
return isset($this->getWaiters()[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a waiter configuration by name.
|
||||
*
|
||||
* @param string $name Name of the waiter by name.
|
||||
*
|
||||
* @return array
|
||||
* @throws \UnexpectedValueException if the waiter does not exist.
|
||||
*/
|
||||
public function getWaiterConfig($name)
|
||||
{
|
||||
// Error if the waiter is not defined
|
||||
if ($this->hasWaiter($name)) {
|
||||
return $this->waiters[$name];
|
||||
}
|
||||
|
||||
throw new \UnexpectedValueException("There is no {$name} waiter "
|
||||
. "defined for the {$this->serviceName} service.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shape map used by the API.
|
||||
*
|
||||
* @return ShapeMap
|
||||
*/
|
||||
public function getShapeMap()
|
||||
{
|
||||
return $this->shapeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the context params of the description.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getClientContextParams()
|
||||
{
|
||||
return $this->clientContextParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service's api provider.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function getProvider()
|
||||
{
|
||||
return $this->apiProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service's definition.
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public function getDefinition()
|
||||
{
|
||||
return $this->definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service's api definition.
|
||||
* Intended for internal use only.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function setDefinition($definition)
|
||||
{
|
||||
$this->definition = $definition;
|
||||
$this->modifiedModel = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Denotes whether or not a service's definition has
|
||||
* been modified. Intended for internal use only.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function isModifiedModel()
|
||||
{
|
||||
return $this->modifiedModel;
|
||||
}
|
||||
}
|
77
lib/aws-sdk/src/Api/Shape.php
Normal file
77
lib/aws-sdk/src/Api/Shape.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Base class representing a modeled shape.
|
||||
*/
|
||||
class Shape extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* Get a concrete shape for the given definition.
|
||||
*
|
||||
* @param array $definition
|
||||
* @param ShapeMap $shapeMap
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \RuntimeException if the type is invalid
|
||||
*/
|
||||
public static function create(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
static $map = [
|
||||
'structure' => StructureShape::class,
|
||||
'map' => MapShape::class,
|
||||
'list' => ListShape::class,
|
||||
'timestamp' => TimestampShape::class,
|
||||
'integer' => Shape::class,
|
||||
'double' => Shape::class,
|
||||
'float' => Shape::class,
|
||||
'long' => Shape::class,
|
||||
'string' => Shape::class,
|
||||
'byte' => Shape::class,
|
||||
'character' => Shape::class,
|
||||
'blob' => Shape::class,
|
||||
'boolean' => Shape::class
|
||||
];
|
||||
|
||||
if (isset($definition['shape'])) {
|
||||
return $shapeMap->resolve($definition);
|
||||
}
|
||||
|
||||
if (!isset($map[$definition['type']])) {
|
||||
throw new \RuntimeException('Invalid type: '
|
||||
. print_r($definition, true));
|
||||
}
|
||||
|
||||
$type = $map[$definition['type']];
|
||||
|
||||
return new $type($definition, $shapeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the shape
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->definition['type'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the shape
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->definition['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a context param definition.
|
||||
*/
|
||||
public function getContextParam()
|
||||
{
|
||||
return $this->contextParam;
|
||||
}
|
||||
}
|
68
lib/aws-sdk/src/Api/ShapeMap.php
Normal file
68
lib/aws-sdk/src/Api/ShapeMap.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Builds shape based on shape references.
|
||||
*/
|
||||
class ShapeMap
|
||||
{
|
||||
/** @var array */
|
||||
private $definitions;
|
||||
|
||||
/** @var Shape[] */
|
||||
private $simple;
|
||||
|
||||
/**
|
||||
* @param array $shapeModels Associative array of shape definitions.
|
||||
*/
|
||||
public function __construct(array $shapeModels)
|
||||
{
|
||||
$this->definitions = $shapeModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of shape names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getShapeNames()
|
||||
{
|
||||
return array_keys($this->definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a shape reference
|
||||
*
|
||||
* @param array $shapeRef Shape reference shape
|
||||
*
|
||||
* @return Shape
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function resolve(array $shapeRef)
|
||||
{
|
||||
$shape = $shapeRef['shape'];
|
||||
|
||||
if (!isset($this->definitions[$shape])) {
|
||||
throw new \InvalidArgumentException('Shape not found: ' . $shape);
|
||||
}
|
||||
|
||||
$isSimple = count($shapeRef) == 1;
|
||||
if ($isSimple && isset($this->simple[$shape])) {
|
||||
return $this->simple[$shape];
|
||||
}
|
||||
|
||||
$definition = $shapeRef + $this->definitions[$shape];
|
||||
$definition['name'] = $definition['shape'];
|
||||
if (isset($definition['shape'])) {
|
||||
unset($definition['shape']);
|
||||
}
|
||||
|
||||
$result = Shape::create($definition, $this);
|
||||
|
||||
if ($isSimple) {
|
||||
$this->simple[$shape] = $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
79
lib/aws-sdk/src/Api/StructureShape.php
Normal file
79
lib/aws-sdk/src/Api/StructureShape.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Represents a structure shape and resolve member shape references.
|
||||
*/
|
||||
class StructureShape extends Shape
|
||||
{
|
||||
/**
|
||||
* @var Shape[]
|
||||
*/
|
||||
private $members;
|
||||
|
||||
public function __construct(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
$definition['type'] = 'structure';
|
||||
|
||||
if (!isset($definition['members'])) {
|
||||
$definition['members'] = [];
|
||||
}
|
||||
|
||||
parent::__construct($definition, $shapeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all members
|
||||
*
|
||||
* @return Shape[]
|
||||
*/
|
||||
public function getMembers()
|
||||
{
|
||||
if (empty($this->members)) {
|
||||
$this->generateMembersHash();
|
||||
}
|
||||
|
||||
return $this->members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a specific member exists by name.
|
||||
*
|
||||
* @param string $name Name of the member to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasMember($name)
|
||||
{
|
||||
return isset($this->definition['members'][$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a member by name.
|
||||
*
|
||||
* @param string $name Name of the member to retrieve
|
||||
*
|
||||
* @return Shape
|
||||
* @throws \InvalidArgumentException if the member is not found.
|
||||
*/
|
||||
public function getMember($name)
|
||||
{
|
||||
$members = $this->getMembers();
|
||||
|
||||
if (!isset($members[$name])) {
|
||||
throw new \InvalidArgumentException('Unknown member ' . $name);
|
||||
}
|
||||
|
||||
return $members[$name];
|
||||
}
|
||||
|
||||
|
||||
private function generateMembersHash()
|
||||
{
|
||||
$this->members = [];
|
||||
|
||||
foreach ($this->definition['members'] as $name => $definition) {
|
||||
$this->members[$name] = $this->shapeFor($definition);
|
||||
}
|
||||
}
|
||||
}
|
48
lib/aws-sdk/src/Api/TimestampShape.php
Normal file
48
lib/aws-sdk/src/Api/TimestampShape.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
/**
|
||||
* Represents a timestamp shape.
|
||||
*/
|
||||
class TimestampShape extends Shape
|
||||
{
|
||||
public function __construct(array $definition, ShapeMap $shapeMap)
|
||||
{
|
||||
$definition['type'] = 'timestamp';
|
||||
parent::__construct($definition, $shapeMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a timestamp value for a service.
|
||||
*
|
||||
* @param mixed $value Value to format
|
||||
* @param string $format Format used to serialize the value
|
||||
*
|
||||
* @return int|string
|
||||
* @throws \UnexpectedValueException if the format is unknown.
|
||||
* @throws \InvalidArgumentException if the value is an unsupported type.
|
||||
*/
|
||||
public static function format($value, $format)
|
||||
{
|
||||
if ($value instanceof \DateTimeInterface) {
|
||||
$value = $value->getTimestamp();
|
||||
} elseif (is_string($value)) {
|
||||
$value = strtotime($value);
|
||||
} elseif (!is_int($value)) {
|
||||
throw new \InvalidArgumentException('Unable to handle the provided'
|
||||
. ' timestamp type: ' . gettype($value));
|
||||
}
|
||||
|
||||
switch ($format) {
|
||||
case 'iso8601':
|
||||
return gmdate('Y-m-d\TH:i:s\Z', $value);
|
||||
case 'rfc822':
|
||||
return gmdate('D, d M Y H:i:s \G\M\T', $value);
|
||||
case 'unixTimestamp':
|
||||
return $value;
|
||||
default:
|
||||
throw new \UnexpectedValueException('Unknown timestamp format: '
|
||||
. $format);
|
||||
}
|
||||
}
|
||||
}
|
346
lib/aws-sdk/src/Api/Validator.php
Normal file
346
lib/aws-sdk/src/Api/Validator.php
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
namespace Aws\Api;
|
||||
|
||||
use Aws;
|
||||
|
||||
/**
|
||||
* Validates a schema against a hash of input.
|
||||
*/
|
||||
class Validator
|
||||
{
|
||||
private $path = [];
|
||||
private $errors = [];
|
||||
private $constraints = [];
|
||||
|
||||
private static $defaultConstraints = [
|
||||
'required' => true,
|
||||
'min' => true,
|
||||
'max' => false,
|
||||
'pattern' => false
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array $constraints Associative array of constraints to enforce.
|
||||
* Accepts the following keys: "required", "min",
|
||||
* "max", and "pattern". If a key is not
|
||||
* provided, the constraint will assume false.
|
||||
*/
|
||||
public function __construct(array $constraints = null)
|
||||
{
|
||||
static $assumedFalseValues = [
|
||||
'required' => false,
|
||||
'min' => false,
|
||||
'max' => false,
|
||||
'pattern' => false
|
||||
];
|
||||
$this->constraints = empty($constraints)
|
||||
? self::$defaultConstraints
|
||||
: $constraints + $assumedFalseValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given input against the schema.
|
||||
*
|
||||
* @param string $name Operation name
|
||||
* @param Shape $shape Shape to validate
|
||||
* @param array $input Input to validate
|
||||
*
|
||||
* @throws \InvalidArgumentException if the input is invalid.
|
||||
*/
|
||||
public function validate($name, Shape $shape, array $input)
|
||||
{
|
||||
$this->dispatch($shape, $input);
|
||||
|
||||
if ($this->errors) {
|
||||
$message = sprintf(
|
||||
"Found %d error%s while validating the input provided for the "
|
||||
. "%s operation:\n%s",
|
||||
count($this->errors),
|
||||
count($this->errors) > 1 ? 's' : '',
|
||||
$name,
|
||||
implode("\n", $this->errors)
|
||||
);
|
||||
$this->errors = [];
|
||||
|
||||
throw new \InvalidArgumentException($message);
|
||||
}
|
||||
}
|
||||
|
||||
private function dispatch(Shape $shape, $value)
|
||||
{
|
||||
static $methods = [
|
||||
'structure' => 'check_structure',
|
||||
'list' => 'check_list',
|
||||
'map' => 'check_map',
|
||||
'blob' => 'check_blob',
|
||||
'boolean' => 'check_boolean',
|
||||
'integer' => 'check_numeric',
|
||||
'float' => 'check_numeric',
|
||||
'long' => 'check_numeric',
|
||||
'string' => 'check_string',
|
||||
'byte' => 'check_string',
|
||||
'char' => 'check_string'
|
||||
];
|
||||
|
||||
$type = $shape->getType();
|
||||
if (isset($methods[$type])) {
|
||||
$this->{$methods[$type]}($shape, $value);
|
||||
}
|
||||
}
|
||||
|
||||
private function check_structure(StructureShape $shape, $value)
|
||||
{
|
||||
$isDocument = (isset($shape['document']) && $shape['document']);
|
||||
$isUnion = (isset($shape['union']) && $shape['union']);
|
||||
if ($isDocument) {
|
||||
if (!$this->checkDocumentType($value)) {
|
||||
$this->addError("is not a valid document type");
|
||||
return;
|
||||
}
|
||||
} elseif ($isUnion) {
|
||||
if (!$this->checkUnion($value)) {
|
||||
$this->addError("is a union type and must have exactly one non null value");
|
||||
return;
|
||||
}
|
||||
} elseif (!$this->checkAssociativeArray($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->constraints['required'] && $shape['required']) {
|
||||
foreach ($shape['required'] as $req) {
|
||||
if (!isset($value[$req])) {
|
||||
$this->path[] = $req;
|
||||
$this->addError('is missing and is a required parameter');
|
||||
array_pop($this->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$isDocument) {
|
||||
foreach ($value as $name => $v) {
|
||||
if ($shape->hasMember($name)) {
|
||||
$this->path[] = $name;
|
||||
$this->dispatch(
|
||||
$shape->getMember($name),
|
||||
isset($value[$name]) ? $value[$name] : null
|
||||
);
|
||||
array_pop($this->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function check_list(ListShape $shape, $value)
|
||||
{
|
||||
if (!is_array($value)) {
|
||||
$this->addError('must be an array. Found '
|
||||
. Aws\describe_type($value));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validateRange($shape, count($value), "list element count");
|
||||
|
||||
$items = $shape->getMember();
|
||||
foreach ($value as $index => $v) {
|
||||
$this->path[] = $index;
|
||||
$this->dispatch($items, $v);
|
||||
array_pop($this->path);
|
||||
}
|
||||
}
|
||||
|
||||
private function check_map(MapShape $shape, $value)
|
||||
{
|
||||
if (!$this->checkAssociativeArray($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$values = $shape->getValue();
|
||||
foreach ($value as $key => $v) {
|
||||
$this->path[] = $key;
|
||||
$this->dispatch($values, $v);
|
||||
array_pop($this->path);
|
||||
}
|
||||
}
|
||||
|
||||
private function check_blob(Shape $shape, $value)
|
||||
{
|
||||
static $valid = [
|
||||
'string' => true,
|
||||
'integer' => true,
|
||||
'double' => true,
|
||||
'resource' => true
|
||||
];
|
||||
|
||||
$type = gettype($value);
|
||||
if (!isset($valid[$type])) {
|
||||
if ($type != 'object' || !method_exists($value, '__toString')) {
|
||||
$this->addError('must be an fopen resource, a '
|
||||
. 'GuzzleHttp\Stream\StreamInterface object, or something '
|
||||
. 'that can be cast to a string. Found '
|
||||
. Aws\describe_type($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function check_numeric(Shape $shape, $value)
|
||||
{
|
||||
if (!is_numeric($value)) {
|
||||
$this->addError('must be numeric. Found '
|
||||
. Aws\describe_type($value));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validateRange($shape, $value, "numeric value");
|
||||
}
|
||||
|
||||
private function check_boolean(Shape $shape, $value)
|
||||
{
|
||||
if (!is_bool($value)) {
|
||||
$this->addError('must be a boolean. Found '
|
||||
. Aws\describe_type($value));
|
||||
}
|
||||
}
|
||||
|
||||
private function check_string(Shape $shape, $value)
|
||||
{
|
||||
if ($shape['jsonvalue']) {
|
||||
if (!self::canJsonEncode($value)) {
|
||||
$this->addError('must be a value encodable with \'json_encode\'.'
|
||||
. ' Found ' . Aws\describe_type($value));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->checkCanString($value)) {
|
||||
$this->addError('must be a string or an object that implements '
|
||||
. '__toString(). Found ' . Aws\describe_type($value));
|
||||
return;
|
||||
}
|
||||
|
||||
$value = isset($value) ? $value : '';
|
||||
$this->validateRange($shape, strlen($value), "string length");
|
||||
|
||||
if ($this->constraints['pattern']) {
|
||||
$pattern = $shape['pattern'];
|
||||
if ($pattern && !preg_match("/$pattern/", $value)) {
|
||||
$this->addError("Pattern /$pattern/ failed to match '$value'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function validateRange(Shape $shape, $length, $descriptor)
|
||||
{
|
||||
if ($this->constraints['min']) {
|
||||
$min = $shape['min'];
|
||||
if ($min && $length < $min) {
|
||||
$this->addError("expected $descriptor to be >= $min, but "
|
||||
. "found $descriptor of $length");
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->constraints['max']) {
|
||||
$max = $shape['max'];
|
||||
if ($max && $length > $max) {
|
||||
$this->addError("expected $descriptor to be <= $max, but "
|
||||
. "found $descriptor of $length");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function checkArray($arr)
|
||||
{
|
||||
return $this->isIndexed($arr) || $this->isAssociative($arr);
|
||||
}
|
||||
|
||||
private function isAssociative($arr)
|
||||
{
|
||||
return count(array_filter(array_keys($arr), "is_string")) == count($arr);
|
||||
}
|
||||
|
||||
private function isIndexed(array $arr)
|
||||
{
|
||||
return $arr == array_values($arr);
|
||||
}
|
||||
|
||||
private function checkCanString($value)
|
||||
{
|
||||
static $valid = [
|
||||
'string' => true,
|
||||
'integer' => true,
|
||||
'double' => true,
|
||||
'NULL' => true,
|
||||
];
|
||||
|
||||
$type = gettype($value);
|
||||
|
||||
return isset($valid[$type]) ||
|
||||
($type == 'object' && method_exists($value, '__toString'));
|
||||
}
|
||||
|
||||
private function checkAssociativeArray($value)
|
||||
{
|
||||
$isAssociative = false;
|
||||
|
||||
if (is_array($value)) {
|
||||
$expectedIndex = 0;
|
||||
$key = key($value);
|
||||
|
||||
do {
|
||||
$isAssociative = $key !== $expectedIndex++;
|
||||
next($value);
|
||||
$key = key($value);
|
||||
} while (!$isAssociative && null !== $key);
|
||||
}
|
||||
|
||||
if (!$isAssociative) {
|
||||
$this->addError('must be an associative array. Found '
|
||||
. Aws\describe_type($value));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function checkDocumentType($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$typeOfFirstKey = gettype(key($value));
|
||||
foreach ($value as $key => $val) {
|
||||
if (!$this->checkDocumentType($val) || gettype($key) != $typeOfFirstKey) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $this->checkArray($value);
|
||||
}
|
||||
return is_null($value)
|
||||
|| is_numeric($value)
|
||||
|| is_string($value)
|
||||
|| is_bool($value);
|
||||
}
|
||||
|
||||
private function checkUnion($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$nonNullCount = 0;
|
||||
foreach ($value as $key => $val) {
|
||||
if (!is_null($val) && !(strpos($key, "@") === 0)) {
|
||||
$nonNullCount++;
|
||||
}
|
||||
}
|
||||
return $nonNullCount == 1;
|
||||
}
|
||||
return !is_null($value);
|
||||
}
|
||||
|
||||
private function addError($message)
|
||||
{
|
||||
$this->errors[] =
|
||||
implode('', array_map(function ($s) { return "[{$s}]"; }, $this->path))
|
||||
. ' '
|
||||
. $message;
|
||||
}
|
||||
|
||||
private function canJsonEncode($data)
|
||||
{
|
||||
return !is_resource($data);
|
||||
}
|
||||
}
|
272
lib/aws-sdk/src/ApiGateway/ApiGatewayClient.php
Normal file
272
lib/aws-sdk/src/ApiGateway/ApiGatewayClient.php
Normal file
@ -0,0 +1,272 @@
|
||||
<?php
|
||||
namespace Aws\ApiGateway;
|
||||
|
||||
use Aws\AwsClient;
|
||||
use Aws\CommandInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AWS API Gateway** service.
|
||||
*
|
||||
* @method \Aws\Result createApiKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createApiKeyAsync(array $args = [])
|
||||
* @method \Aws\Result createAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result createBasePathMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createBasePathMappingAsync(array $args = [])
|
||||
* @method \Aws\Result createDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result createDocumentationPart(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDocumentationPartAsync(array $args = [])
|
||||
* @method \Aws\Result createDocumentationVersion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDocumentationVersionAsync(array $args = [])
|
||||
* @method \Aws\Result createDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result createModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createModelAsync(array $args = [])
|
||||
* @method \Aws\Result createRequestValidator(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createRequestValidatorAsync(array $args = [])
|
||||
* @method \Aws\Result createResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createResourceAsync(array $args = [])
|
||||
* @method \Aws\Result createRestApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createRestApiAsync(array $args = [])
|
||||
* @method \Aws\Result createStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createStageAsync(array $args = [])
|
||||
* @method \Aws\Result createUsagePlan(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createUsagePlanAsync(array $args = [])
|
||||
* @method \Aws\Result createUsagePlanKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createUsagePlanKeyAsync(array $args = [])
|
||||
* @method \Aws\Result createVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createVpcLinkAsync(array $args = [])
|
||||
* @method \Aws\Result deleteApiKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteApiKeyAsync(array $args = [])
|
||||
* @method \Aws\Result deleteAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result deleteBasePathMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteBasePathMappingAsync(array $args = [])
|
||||
* @method \Aws\Result deleteClientCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteClientCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDocumentationPart(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDocumentationPartAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDocumentationVersion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDocumentationVersionAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result deleteGatewayResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteGatewayResponseAsync(array $args = [])
|
||||
* @method \Aws\Result deleteIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result deleteIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result deleteMethod(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteMethodAsync(array $args = [])
|
||||
* @method \Aws\Result deleteMethodResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteMethodResponseAsync(array $args = [])
|
||||
* @method \Aws\Result deleteModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteModelAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRequestValidator(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRequestValidatorAsync(array $args = [])
|
||||
* @method \Aws\Result deleteResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteResourceAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRestApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRestApiAsync(array $args = [])
|
||||
* @method \Aws\Result deleteStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteStageAsync(array $args = [])
|
||||
* @method \Aws\Result deleteUsagePlan(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteUsagePlanAsync(array $args = [])
|
||||
* @method \Aws\Result deleteUsagePlanKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteUsagePlanKeyAsync(array $args = [])
|
||||
* @method \Aws\Result deleteVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteVpcLinkAsync(array $args = [])
|
||||
* @method \Aws\Result flushStageAuthorizersCache(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise flushStageAuthorizersCacheAsync(array $args = [])
|
||||
* @method \Aws\Result flushStageCache(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise flushStageCacheAsync(array $args = [])
|
||||
* @method \Aws\Result generateClientCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise generateClientCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result getAccount(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAccountAsync(array $args = [])
|
||||
* @method \Aws\Result getApiKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getApiKeyAsync(array $args = [])
|
||||
* @method \Aws\Result getApiKeys(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getApiKeysAsync(array $args = [])
|
||||
* @method \Aws\Result getAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result getAuthorizers(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAuthorizersAsync(array $args = [])
|
||||
* @method \Aws\Result getBasePathMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBasePathMappingAsync(array $args = [])
|
||||
* @method \Aws\Result getBasePathMappings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getBasePathMappingsAsync(array $args = [])
|
||||
* @method \Aws\Result getClientCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getClientCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result getClientCertificates(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getClientCertificatesAsync(array $args = [])
|
||||
* @method \Aws\Result getDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result getDeployments(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDeploymentsAsync(array $args = [])
|
||||
* @method \Aws\Result getDocumentationPart(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDocumentationPartAsync(array $args = [])
|
||||
* @method \Aws\Result getDocumentationParts(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDocumentationPartsAsync(array $args = [])
|
||||
* @method \Aws\Result getDocumentationVersion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDocumentationVersionAsync(array $args = [])
|
||||
* @method \Aws\Result getDocumentationVersions(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDocumentationVersionsAsync(array $args = [])
|
||||
* @method \Aws\Result getDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result getDomainNames(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDomainNamesAsync(array $args = [])
|
||||
* @method \Aws\Result getExport(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getExportAsync(array $args = [])
|
||||
* @method \Aws\Result getGatewayResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getGatewayResponseAsync(array $args = [])
|
||||
* @method \Aws\Result getGatewayResponses(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getGatewayResponsesAsync(array $args = [])
|
||||
* @method \Aws\Result getIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result getIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result getMethod(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getMethodAsync(array $args = [])
|
||||
* @method \Aws\Result getMethodResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getMethodResponseAsync(array $args = [])
|
||||
* @method \Aws\Result getModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelAsync(array $args = [])
|
||||
* @method \Aws\Result getModelTemplate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelTemplateAsync(array $args = [])
|
||||
* @method \Aws\Result getModels(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelsAsync(array $args = [])
|
||||
* @method \Aws\Result getRequestValidator(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRequestValidatorAsync(array $args = [])
|
||||
* @method \Aws\Result getRequestValidators(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRequestValidatorsAsync(array $args = [])
|
||||
* @method \Aws\Result getResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getResourceAsync(array $args = [])
|
||||
* @method \Aws\Result getResources(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getResourcesAsync(array $args = [])
|
||||
* @method \Aws\Result getRestApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRestApiAsync(array $args = [])
|
||||
* @method \Aws\Result getRestApis(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRestApisAsync(array $args = [])
|
||||
* @method \Aws\Result getSdk(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getSdkAsync(array $args = [])
|
||||
* @method \Aws\Result getSdkType(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getSdkTypeAsync(array $args = [])
|
||||
* @method \Aws\Result getSdkTypes(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getSdkTypesAsync(array $args = [])
|
||||
* @method \Aws\Result getStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getStageAsync(array $args = [])
|
||||
* @method \Aws\Result getStages(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getStagesAsync(array $args = [])
|
||||
* @method \Aws\Result getTags(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getTagsAsync(array $args = [])
|
||||
* @method \Aws\Result getUsage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getUsageAsync(array $args = [])
|
||||
* @method \Aws\Result getUsagePlan(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getUsagePlanAsync(array $args = [])
|
||||
* @method \Aws\Result getUsagePlanKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getUsagePlanKeyAsync(array $args = [])
|
||||
* @method \Aws\Result getUsagePlanKeys(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getUsagePlanKeysAsync(array $args = [])
|
||||
* @method \Aws\Result getUsagePlans(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getUsagePlansAsync(array $args = [])
|
||||
* @method \Aws\Result getVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getVpcLinkAsync(array $args = [])
|
||||
* @method \Aws\Result getVpcLinks(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getVpcLinksAsync(array $args = [])
|
||||
* @method \Aws\Result importApiKeys(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importApiKeysAsync(array $args = [])
|
||||
* @method \Aws\Result importDocumentationParts(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importDocumentationPartsAsync(array $args = [])
|
||||
* @method \Aws\Result importRestApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importRestApiAsync(array $args = [])
|
||||
* @method \Aws\Result putGatewayResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putGatewayResponseAsync(array $args = [])
|
||||
* @method \Aws\Result putIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result putIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result putMethod(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putMethodAsync(array $args = [])
|
||||
* @method \Aws\Result putMethodResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putMethodResponseAsync(array $args = [])
|
||||
* @method \Aws\Result putRestApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise putRestApiAsync(array $args = [])
|
||||
* @method \Aws\Result tagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result testInvokeAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise testInvokeAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result testInvokeMethod(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise testInvokeMethodAsync(array $args = [])
|
||||
* @method \Aws\Result untagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result updateAccount(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateAccountAsync(array $args = [])
|
||||
* @method \Aws\Result updateApiKey(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateApiKeyAsync(array $args = [])
|
||||
* @method \Aws\Result updateAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result updateBasePathMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateBasePathMappingAsync(array $args = [])
|
||||
* @method \Aws\Result updateClientCertificate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateClientCertificateAsync(array $args = [])
|
||||
* @method \Aws\Result updateDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result updateDocumentationPart(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDocumentationPartAsync(array $args = [])
|
||||
* @method \Aws\Result updateDocumentationVersion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDocumentationVersionAsync(array $args = [])
|
||||
* @method \Aws\Result updateDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result updateGatewayResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateGatewayResponseAsync(array $args = [])
|
||||
* @method \Aws\Result updateIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result updateIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result updateMethod(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateMethodAsync(array $args = [])
|
||||
* @method \Aws\Result updateMethodResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateMethodResponseAsync(array $args = [])
|
||||
* @method \Aws\Result updateModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateModelAsync(array $args = [])
|
||||
* @method \Aws\Result updateRequestValidator(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateRequestValidatorAsync(array $args = [])
|
||||
* @method \Aws\Result updateResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateResourceAsync(array $args = [])
|
||||
* @method \Aws\Result updateRestApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateRestApiAsync(array $args = [])
|
||||
* @method \Aws\Result updateStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateStageAsync(array $args = [])
|
||||
* @method \Aws\Result updateUsage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateUsageAsync(array $args = [])
|
||||
* @method \Aws\Result updateUsagePlan(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateUsagePlanAsync(array $args = [])
|
||||
* @method \Aws\Result updateVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateVpcLinkAsync(array $args = [])
|
||||
*/
|
||||
class ApiGatewayClient extends AwsClient
|
||||
{
|
||||
public function __construct(array $args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
$stack = $this->getHandlerList();
|
||||
$stack->appendBuild([__CLASS__, '_add_accept_header']);
|
||||
}
|
||||
|
||||
public static function _add_accept_header(callable $handler)
|
||||
{
|
||||
return function (
|
||||
CommandInterface $command,
|
||||
RequestInterface $request
|
||||
) use ($handler) {
|
||||
$request = $request->withHeader('Accept', 'application/json');
|
||||
|
||||
return $handler($command, $request);
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\ApiGateway\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AWS API Gateway** service.
|
||||
*/
|
||||
class ApiGatewayException extends AwsException {}
|
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace Aws\ApiGatewayManagementApi;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AmazonApiGatewayManagementApi** service.
|
||||
* @method \Aws\Result deleteConnection(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteConnectionAsync(array $args = [])
|
||||
* @method \Aws\Result getConnection(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getConnectionAsync(array $args = [])
|
||||
* @method \Aws\Result postToConnection(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise postToConnectionAsync(array $args = [])
|
||||
*/
|
||||
class ApiGatewayManagementApiClient extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\ApiGatewayManagementApi\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AmazonApiGatewayManagementApi** service.
|
||||
*/
|
||||
class ApiGatewayManagementApiException extends AwsException {}
|
153
lib/aws-sdk/src/ApiGatewayV2/ApiGatewayV2Client.php
Normal file
153
lib/aws-sdk/src/ApiGatewayV2/ApiGatewayV2Client.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
namespace Aws\ApiGatewayV2;
|
||||
|
||||
use Aws\AwsClient;
|
||||
|
||||
/**
|
||||
* This client is used to interact with the **AmazonApiGatewayV2** service.
|
||||
* @method \Aws\Result createApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createApiAsync(array $args = [])
|
||||
* @method \Aws\Result createApiMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createApiMappingAsync(array $args = [])
|
||||
* @method \Aws\Result createAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result createDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result createDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result createIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result createIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result createModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createModelAsync(array $args = [])
|
||||
* @method \Aws\Result createRoute(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createRouteAsync(array $args = [])
|
||||
* @method \Aws\Result createRouteResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createRouteResponseAsync(array $args = [])
|
||||
* @method \Aws\Result createStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createStageAsync(array $args = [])
|
||||
* @method \Aws\Result createVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createVpcLinkAsync(array $args = [])
|
||||
* @method \Aws\Result deleteAccessLogSettings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAccessLogSettingsAsync(array $args = [])
|
||||
* @method \Aws\Result deleteApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteApiAsync(array $args = [])
|
||||
* @method \Aws\Result deleteApiMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteApiMappingAsync(array $args = [])
|
||||
* @method \Aws\Result deleteAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result deleteCorsConfiguration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteCorsConfigurationAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result deleteDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result deleteIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result deleteIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result deleteModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteModelAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRoute(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRouteAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRouteRequestParameter(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRouteRequestParameterAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRouteResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRouteResponseAsync(array $args = [])
|
||||
* @method \Aws\Result deleteRouteSettings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteRouteSettingsAsync(array $args = [])
|
||||
* @method \Aws\Result deleteStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteStageAsync(array $args = [])
|
||||
* @method \Aws\Result deleteVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteVpcLinkAsync(array $args = [])
|
||||
* @method \Aws\Result exportApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise exportApiAsync(array $args = [])
|
||||
* @method \Aws\Result resetAuthorizersCache(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise resetAuthorizersCacheAsync(array $args = [])
|
||||
* @method \Aws\Result getApiResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getApiResourceAsync(array $args = [])
|
||||
* @method \Aws\Result getApiMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getApiMappingAsync(array $args = [])
|
||||
* @method \Aws\Result getApiMappings(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getApiMappingsAsync(array $args = [])
|
||||
* @method \Aws\Result getApis(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getApisAsync(array $args = [])
|
||||
* @method \Aws\Result getAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result getAuthorizers(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getAuthorizersAsync(array $args = [])
|
||||
* @method \Aws\Result getDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result getDeployments(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDeploymentsAsync(array $args = [])
|
||||
* @method \Aws\Result getDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result getDomainNames(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getDomainNamesAsync(array $args = [])
|
||||
* @method \Aws\Result getIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result getIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result getIntegrationResponses(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getIntegrationResponsesAsync(array $args = [])
|
||||
* @method \Aws\Result getIntegrations(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getIntegrationsAsync(array $args = [])
|
||||
* @method \Aws\Result getModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelAsync(array $args = [])
|
||||
* @method \Aws\Result getModelTemplate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelTemplateAsync(array $args = [])
|
||||
* @method \Aws\Result getModels(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelsAsync(array $args = [])
|
||||
* @method \Aws\Result getRoute(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRouteAsync(array $args = [])
|
||||
* @method \Aws\Result getRouteResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRouteResponseAsync(array $args = [])
|
||||
* @method \Aws\Result getRouteResponses(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRouteResponsesAsync(array $args = [])
|
||||
* @method \Aws\Result getRoutes(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getRoutesAsync(array $args = [])
|
||||
* @method \Aws\Result getStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getStageAsync(array $args = [])
|
||||
* @method \Aws\Result getStages(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getStagesAsync(array $args = [])
|
||||
* @method \Aws\Result getTags(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getTagsAsync(array $args = [])
|
||||
* @method \Aws\Result getVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getVpcLinkAsync(array $args = [])
|
||||
* @method \Aws\Result getVpcLinks(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getVpcLinksAsync(array $args = [])
|
||||
* @method \Aws\Result importApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise importApiAsync(array $args = [])
|
||||
* @method \Aws\Result reimportApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise reimportApiAsync(array $args = [])
|
||||
* @method \Aws\Result tagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result untagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise untagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result updateApi(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateApiAsync(array $args = [])
|
||||
* @method \Aws\Result updateApiMapping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateApiMappingAsync(array $args = [])
|
||||
* @method \Aws\Result updateAuthorizer(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateAuthorizerAsync(array $args = [])
|
||||
* @method \Aws\Result updateDeployment(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDeploymentAsync(array $args = [])
|
||||
* @method \Aws\Result updateDomainName(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateDomainNameAsync(array $args = [])
|
||||
* @method \Aws\Result updateIntegration(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateIntegrationAsync(array $args = [])
|
||||
* @method \Aws\Result updateIntegrationResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateIntegrationResponseAsync(array $args = [])
|
||||
* @method \Aws\Result updateModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateModelAsync(array $args = [])
|
||||
* @method \Aws\Result updateRoute(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateRouteAsync(array $args = [])
|
||||
* @method \Aws\Result updateRouteResponse(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateRouteResponseAsync(array $args = [])
|
||||
* @method \Aws\Result updateStage(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateStageAsync(array $args = [])
|
||||
* @method \Aws\Result updateVpcLink(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateVpcLinkAsync(array $args = [])
|
||||
*/
|
||||
class ApiGatewayV2Client extends AwsClient {}
|
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Aws\ApiGatewayV2\Exception;
|
||||
|
||||
use Aws\Exception\AwsException;
|
||||
|
||||
/**
|
||||
* Represents an error interacting with the **AmazonApiGatewayV2** service.
|
||||
*/
|
||||
class ApiGatewayV2Exception extends AwsException {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user