Skip to content

Commit

Permalink
MDL-81924 core_sms: Add SMS gateway management UI
Browse files Browse the repository at this point in the history
Originally implemented as MDL-81732.

Co-authored by: Michael Hawkins <michaelh@moodle.com>
  • Loading branch information
safatshahin authored and HuongNV13 committed Sep 23, 2024
1 parent 3348832 commit b5ac325
Show file tree
Hide file tree
Showing 29 changed files with 1,510 additions and 38 deletions.
31 changes: 31 additions & 0 deletions admin/settings/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,37 @@
}
}

// SMS plugins.
if ($hassiteconfig) {
$ADMIN->add(
'modules',
new admin_category(
'sms',
new lang_string('sms', 'core_sms'),
),
);
$ADMIN->add(
'sms',
new admin_externalpage(
'smsgateway',
new lang_string('manage_sms_gateways', 'core_sms'),
$CFG->wwwroot . '/sms/sms_gateways.php',
),
);
foreach (core_component::get_plugin_list('smsgateway') as $plugin => $path) {
$settingspath = $path . '/settings.php';
if (file_exists($settingspath)) {
$settings = new admin_settingpage(
'smsgateway_' . $plugin . '_settings',
new lang_string('pluginname', 'smsgateway_' . $plugin),
'moodle/site:config',
);
include($settingspath);
$ADMIN->add('smsgateway', $settings);
}
}
}

