-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #49 from waleedhassan5/aws_suppression_list
WR #439133: read-only access to AWS suppression list
- Loading branch information
Showing
11 changed files
with
585 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?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 tool_emailutils; | ||
|
||
defined('MOODLE_INTERNAL') || die(); | ||
|
||
require_once($CFG->libdir . '/csvlib.class.php'); | ||
|
||
/** | ||
* Class for handling suppression list operations. | ||
* | ||
* @package tool_emailutils | ||
* @copyright 2024 onwards Catalyst IT {@link http://www.catalyst-eu.net/} | ||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | ||
*/ | ||
class suppression_list { | ||
|
||
/** | ||
* Generate CSV content for the suppression list. | ||
* | ||
* @return string The CSV content. | ||
* @throws \dml_exception | ||
*/ | ||
public static function generate_csv(): string { | ||
global $DB; | ||
|
||
$csvexport = new \csv_export_writer('comma'); | ||
|
||
// Add CSV headers. | ||
$csvexport->add_data(['Email', 'Reason', 'Created At']); | ||
|
||
// Fetch suppression list from database. | ||
$suppressionlist = $DB->get_records('tool_emailutils_suppression'); | ||
|
||
// Add suppression list data to CSV. | ||
foreach ($suppressionlist as $item) { | ||
$csvexport->add_data([ | ||
$item->email, | ||
$item->reason, | ||
$item->created_at, | ||
]); | ||
} | ||
|
||
return $csvexport->print_csv_data(true); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
<?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/>. | ||
|
||
/** | ||
* Scheduled task for updating the email suppression list. | ||
* | ||
* @package tool_emailutils | ||
* @copyright 2024 onwards Catalyst IT {@link http://www.catalyst-eu.net/} | ||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | ||
* @author Waleed ul hassan <[email protected]> | ||
*/ | ||
|
||
namespace tool_emailutils\task; | ||
|
||
defined('MOODLE_INTERNAL') || die(); | ||
|
||
if (!class_exists('\Aws\SesV2\SesV2Client')) { | ||
if (file_exists($CFG->dirroot . '/local/aws/sdk/aws-autoloader.php')) { | ||
require_once($CFG->dirroot . '/local/aws/sdk/aws-autoloader.php'); | ||
} else { | ||
throw new \Exception('AWS SDK not found.'); | ||
} | ||
} | ||
|
||
/** | ||
* Scheduled task class for updating the email suppression list. | ||
* | ||
* This task fetches the latest suppression list from AWS SES and updates | ||
* the local database with this information. | ||
*/ | ||
class update_suppression_list extends \core\task\scheduled_task { | ||
/** @var \Aws\SesV2\SesV2Client|null */ | ||
protected $sesclient = null; | ||
|
||
/** | ||
* Return the task's name as shown in admin screens. | ||
* | ||
* @return string The name of the task. | ||
*/ | ||
public function get_name(): string { | ||
return get_string('task_update_suppression_list', 'tool_emailutils'); | ||
} | ||
|
||
/** | ||
* Execute the task. | ||
* | ||
* This method fetches the suppression list from AWS SES and updates | ||
* the local database with the fetched information. | ||
* | ||
* @return void | ||
*/ | ||
public function execute(): void { | ||
global $DB; | ||
|
||
$suppressionlist = $this->fetch_aws_ses_suppression_list(); | ||
|
||
$DB->delete_records('tool_emailutils_suppression'); | ||
|
||
foreach ($suppressionlist as $item) { | ||
$record = new \stdClass(); | ||
$record->email = $item['email']; | ||
$record->reason = $item['reason']; | ||
$record->created_at = $item['created_at']; | ||
$record->timecreated = time(); | ||
$record->timemodified = time(); | ||
|
||
$DB->insert_record('tool_emailutils_suppression', $record); | ||
} | ||
} | ||
|
||
/** | ||
* Fetch the suppression list from AWS SES. | ||
* | ||
* This method connects to AWS SES, retrieves the suppression list, | ||
* and formats it for local storage. It includes error handling and | ||
* retries for rate limiting. | ||
* | ||
* @return array The fetched suppression list. | ||
*/ | ||
protected function fetch_aws_ses_suppression_list(): array { | ||
if (!$this->sesclient) { | ||
$this->sesclient = $this->create_ses_client(); | ||
} | ||
|
||
try { | ||
$suppressionlist = []; | ||
$params = ['MaxItems' => 100]; | ||
|
||
do { | ||
$result = $this->sesclient->listSuppressedDestinations($params); | ||
foreach ($result['SuppressedDestinationSummaries'] as $item) { | ||
$suppressionlist[] = [ | ||
'email' => $item['EmailAddress'], | ||
'reason' => $item['Reason'], | ||
'created_at' => $item['LastUpdateTime']->format('Y-m-d H:i:s'), | ||
]; | ||
} | ||
$params['NextToken'] = $result['NextToken'] ?? null; | ||
} while ($params['NextToken']); | ||
|
||
return $suppressionlist; | ||
} catch (\Exception $e) { | ||
$this->log_error('Error fetching suppression list: ' . $e->getMessage()); | ||
return []; | ||
} | ||
} | ||
|
||
/** | ||
* Create an SES client instance. | ||
* | ||
* @return \Aws\SesV2\SesV2Client | ||
*/ | ||
protected function create_ses_client(): \Aws\SesV2\SesV2Client { | ||
global $CFG; | ||
|
||
$awsregion = get_config('tool_emailutils', 'aws_region'); | ||
$awskey = get_config('tool_emailutils', 'aws_key'); | ||
$awssecret = get_config('tool_emailutils', 'aws_secret'); | ||
|
||
if (empty($awsregion) || empty($awskey) || empty($awssecret)) { | ||
throw new \Exception('AWS credentials are not configured.'); | ||
} | ||
|
||
return new \Aws\SesV2\SesV2Client([ | ||
'version' => 'latest', | ||
'region' => $awsregion, | ||
'credentials' => [ | ||
'key' => $awskey, | ||
'secret' => $awssecret, | ||
], | ||
'retries' => [ | ||
'mode' => 'adaptive', | ||
'max_attempts' => 10, | ||
], | ||
]); | ||
} | ||
|
||
/** | ||
* Log an error message, printing to console if running via CLI. | ||
* | ||
* This method logs error messages, ensuring they are visible both in | ||
* the Moodle error log and on the console when run via CLI. | ||
* | ||
* @param string $message The error message to log. | ||
* @return void | ||
*/ | ||
private function log_error(string $message): void { | ||
if (CLI_SCRIPT) { | ||
mtrace($message); | ||
} | ||
debugging($message); | ||
} | ||
|
||
/** | ||
* Set the SES client (for testing purposes). | ||
* | ||
* @param \Aws\SesV2\SesV2Client $client | ||
*/ | ||
public function set_ses_client(\Aws\SesV2\SesV2Client $client): void { | ||
$this->sesclient = $client; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?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/>. | ||
|
||
/** | ||
* Definition of Email utils scheduled tasks. | ||
* | ||
* @package tool_emailutils | ||
* @copyright 2024 onwards Catalyst IT {@link http://www.catalyst-eu.net/} | ||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | ||
* @author Waleed ul hassan <[email protected]> | ||
*/ | ||
|
||
defined('MOODLE_INTERNAL') || die(); | ||
|
||
$tasks = [ | ||
[ | ||
'classname' => 'tool_emailutils\task\update_suppression_list', | ||
'blocking' => 0, | ||
'minute' => 'R', | ||
'hour' => '3', | ||
'day' => '*', | ||
'month' => '*', | ||
'dayofweek' => '*', | ||
], | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/>. | ||
|
||
/** | ||
* Email utils plugin upgrade code. | ||
* | ||
* @package tool_emailutils | ||
* @copyright 2024 onwards Catalyst IT {@link http://www.catalyst-eu.net/} | ||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | ||
* @author Waleed ul hassan <[email protected]> | ||
*/ | ||
|
||
/** | ||
* Upgrade script for the email utilities tool plugin. | ||
* | ||
* This function is executed during the plugin upgrade process. | ||
* It checks the current version of the plugin and applies | ||
* necessary upgrades, such as creating new database tables | ||
* or modifying existing structures. | ||
* | ||
* @param int $oldversion The version we are upgrading from. | ||
* @return bool Always returns true. | ||
*/ | ||
function xmldb_tool_emailutils_upgrade($oldversion) { | ||
global $DB; | ||
$dbman = $DB->get_manager(); | ||
|
||
if ($oldversion < 2024100101) { | ||
|
||
// Define table tool_emailutils_suppression to be created. | ||
$table = new xmldb_table('tool_emailutils_suppression'); | ||
|
||
// Adding fields to table tool_emailutils_suppression. | ||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); | ||
$table->add_field('email', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); | ||
$table->add_field('reason', XMLDB_TYPE_CHAR, '50', null, XMLDB_NOTNULL, null, null); | ||
$table->add_field('created_at', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null); | ||
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | ||
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); | ||
|
||
// Adding keys to table tool_emailutils_suppression. | ||
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); | ||
|
||
// Conditionally launch create table for tool_emailutils_suppression. | ||
if (!$dbman->table_exists($table)) { | ||
$dbman->create_table($table); | ||
} | ||
|
||
// Emailutils savepoint reached. | ||
upgrade_plugin_savepoint(true, 2024100101, 'tool', 'emailutils'); | ||
} | ||
|
||
return true; | ||
} |
Oops, something went wrong.