Commit 7a6d1f34 authored by Jiri Baum's avatar Jiri Baum
Browse files

Masquerading auditability - log events. (Bug #1027574)



Log events, including both user IDs when masquerading is in progress. The log
can be configured to log all events or only those while masquerading is in
progress or none. The log is expired after a configurable delay.

Note that this logs all events (or all masquerading events) even though this
feature only includes one report of one type of event.

Change-Id: I7a59d98b84b0527a55363b4d01448b9b1809aa9e
Signed-off-by: default avatarJiri Baum <jiri@catalyst-au.net>
parent 40517fde
......@@ -614,6 +614,35 @@ $siteoptionform = array(
),
),
),
'loggingsettings' => array(
'type' => 'fieldset',
'collapsible' => true,
'collapsed' => true,
'legend' => get_string('loggingsettingslegend', 'admin'),
'elements' => array(
'eventloglevel' => array(
'type' => 'select',
'title' => get_string('eventloglevel', 'admin'),
'description' => get_string('eventlogleveldescription', 'admin'),
'defaultvalue' => get_config('eventloglevel'),
'options' => array(
'none' => get_string('eventloglevelnone', 'admin'),
'masq' => get_string('eventloglevelmasq', 'admin'),
'all' => get_string('eventloglevelall', 'admin'),
),
'help' => true,
'disabled' => in_array('eventloglevel', $OVERRIDDEN),
),
'eventlogexpiry' => array(
'type' => 'expiry',
'title' => get_string('eventlogexpiry', 'admin'),
'description' => get_string('eventlogexpirydescription', 'admin'),
'defaultvalue' => get_config('eventlogexpiry'),
'help' => false,
'disabled' => in_array('eventlogexpiry', $OVERRIDDEN),
),
),
),
)
);
......@@ -645,6 +674,7 @@ function siteoptions_submit(Pieform $form, $values) {
'registerterms', 'allowmobileuploads', 'creategroups', 'createpublicgroups', 'allowgroupcategories', 'wysiwyg',
'staffreports', 'staffstats', 'userscandisabledevicedetection',
'masqueradingreasonrequired', 'masqueradingnotified',
'eventloglevel', 'eventlogexpiry',
);
// if public views are disabled, sitemap generation must also be disabled.
......
......@@ -388,6 +388,13 @@ $string['whocancreatepublicgroupsdescription'] = 'Decide which users will be abl
$string['wysiwyg'] = 'HTML editor';
$string['wysiwygdescription'] = 'Defines whether or not the HTML editor is enabled globally or whether users are allowed to enable / disable it themselves.';
$string['wysiwyguserdefined'] = 'User-defined';
$string['eventloglevel'] = 'Log events';
$string['eventlogleveldescription'] = 'Which events should be logged?';
$string['eventlogexpiry'] = 'Event log expiry';
$string['eventlogexpirydescription'] = 'How long to keep the event log.';
$string['eventloglevelnone'] = 'None';
$string['eventloglevelmasq'] = 'Masquerading';
$string['eventloglevelall'] = 'All';
// Site content
$string['about'] = 'About';
......@@ -983,6 +990,7 @@ $string['institutionsettingslegend'] = 'Institution settings';
$string['accountsettingslegend'] = 'Account settings';
$string['securitysettingslegend'] = 'Security settings';
$string['generalsettingslegend'] = 'General settings';
$string['loggingsettingslegend'] = 'Logging settings';
$string['groupname'] = 'Group name';
$string['groupmembers'] = 'Members';
......
<h3>Log events</h3>
<p>Events are generated every time the user does anything significant on the site, such as editing a page.</p>
<p>Optionally, a log of these events can be kept. You can keep either all events, which could be a lot of data and database activity on a busy site, or only those events pertaining to the masquerading of an administrator as another user when using the "Log in as" functionality.
This log is kept in the event_log table in the database.</p>
<p>No matter which setting you choose, all events are still logged in the access log.</p>
......@@ -274,6 +274,19 @@
<KEY NAME="callfunctionuk" TYPE="unique" FIELDS="callfunction" />
</KEYS>
</TABLE>
<TABLE NAME="event_log">
<FIELDS>
<FIELD NAME="usr" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="realusr" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="time" TYPE="datetime" NOTNULL="true" />
<FIELD NAME="event" TYPE="char" LENGTH="255" NOTNULL="false" />
<FIELD NAME="data" TYPE="text" NOTNULL="false" />
</FIELDS>
<KEYS>
<KEY NAME="usrfk" TYPE="foreign" FIELDS="usr" REFTABLE="usr" REFFIELDS="id" />
<KEY NAME="realusrfk" TYPE="foreign" FIELDS="realusr" REFTABLE="usr" REFFIELDS="id" />
</KEYS>
</TABLE>
<TABLE NAME="activity_type">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
......
......@@ -3137,5 +3137,26 @@ function xmldb_core_upgrade($oldversion=0) {
ensure_record_exists('event_type', $event, $event);
}
if ($oldversion < 2013012101) {
$table = new XMLDBTable('event_log');
$table->addFieldInfo('usr', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL);
$table->addFieldInfo('realusr', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL);
$table->addFieldInfo('event', XMLDB_TYPE_CHAR, 255, null, XMLDB_NOTNULL);
$table->addFieldInfo('data', XMLDB_TYPE_TEXT, null, null, null);
$table->addFieldInfo('time', XMLDB_TYPE_DATETIME, null, null, XMLDB_NOTNULL);
$table->addKeyInfo('usrfk', XMLDB_KEY_FOREIGN, array('usr'), 'usr', array('id'));
$table->addKeyInfo('realusrfk', XMLDB_KEY_FOREIGN, array('realusr'), 'usr', array('id'));
create_table($table);
$cron = new StdClass;
$cron->callfunction = 'cron_event_log_expire';
$cron->minute = 7;
$cron->hour = 23;
$cron->day = '*';
$cron->month = '*';
$cron->dayofweek = '*';
insert_record('cron', $cron);
}
return $status;
}
......@@ -1427,12 +1427,21 @@ function blocktype_artefactplugin($blocktype) {
* Fires an event which can be handled by different parts of the system
*/
function handle_event($event, $data) {
global $USER;
if (!$e = get_record('event_type', 'name', $event)) {
throw new SystemException("Invalid event");
}
if ($data instanceof ArtefactType || $data instanceof BlockInstance) {
// leave it alone
if ($data instanceof ArtefactType) {
// leave $data alone, but convert for the event log
$logdata = $data->to_stdclass();
}
else if ($data instanceof BlockInstance) {
// leave $data alone, but convert for the event log
$logdata = array(
'id' => $data->get('id'),
'blocktype' => $data->get('blocktype'),
);
}
else if (is_object($data)) {
$data = (array)$data;
......@@ -1441,6 +1450,21 @@ function handle_event($event, $data) {
$data = array('id' => $data);
}
$parentuser = $USER->get('parentuser');
$eventloglevel = get_config('eventloglevel');
if ($eventloglevel === 'all'
or ($parentuser and $eventloglevel === 'masq')) {
$logentry = (object) array(
'usr' => $USER->get('id'),
'realusr' => $parentuser ? $parentuser->id : $USER->get('id'),
'event' => $event,
'data' => json_encode(isset($logdata) ? $logdata : $data),
'time' => db_format_timestamp(time()),
);
insert_record('event_log', $logentry);
}
if ($coreevents = get_records_array('event_subscription', 'event', $event)) {
require_once('activity.php'); // core events can generate activity.
foreach ($coreevents as $ce) {
......@@ -2966,6 +2990,20 @@ function cron_sitemap_daily() {
$sitemap->generate();
}
/**
* Cronjob to expire the event_log table.
*/
function cron_event_log_expire() {
if ($expiry = get_config('eventlogexpiry')) {
delete_records_select(
'event_log',
'time < CURRENT_DATE - INTERVAL ' .
(is_postgres() ? "'" . $expiry . " seconds'" : $expiry . ' SECONDS')
);
}
}
function build_portfolio_search_html(&$data) {
global $THEME;
$artefacttypes = get_records_assoc('artefact_installed_type');
......
......@@ -884,6 +884,7 @@ function core_install_firstcoredata_defaults() {
'cron_institution_data_weekly' => array('55', '23', '*', '*', '6'),
'cron_institution_data_daily' => array('51', '23', '*', '*', '*'),
'check_imap_for_bounces' => array('*', '*', '*', '*', '*'),
'cron_event_log_expire' => array('7', '23', '*', '*', '*'),
);
foreach ($cronjobs as $callfunction => $times) {
$cron = new StdClass;
......
......@@ -30,7 +30,7 @@ defined('INTERNAL') || die();
$config = new StdClass;
// See https://wiki.mahara.org/index.php/Developer_Area/Version_Numbering_Policy
// For upgrades on stable branches, increment the version by one. On master, use the date.
$config->version = 2013012100;
$config->version = 2013012101;
$config->release = '1.7.0dev';
$config->minupgradefrom = 2008040200;
$config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment