Merge branch 'MDL-40050-master' of git://github.com/FMCorz/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 30 Sep 2013 19:55:41 +0000 (21:55 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 30 Sep 2013 19:55:41 +0000 (21:55 +0200)
15 files changed:
admin/webservice/service.php
admin/webservice/service_users.php
lang/en/webservice.php
lib/classes/event/webservice_function_called.php [new file with mode: 0644]
lib/classes/event/webservice_login_failed.php [new file with mode: 0644]
lib/classes/event/webservice_service_created.php [new file with mode: 0644]
lib/classes/event/webservice_service_deleted.php [new file with mode: 0644]
lib/classes/event/webservice_service_updated.php [new file with mode: 0644]
lib/classes/event/webservice_service_user_added.php [new file with mode: 0644]
lib/classes/event/webservice_service_user_removed.php [new file with mode: 0644]
lib/classes/event/webservice_token_created.php [new file with mode: 0644]
lib/classes/event/webservice_token_sent.php [new file with mode: 0644]
login/token.php
webservice/lib.php
webservice/tests/events.php [new file with mode: 0644]

index a933ec4..13f3c8d 100644 (file)
@@ -58,7 +58,12 @@ if ($action == 'delete' and confirm_sesskey() and $service and empty($service->c
     }
     //The user has confirmed the deletion, delete and redirect
     $webservicemanager->delete_service($service->id);
-    add_to_log(SITEID, 'webservice', 'delete', $returnurl, get_string('deleteservice', 'webservice', $service));
+    $params = array(
+        'objectid' => $service->id
+    );
+    $event = \core\event\webservice_service_deleted::create($params);
+    $event->add_record_snapshot('external_services', $service);
+    $event->trigger();
     redirect($returnurl);
 }
 