// Content bank content types.
if ($hassiteconfig) {
$ADMIN->add('modules', new admin_category('contentbanksettings', new lang_string('contentbank')));
Expand Down
12 changes: 11 additions & 1 deletion admin/tool/mfa/factor/sms/tests/behat/factor_sms_login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ Feature: Login user with sms authentication factor

Background:
Given I log in as "admin"
And the following "core_sms > sms_gateways" exist:
| name | classname | enabled | config |
| Dummy gateway | smsgateway_aws\gateway | 1 | {"countrycode":"+61", "gateway":"aws_sns", "api_region":"ap-southeast-2", "api_key":"abc", "api_secret":"123"} |
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 |
| enabled | 1 | factor_sms |
| weight | 100 | factor_sms |
| duration | 1800 | factor_sms |
And I navigate to "Plugins > Admin tools > Multi-factor authentication" in site administration
And I follow "Edit settings for the SMS mobile phone factor"
And I set the field "SMS gateway" to "Dummy gateway (AWS)"
And I press "Save changes"
And I should see "Changes saved"
# 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"
Expand Down
18 changes: 17 additions & 1 deletion admin/tool/mfa/factor/sms/tests/behat/factor_sms_setup.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,26 @@ Feature: Set up SMS factor in user preferences

Background:
Given I log in as "admin"
And I navigate to "Plugins > SMS > Manage SMS gateways" in site administration
And I follow "Create a new SMS gateway"
And I set the following fields to these values:
| SMS gateway provider | AWS |
| Gateway name | Dummy gateway |
| Access key | key123 |
| Secret access key | secret456 |
And I press "Save changes"
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 |
| enabled | 1 | factor_sms |
| weight | 100 | factor_sms |
| duration | 1800 | factor_sms |
And I navigate to "Plugins > Admin tools > Multi-factor authentication" in site administration
And I follow "Edit settings for the SMS mobile phone factor"
And I set the field "SMS gateway" to "Dummy gateway (AWS)"
And I press "Save changes"
And I should see "Changes saved"
When I follow "Preferences" in the user menu
And I click on "Multi-factor authentication preferences" "link"
And I click on "Set up" "button"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@tool @tool_mfa @factor_sms
Feature: Set up SMS factor when relevant gateway is not configured
In order configure the SMS factor
As an admin
I want to be directed to the SMS gateway setup when necessary

Scenario: Configuring gateways from the SMS factor settings
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 |
| weight | 100 | factor_sms |
| duration | 1800 | factor_sms |
When I navigate to "Plugins > Admin tools > Multi-factor authentication" in site administration
And I follow "Edit settings for the SMS mobile phone factor"
Then I should see "To use SMS as an authentication factor, you first need to set up an SMS gateway."
And I should see "set up an SMS gateway"
And I follow "set up an SMS gateway"
And I should see "Configure SMS gateway"
And I set the following fields to these values:
| SMS gateway provider | AWS |
| Gateway name | First AWS gateway |
| Country code | 61 |
| Access key | key123 |
| Secret access key | secret456 |
| Amazon API gateway region | ap-southeast-2 |
And I press "Save changes"
And I should see "SMS mobile phone"
And the "SMS gateway" select box should contain "First AWS gateway (AWS)"
And I follow "create a new gateway"
And I should see "Configure SMS gateway"
And I set the following fields to these values:
| SMS gateway provider | AWS |
| Gateway name | Second one |
| Country code | 1 |
| Access key | key1234 |
| Secret access key | secret4567 |
| Amazon API gateway region | ap-southeast-2 |
And I press "Save changes"
And I should see "SMS mobile phone"
And the "SMS gateway" select box should contain "First AWS gateway (AWS)"
And the "SMS gateway" select box should contain "Second one (AWS)"
16 changes: 16 additions & 0 deletions lang/en/sms.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@
* @copyright 2024 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['actions'] = 'Actions';
$string['configure_sms_gateway'] = 'Configure SMS gateway';
$string['countrycode'] = 'Country code';
$string['countrycode_help'] = 'Set the default phone number format to exclude the "+" symbol if user does not enter an international number with it.';
$string['createnewgateway'] = 'Create a new SMS gateway';
$string['delete_sms_gateway'] = 'Delete SMS gateway';
$string['delete_sms_gateway_confirmation'] = 'Are you sure you want to delete the {$a->gateway} SMS gateway?';
$string['gateway'] = 'Gateway';
$string['gateway_name'] = 'Gateway name';
$string['manage_sms_gateways'] = 'Manage SMS gateways';
$string['phonenumbernotvalid'] = 'Format of phone number not recognised: {$a->message}';
$string['privacy:metadata:sms_messages'] = 'Stores messages sent via SMS';
$string['privacy:metadata:sms_messages:content'] = 'The message text';
Expand All @@ -32,10 +42,16 @@
$string['privacy:metadata:sms_messages:timecreated'] = 'The time the message was created';
$string['privacy:sms:sensitive_not_shown'] = 'The content of this message was not stored as it was marked as containing sensitive content.';
$string['sms'] = 'SMS';
$string['sms_form_information'] = 'This page allow you to set up and manage your SMS gateway for sending text messages.';
$string['status:gateway_failed'] = 'The gateway has failed to send the message';
$string['status:gateway_not_available'] = 'The gateway is not available to send the message';
$string['status:gateway_queued'] = 'The message is queued to be sent by the gateway';
$string['status:gateway_rejected'] = 'The gateway has rejected the message';
$string['status:gateway_sent'] = 'The message has been sent by the gateway';
$string['status:message_over_size'] = 'The message is too large to be sent by the gateway';
$string['status:unknown'] = 'Unable to determine the status of the message';
$string['sms_gateways'] = 'SMS gateways';
$string['sms_gateway_deleted'] = '{$a->gateway} SMS gateway has been deleted';
$string['sms_gateway_delete_failed'] = 'Cannot delete the {$a->gateway} SMS gateway. The gateway is either in use or there\'s a database issue. Check if the gateway is active or contact your database administrator for help.';
$string['sms_gateway_disable_failed'] = 'Cannot disable the SMS gateway. The gateway is either in use or there\'s a database issue. Check if the gateway is active or contact your database administrator for help.';
$string['select_sms_gateways'] = 'SMS gateway provider';
6 changes: 6 additions & 0 deletions lib/db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -3264,6 +3264,12 @@
'type' => 'write',
'ajax' => true,
],
'core_sms_set_gateway_status' => [
'classname' => 'core_sms\external\sms_gateway_status',
'description' => 'Set the sms gateway status',
'type' => 'write',
'ajax' => true,
],
);