@@ -75,7 +80,12 @@ if ($mform->is_cancelled()) {
     //create operation
     if (empty($servicedata->id)) {
         $servicedata->id = $webservicemanager->add_external_service($servicedata);
-        add_to_log(SITEID, 'webservice', 'add', $returnurl, get_string('addservice', 'webservice', $servicedata));
+        $params = array(
+            'objectid' => $servicedata->id
+        );
+        $event = \core\event\webservice_service_updated::create($params);
+        $event->add_record_snapshot('external_services', $servicedata);
+        $event->trigger();
 
         //redirect to the 'add functions to service' page
         $addfunctionpage = new moodle_url(
@@ -85,7 +95,12 @@ if ($mform->is_cancelled()) {
     } else {
         //update operation
         $webservicemanager->update_external_service($servicedata);
-        add_to_log(SITEID, 'webservice', 'edit', $returnurl, get_string('editservice', 'webservice', $servicedata));
+        $params = array(
+            'objectid' => $servicedata->id
+        );
+        $event = \core\event\webservice_service_created::create($params);
+        $event->add_record_snapshot('external_services', $servicedata);
+        $event->trigger();
     }
 
     redirect($returnurl);
index ad67c66..907a4cc 100644 (file)
@@ -57,8 +57,13 @@ if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
             $serviceuser->externalserviceid = $id;
             $serviceuser->userid = $adduser->id;
             $webservicemanager->add_ws_authorised_user($serviceuser);
-            add_to_log(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id='
-                    . $id, 'add', '', $adduser->id);
+
+            $params = array(
+                'objectid' => $serviceuser->externalserviceid,
+                'relateduserid' => $serviceuser->userid
+            );
+            $event = \core\event\webservice_service_user_added::create($params);
+            $event->trigger();
         }
         $potentialuserselector->invalidate_selected_users();
         $alloweduserselector->invalidate_selected_users();
@@ -71,8 +76,13 @@ if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) {
     if (!empty($userstoremove)) {
         foreach ($userstoremove as $removeuser) {
             $webservicemanager->remove_ws_authorised_user($removeuser, $id);
-            add_to_log(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id='
-                    . $id, 'remove', '', $removeuser->id);
+
+            $params = array(
+                'objectid' => $id,
+                'relateduserid' => $removeuser->id
+            );
+            $event = \core\event\webservice_service_user_removed::create($params);
+            $event->trigger();
         }
         $potentialuserselector->invalidate_selected_users();
         $alloweduserselector->invalidate_selected_users();
index 83cdb58..52966b2 100644 (file)
@@ -82,6 +82,14 @@ $string['errorcoursecontextnotvalid'] = 'You cannot execute functions in the cou
 $string['errorinvalidparam'] = 'The param "{$a}" is invalid.';
 $string['errornotemptydefaultparamarray'] = 'The web service description parameter named \'{$a}\' is an single or multiple structure. The default can only be empty array. Check web service description.';
 $string['erroroptionalparamarray'] = 'The web service description parameter named \'{$a}\' is an single or multiple structure. It can not be set as VALUE_OPTIONAL. Check web service description.';
+$string['event_webservice_function_called'] = 'Web service function called';
+$string['event_webservice_login_failed'] = 'Web service login failed';
+$string['event_webservice_service_created'] = 'Web service service created';
+$string['event_webservice_service_updated'] = 'Web service service updated';
+$string['event_webservice_service_user_added'] = 'Web service service user added';
+$string['event_webservice_service_user_removed'] = 'Web service service user removed';
+$string['event_webservice_token_created'] = 'Web service token created';
+$string['event_webservice_token_sent'] = 'Web service token sent';
 $string['execute'] = 'Execute';
 $string['executewarnign'] = 'WARNING: If you press execute your database will be modified and changes can not be reverted automatically!';
 $string['externalservice'] = 'External service';
diff --git a/lib/classes/event/webservice_function_called.php b/lib/classes/event/webservice_function_called.php
new file mode 100644 (file)
index 0000000..9914385
--- /dev/null
@@ -0,0 +1,101 @@
+<?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/>.
+
+/**
+ * core webservice function_called event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice function_called event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_function_called extends \core\event\base {
+
+    /**
+     * Legacy log data.
+     */
+    protected $legacylogdata;
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service function '{$this->other['function']}' has been called.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        return $this->legacylogdata;
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_function_called', 'webservice');
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->context = \context_system::instance();
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return void
+     */
+    public function set_legacy_logdata($legacydata) {
+        $this->legacylogdata = $legacydata;
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->other['function'])) {
+           throw new \coding_exception('The key \'function\' needs to be set in $other.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_login_failed.php b/lib/classes/event/webservice_login_failed.php
new file mode 100644 (file)
index 0000000..02c49a3
--- /dev/null
@@ -0,0 +1,107 @@
+<?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/>.
+
+/**
+ * core web service login failed event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core web service login_failed event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_login_failed extends \core\event\base {
+
+    /**
+     * Legacy log data.
+     *
+     * @var null|array
+     */
+    protected $legacylogdata;
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "Web service authentication failed with code: {$this->other['reason']}.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        return $this->legacylogdata;
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_login_failed', 'webservice');
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->context = \context_system::instance();
+    }
+
+    /**
+     * Set the legacy event log data.
+     *
+     * @param array $logdata The log data.
+     * @return void
+     */
+    public function set_legacy_logdata($logdata) {
+        $this->legacylogdata = $logdata;
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->other['reason'])) {
+           throw new \coding_exception('The key \'reason\' needs to be set in $other.');
+        } else if (!isset($this->other['method'])) {
+           throw new \coding_exception('The key \'method\' needs to be set in $other.');
+        } else if (!isset($this->other['token']) && !isset($this->other['tokenid']) && !isset($this->other['username'])) {
+           throw new \coding_exception('The keys \'username\', \'token\' or \'tokenid\' need to be set in $other.');
+        }
+    }
+}
diff --git a/lib/classes/event/webservice_service_created.php b/lib/classes/event/webservice_service_created.php
new file mode 100644 (file)
index 0000000..436a236
--- /dev/null
@@ -0,0 +1,88 @@
+<?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/>.
+
+/**
+ * core webservice service created event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service created event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_created extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service service $this->objectid has been created by user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        $service = $this->get_record_snapshot('external_services', $this->objectid);
+        return array(SITEID, 'webservice', 'add', $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices",
+            get_string('addservice', 'webservice', $service));
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_created', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'externalservices'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_deleted.php b/lib/classes/event/webservice_service_deleted.php
new file mode 100644 (file)
index 0000000..4c497d9
--- /dev/null
@@ -0,0 +1,88 @@
+<?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/>.
+
+/**
+ * core webservice service deleted event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service deleted event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_deleted extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service service $this->objectid has been deleted by user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        $service = $this->get_record_snapshot('external_services', $this->objectid);
+        return array(SITEID, 'webservice', 'delete', $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices",
+            get_string('deleteservice', 'webservice', $service));
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_deleted', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'externalservices'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'd';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_updated.php b/lib/classes/event/webservice_service_updated.php
new file mode 100644 (file)
index 0000000..0b82da7
--- /dev/null
@@ -0,0 +1,97 @@
+<?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/>.
+
+/**
+ * core webservice service updated event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service updated event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_updated extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The web service service $this->objectid has been updated by user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        $service = $this->get_record_snapshot('external_services', $this->objectid);
+        return array(SITEID, 'webservice', 'edit', $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices",
+            get_string('editservice', 'webservice', $service));
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_updated', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'externalservices'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'u';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+    /**
+     * Set the legacy event log data.
+     *
+     * @return void
+     */
+    public function set_legacy_logdata($legacylogdata) {
+        $this->legacylogdata = $legacylogdata;
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_user_added.php b/lib/classes/event/webservice_service_user_added.php
new file mode 100644 (file)
index 0000000..38309fb
--- /dev/null
@@ -0,0 +1,98 @@
+<?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/>.
+
+/**
+ * core webservice service user added event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service user added event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_user_added extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The user $this->relateduserid has been added to the web service service $this->objectid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        return array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $this->objectid, 'add', '',
+            $this->relateduserid);
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_user_added', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/webservice/service_users.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('The relateduserid must be set.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_service_user_removed.php b/lib/classes/event/webservice_service_user_removed.php
new file mode 100644 (file)
index 0000000..a0f7eec
--- /dev/null
@@ -0,0 +1,98 @@
+<?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/>.
+
+/**
+ * core webservice service user removed event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice service user removed event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_service_user_removed extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The user $this->relateduserid has been removed to the web service service $this->objectid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        global $CFG;
+        return array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $this->objectid, 'remove', '',
+            $this->relateduserid);
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_service_user_removed', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/webservice/service_users.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'd';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_services';
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('The relateduserid must be set.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_token_created.php b/lib/classes/event/webservice_token_created.php
new file mode 100644 (file)
index 0000000..5f18336
--- /dev/null
@@ -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/>.
+
+/**
+ * core webservice token_created event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice token_created event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_token_created extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "A web service token has been created for the user $this->relateduserid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        if (!empty($this->other['auto'])) {
+            // The token has been automatically created.
+            return array(SITEID, 'webservice', 'automatically create user token', '' , 'User ID: ' . $this->relateduserid);
+        }
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_token_created', 'webservice');
+    }
+
+    /**
+     * Get URL related to the action.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/admin/settings.php', array('section' => 'webservicetokens'));
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_tokens';
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        if (!isset($this->relateduserid)) {
+           throw new \coding_exception('The property \'relateduserid\' must be set.');
+        }
+    }
+
+}
diff --git a/lib/classes/event/webservice_token_sent.php b/lib/classes/event/webservice_token_sent.php
new file mode 100644 (file)
index 0000000..51775bd
--- /dev/null
@@ -0,0 +1,76 @@
+<?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/>.
+
+/**
+ * core webservice token_sent event.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\event;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * core webservice token sent event class.
+ *
+ * @package    core
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_token_sent extends \core\event\base {
+
+    /**
+     * Returns description of what happened.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return "The token $this->objectid has been sent to the user $this->userid.";
+    }
+
+    /**
+     * Return the legacy event log data.
+     *
+     * @return array|null
+     */
+    protected function get_legacy_logdata() {
+        return array(SITEID, 'webservice', 'sending requested user token', '' , 'User ID: ' . $this->userid);
+    }
+
+    /**
+     * Return localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('event_webservice_token_sent', 'webservice');
+    }
+
+    /**
+     * Init method.
+     *
+     * @return void
+     */
+    protected function init() {
+        $this->context = \context_system::instance();
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+        $this->data['objecttable'] = 'external_tokens';
+    }
+
+}
index 9fd88b0..919b97c 100644 (file)
@@ -150,7 +150,8 @@ if (!empty($user)) {
                 or (!is_siteadmin($user) && has_capability('moodle/webservice:createtoken', context_system::instance()))) {
             // if service doesn't exist, dml will throw exception
             $service_record = $DB->get_record('external_services', array('shortname'=>$serviceshortname, 'enabled'=>1), '*', MUST_EXIST);
-            // create a new token
+
+            // Create a new token.
             $token = new stdClass;
             $token->token = md5(uniqid(rand(), 1));
             $token->userid = $user->id;
@@ -159,9 +160,18 @@ if (!empty($user)) {
             $token->creatorid = $user->id;
             $token->timecreated = time();
             $token->externalserviceid = $service_record->id;
-            $tokenid = $DB->insert_record('external_tokens', $token);
-            add_to_log(SITEID, 'webservice', 'automatically create user token', '' , 'User ID: ' . $user->id);
-            $token->id = $tokenid;
+            $token->id = $DB->insert_record('external_tokens', $token);
+
+            $params = array(
+                'objectid' => $token->id,
+                'relateduserid' => $user->id,
+                'other' => array(
+                    'auto' => true
+                )
+            );
+            $event = \core\event\webservice_token_created::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->trigger();
         } else {
             throw new moodle_exception('cannotcreatetoken', 'webservice', '', $serviceshortname);
         }
@@ -170,7 +180,12 @@ if (!empty($user)) {
     // log token access
     $DB->set_field('external_tokens', 'lastaccess', time(), array('id'=>$token->id));
 
-    add_to_log(SITEID, 'webservice', 'sending requested user token', '' , 'User ID: ' . $user->id);
+    $params = array(
+        'objectid' => $token->id,
+    );
+    $event = \core\event\webservice_token_sent::create($params);
+    $event->add_record_snapshot('external_tokens', $token);
+    $event->trigger();
 
     $usertoken = new stdClass;
     $usertoken->token = $token->token;
index 1723d72..56d437a 100644 (file)
@@ -69,16 +69,36 @@ class webservice {
             throw new moodle_exception('invalidtoken', 'webservice');
         }
 
+        $loginfaileddefaultparams = array(
+            'other' => array(
+                'method' => WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN,
+                'reason' => null,
+                'tokenid' => $token->id
+            )
+        );
+
         // Validate token date
         if ($token->validuntil and $token->validuntil < time()) {
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '', get_string('invalidtimedtoken', 'webservice'), 0);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'token_expired';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '',
+                get_string('invalidtimedtoken', 'webservice'), 0));
+            $event->trigger();
             $DB->delete_records('external_tokens', array('token' => $token->token));
             throw new webservice_access_exception('Invalid token - token expired - check validuntil time for the token');
         }
 
         // Check ip
         if ($token->iprestriction and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '', get_string('failedtolog', 'webservice') . ": " . getremoteaddr(), 0);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'ip_restricted';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '',
+                get_string('failedtolog', 'webservice') . ": " . getremoteaddr(), 0));
+            $event->trigger();
             throw new webservice_access_exception('Invalid token - IP:' . getremoteaddr()
                     . ' is not supported');
         }
@@ -141,19 +161,34 @@ class webservice {
 
         //only confirmed user should be able to call web service
         if (empty($user->confirmed)) {
-            add_to_log(SITEID, 'webservice', 'user unconfirmed', '', $user->username);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_unconfirmed';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', 'user unconfirmed', '', $user->username));
+            $event->trigger();
             throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username);
         }
 
         //check the user is suspended
         if (!empty($user->suspended)) {
-            add_to_log(SITEID, 'webservice', 'user suspended', '', $user->username);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_suspended';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', 'user suspended', '', $user->username));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for suspended username: ' . $user->username);
         }
 
         //check if the auth method is nologin (in this case refuse connection)
         if ($user->auth == 'nologin') {
-            add_to_log(SITEID, 'webservice', 'nologin auth attempt with web service', '', $user->username);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'nologin';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', 'nologin auth attempt with web service', '', $user->username));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for nologin authentication username: ' . $user->username);
         }
 
@@ -162,7 +197,12 @@ class webservice {
         if (!empty($auth->config->expiration) and $auth->config->expiration == 1) {
             $days2expire = $auth->password_expire($user->username);
             if (intval($days2expire) < 0) {
-                add_to_log(SITEID, 'webservice', 'expired password', '', $user->username);
+                $params = $loginfaileddefaultparams;
+                $params['other']['reason'] = 'password_expired';
+                $event = \core\event\webservice_login_failed::create($params);
+                $event->add_record_snapshot('external_tokens', $token);
+                $event->set_legacy_logdata(array(SITEID, 'webservice', 'expired password', '', $user->username));
+                $event->trigger();
                 throw new moodle_exception('passwordisexpired', 'webservice');
             }
         }
@@ -822,6 +862,15 @@ abstract class webservice_server implements webservice_server_interface {
             throw new coding_exception('Cookies must be disabled in WS servers!');
         }
 
+        $loginfaileddefaultparams = array(
+            'context' => context_system::instance(),
+            'other' => array(
+                'method' => $this->authmethod,
+                'reason' => null,
+                'token' => $this->token
+            )
+        );
+
         if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) {
 
             //we check that authentication plugin is enabled
@@ -845,8 +894,16 @@ abstract class webservice_server implements webservice_server_interface {
             }
 
             if (!$auth->user_login_webservice($this->username, $this->password)) {
-                // log failed login attempts
-                add_to_log(SITEID, 'webservice', get_string('simpleauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".$this->username."/".$this->password." - ".getremoteaddr() , 0);
+
+                // Log failed login attempts.
+                $params = $loginfaileddefaultparams;
+                $params['other']['reason'] = 'password';
+                $params['other']['username'] = $this->username;
+                $event = \core\event\webservice_login_failed::create($params);
+                $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('simpleauthlog', 'webservice'), '' ,
+                    get_string('failedtolog', 'webservice').": ".$this->username."/".$this->password." - ".getremoteaddr() , 0));
+                $event->trigger();
+
                 throw new moodle_exception('wrongusernamepassword', 'webservice');
             }
 
@@ -866,19 +923,37 @@ abstract class webservice_server implements webservice_server_interface {
 
         //only confirmed user should be able to call web service
         if (!empty($user->deleted)) {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessuserdeleted', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_deleted';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserdeleted', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for deleted username: ' . $user->username);
         }
 
         //only confirmed user should be able to call web service
         if (empty($user->confirmed)) {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessuserunconfirmed', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_unconfirmed';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserunconfirmed', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new moodle_exception('wsaccessuserunconfirmed', 'webservice', '', $user->username);
         }
 
         //check the user is suspended
         if (!empty($user->suspended)) {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessusersuspended', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'user_unconfirmed';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessusersuspended', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for suspended username: ' . $user->username);
         }
 
@@ -891,14 +966,26 @@ abstract class webservice_server implements webservice_server_interface {
         if (!empty($auth->config->expiration) and $auth->config->expiration == 1) {
             $days2expire = $auth->password_expire($user->username);
             if (intval($days2expire) < 0 ) {
-                add_to_log(SITEID, '', '', '', get_string('wsaccessuserexpired', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+                $params = $loginfaileddefaultparams;
+                $params['other']['reason'] = 'password_expired';
+                $params['other']['username'] = $user->username;
+                $event = \core\event\webservice_login_failed::create($params);
+                $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessuserexpired', 'webservice',
+                    $user->username) . " - ".getremoteaddr(), 0, $user->id));
+                $event->trigger();
                 throw new webservice_access_exception('Refused web service access for password expired username: ' . $user->username);
             }
         }
 
         //check if the auth method is nologin (in this case refuse connection)
         if ($user->auth=='nologin') {
-            add_to_log(SITEID, '', '', '', get_string('wsaccessusernologin', 'webservice', $user->username) . " - ".getremoteaddr(), 0, $user->id);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'login';
+            $params['other']['username'] = $user->username;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, '', '', '', get_string('wsaccessusernologin', 'webservice',
+                $user->username) . " - ".getremoteaddr(), 0, $user->id));
+            $event->trigger();
             throw new webservice_access_exception('Refused web service access for nologin authentication username: ' . $user->username);
         }
 