$services = array(
Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@
<directory suffix="_test.php">ai/tests</directory>
<exclude>ai/tests/classes</exclude>
</testsuite>
<testsuite name="core_sms_testsuite">
<directory suffix="_test.php">sms/tests</directory>
</testsuite>

<!--Plugin suites: use admin/tool/phpunit/cli/util.php to build phpunit.xml from
phpunit.xml.dist with up-to-date list of plugins in current install-->
Expand Down
11 changes: 11 additions & 0 deletions sms/amd/build/smsgatewaychooser.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sms/amd/build/smsgatewaychooser.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions sms/amd/src/smsgatewaychooser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

// 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 selection handler.
*
* @module core_sms/smsgatewaychooser
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

const Selectors = {
fields: {
selector: '[data-smsgatewaychooser-field="selector"]',
updateButton: '[data-smsgatewaychooser-field="updateButton"]',
},
};

/**
* Initialise the sms gateway chooser.
*/
export const init = () => {
document.querySelector(Selectors.fields.selector)?.addEventListener('change', e => {
const form = e.target.closest('form');
const updateButton = form.querySelector(Selectors.fields.updateButton);
const url = new URL(form.action);

form.action = url.toString();
updateButton.click();
});
};
108 changes: 108 additions & 0 deletions sms/classes/external/sms_gateway_status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?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 core_sms\external;

use context_system;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;

/**
* Webservice to enable or disable sms gateway.
*
* @package core_sms
* @copyright 2024 Safat Shahin <safat.shahin@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class sms_gateway_status extends external_api {

public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_INT, 'Gateway ID', VALUE_REQUIRED),
'state' => new external_value(PARAM_INT, 'Enabled or disabled', VALUE_REQUIRED),
]);
}

public static function execute(int $plugin, int $state): array {
// Parameter validation.
[
'plugin' => $gatewayid,
'state' => $state,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'state' => $state,
]);

$context = context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);

$result = [
'result' => true,
'message' => '',
'messagetype' => '',
];
$manager = \core\di::get(\core_sms\manager::class);
$gatewaymanagers = $manager->get_gateway_instances(['id' => $gatewayid]);
$gatewaymanager = reset($gatewaymanagers);

if (!$gatewaymanager) {
$result = [
'result' => false,
'message' => 'sms_gateway_not_found',
'messagetype' => 'error'
];
return $result;
}

if (!empty($state)) {
$manager->enable_gateway(gateway: $gatewaymanager);
$message = get_string('plugin_enabled', 'core_admin', $gatewaymanager->name);
$messagetype = \core\notification::SUCCESS;
} else {
$gatewayresult = $manager->disable_gateway(gateway: $gatewaymanager);
if ($gatewayresult->enabled) {
$result = [
'result' => false,
'message' => 'sms_gateway_disable_failed',
'messagetype' => 'error'
];
$message = get_string('sms_gateway_disable_failed', 'core_sms');
$messagetype = \core\notification::ERROR;
} else {
$message = get_string('plugin_disabled', 'core_admin', $gatewaymanager->name);
$messagetype = \core\notification::SUCCESS;
}
}

\core\notification::add($message, $messagetype);

return $result;
}

public static function execute_returns(): external_single_structure {
return new external_single_structure(
[
'result' => new external_value(PARAM_BOOL, 'Whether the status was changed, true or false'),
'message' => new external_value(PARAM_TEXT, 'Messages'),
'messagetype' => new external_value(PARAM_TEXT, 'Message type'),
]
);
}

}
Loading

0 comments on commit b5ac325

Please sign in to comment.