@@ -923,9 +1010,24 @@ abstract class webservice_server implements webservice_server_interface {
      */
     protected function authenticate_by_token($tokentype){
         global $DB;
+
+        $loginfaileddefaultparams = array(
+            'context' => context_system::instance(),
+            'other' => array(
+                'method' => $this->authmethod,
+                'reason' => null,
+                'token' => $this->token
+            )
+        );
+
         if (!$token = $DB->get_record('external_tokens', array('token'=>$this->token, 'tokentype'=>$tokentype))) {
-            // log failed login attempts
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".$this->token. " - ".getremoteaddr() , 0);
+            // Log failed login attempts.
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'invalid_token';
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' ,
+                get_string('failedtolog', 'webservice').": ".$this->token. " - ".getremoteaddr() , 0));
+            $event->trigger();
             throw new moodle_exception('invalidtoken', 'webservice');
         }
 
@@ -942,7 +1044,14 @@ abstract class webservice_server implements webservice_server_interface {
         }
 
         if ($token->iprestriction and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
-            add_to_log(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' , get_string('failedtolog', 'webservice').": ".getremoteaddr() , 0);
+            $params = $loginfaileddefaultparams;
+            $params['other']['reason'] = 'ip_restricted';
+            $params['other']['tokenid'] = $token->id;
+            $event = \core\event\webservice_login_failed::create($params);
+            $event->add_record_snapshot('external_tokens', $token);
+            $event->set_legacy_logdata(array(SITEID, 'webservice', get_string('tokenauthlog', 'webservice'), '' ,
+                get_string('failedtolog', 'webservice').": ".getremoteaddr() , 0));
+            $event->trigger();
             throw new webservice_access_exception('Invalid service - IP:' . getremoteaddr()
                     . ' is not supported - check this allowed user');
         }
@@ -1055,8 +1164,15 @@ abstract class webservice_zend_server extends webservice_server {
         // tell server what functions are available
         $this->zend_server->setClass($this->service_class);
 
-        //log the web service request
-        add_to_log(SITEID, 'webservice', '', '' , $this->zend_class." ".getremoteaddr() , 0, $this->userid);
+        // Log the web service request.
+        $params = array(
+            'other' => array(
+                'function' => 'unknown'
+            )
+        );
+        $event = \core\event\webservice_function_called::create($params);
+        $event->set_legacy_logdata(array(SITEID, 'webservice', '', '', $this->zend_class.' '.getremoteaddr(), 0, $this->userid));
+        $event->trigger();
 
         //send headers
         $this->send_headers();
@@ -1516,8 +1632,15 @@ abstract class webservice_base_server extends webservice_server {
         // find all needed function info and make sure user may actually execute the function
         $this->load_function_info();
 
-        //log the web service request
-        add_to_log(SITEID, 'webservice', $this->functionname, '' , getremoteaddr() , 0, $this->userid);
+        // Log the web service request.
+        $params = array(
+            'other' => array(
+                'function' => $this->functionname
+            )
+        );
+        $event = \core\event\webservice_function_called::create($params);
+        $event->set_legacy_logdata(array(SITEID, 'webservice', $this->functionname, '' , getremoteaddr() , 0, $this->userid));
+        $event->trigger();
 
         // finally, execute the function - any errors are catched by the default exception handler
         $this->execute();
diff --git a/webservice/tests/events.php b/webservice/tests/events.php
new file mode 100644 (file)
index 0000000..b196100
--- /dev/null
@@ -0,0 +1,342 @@
+<?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/>.
+
+/**
+ * Unit tests for Web service events.
+ *
+ * @package    webservice
+ * @category   phpunit
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Unit tests for Web service events.
+ *
+ * @package    webservice
+ * @category   phpunit
+ * @copyright  2013 Frédéric Massart
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class webservice_events_testcase extends advanced_testcase {
+
+    public function setUp() {
+        $this->resetAfterTest();
+    }
+
+    public function test_function_called() {
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $fakelogdata = array(1, 'B', true, null);
+        $params = array(
+            'other' => array(
+                'function' => 'A function'
+            )
+        );
+        $event = \core\event\webservice_function_called::create($params);
+        $event->set_legacy_logdata($fakelogdata);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals('A function', $event->other['function']);
+        $this->assertEventLegacyLogData($fakelogdata, $event);
+    }
+
+    public function test_login_failed() {
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $fakelogdata = array(1, 'B', true, null);
+        $params = array(
+            'other' => array(
+                'reason' => 'Unit Test',
+                'method' => 'Some method',
+                'token' => 'A fake token'
+            )
+        );
+        $event = \core\event\webservice_login_failed::create($params);
+        $event->set_legacy_logdata($fakelogdata);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($params['other']['reason'], $event->other['reason']);
+        $this->assertEquals($params['other']['method'], $event->other['method']);
+        $this->assertEquals($params['other']['token'], $event->other['token']);
+        $this->assertEventLegacyLogData($fakelogdata, $event);
+    }
+
+    public function test_service_created() {
+        global $CFG, $DB;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        // Creating a fake service.
+        $service = (object) array(
+            'name' => 'Test',
+            'enabled' => 1,
+            'requiredcapability' => '',
+            'restrictedusers' => 0,
+            'component' => null,
+            'timecreated' => time(),
+            'timemodified' => time(),
+            'shortname' => null,
+            'downloadfiles' => 0,
+            'uploadfiles' => 0
+        );
+        $service->id = $DB->insert_record('external_services', $service);
+
+        // Trigger the event.
+        $params = array(
+            'objectid' => $service->id,
+        );
+        $event = \core\event\webservice_service_created::create($params);
+        $event->add_record_snapshot('external_services', $service);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        // Assert that the event contains the right information.
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($service->id, $event->objectid);
+        $returnurl = $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices";
+        $expected = array(SITEID, 'webservice', 'add', $returnurl, get_string('addservice', 'webservice', $service));
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_updated() {
+        global $CFG, $DB;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        // Creating a fake service.
+        $service = (object) array(
+            'name' => 'Test',
+            'enabled' => 1,
+            'requiredcapability' => '',
+            'restrictedusers' => 0,
+            'component' => null,
+            'timecreated' => time(),
+            'timemodified' => time(),
+            'shortname' => null,
+            'downloadfiles' => 0,
+            'uploadfiles' => 0
+        );
+        $service->id = $DB->insert_record('external_services', $service);
+
+        // Trigger the event.
+        $params = array(
+            'objectid' => $service->id,
+        );
+        $event = \core\event\webservice_service_updated::create($params);
+        $event->add_record_snapshot('external_services', $service);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        // Assert that the event contains the right information.
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($service->id, $event->objectid);
+        $returnurl = $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices";
+        $expected = array(SITEID, 'webservice', 'edit', $returnurl, get_string('editservice', 'webservice', $service));
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_deleted() {
+        global $CFG, $DB;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        // Creating a fake service.
+        $service = (object) array(
+            'name' => 'Test',
+            'enabled' => 1,
+            'requiredcapability' => '',
+            'restrictedusers' => 0,
+            'component' => null,
+            'timecreated' => time(),
+            'timemodified' => time(),
+            'shortname' => null,
+            'downloadfiles' => 0,
+            'uploadfiles' => 0
+        );
+        $service->id = $DB->insert_record('external_services', $service);
+
+        // Trigger the event.
+        $params = array(
+            'objectid' => $service->id,
+        );
+        $event = \core\event\webservice_service_deleted::create($params);
+        $event->add_record_snapshot('external_services', $service);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        // Assert that the event contains the right information.
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals($service->id, $event->objectid);
+        $returnurl = $CFG->wwwroot . "/" . $CFG->admin . "/settings.php?section=externalservices";
+        $expected = array(SITEID, 'webservice', 'delete', $returnurl, get_string('deleteservice', 'webservice', $service));
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_user_added() {
+        global $CFG;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'relateduserid' => 2
+        );
+        $event = \core\event\webservice_service_user_added::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $this->assertEquals(2, $event->relateduserid);
+        $expected = array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $params['objectid'],
+            'add', '', $params['relateduserid']);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_service_user_removed() {
+        global $CFG;
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'relateduserid' => 2
+        );
+        $event = \core\event\webservice_service_user_removed::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $this->assertEquals(2, $event->relateduserid);
+        $expected = array(SITEID, 'core', 'assign', $CFG->admin . '/webservice/service_users.php?id=' . $params['objectid'],
+            'remove', '', $params['relateduserid']);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_token_created() {
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'relateduserid' => 2,
+            'other' => array(
+                'auto' => true
+            )
+        );
+        $event = \core\event\webservice_token_created::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $this->assertEquals(2, $event->relateduserid);
+        $expected = array(SITEID, 'webservice', 'automatically create user token', '' , 'User ID: ' . 2);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+
+    public function test_token_sent() {
+        $user = $this->getDataGenerator()->create_user();
+        $this->setUser($user);
+
+        // The Web service API doesn't allow the testing of the events directly by
+        // calling some functions which trigger the events, so what we are going here
+        // is just checking that the event returns the expected information.
+
+        $sink = $this->redirectEvents();
+
+        $params = array(
+            'objectid' => 1,
+            'other' => array(
+                'auto' => true
+            )
+        );
+        $event = \core\event\webservice_token_sent::create($params);
+        $event->trigger();
+
+        $events = $sink->get_events();
+        $this->assertCount(1, $events);
+        $event = reset($events);
+
+        $this->assertEquals(context_system::instance(), $event->get_context());
+        $this->assertEquals(1, $event->objectid);
+        $expected = array(SITEID, 'webservice', 'sending requested user token', '' , 'User ID: ' . $user->id);
+        $this->assertEventLegacyLogData($expected, $event);
+    }
+}