Compare commits

..

No commits in common. "48e5d45d325bf8ad59bab8b31474f1224d338366" and "f3e75574214a2171ca451e75f94ebe43c78c96bc" have entirely different histories.

14 changed files with 424 additions and 1486 deletions

View file

@ -23,14 +23,3 @@
// Accesslog base DN // Accesslog base DN
define('LS_ACCESSLOG_BASEDN', 'cn=ldapsaisie-accesslog'); define('LS_ACCESSLOG_BASEDN', 'cn=ldapsaisie-accesslog');
/*
* Enable logging write events on LDAP entries managed by LdapSaisie in the accesslog base
*
* The feature permit to LdapSaisie to write it self log entries in accesslog base about
* modifications made with its system account with the right author DN.
*
* Note: If your LDAP directory ACL permit to your users to do them self modifications on LDAP
* directory, the recommanded way is to use authz proxy authentication (see useAuthzProxyControl
* configuration parameter).
*/
define('LS_ACCESSLOG_LOG_WRITE_EVENTS', false);

View file

@ -1,36 +0,0 @@
table.objectAccessLogs tbody tr {
border-bottom: 1px dotted;
}
table.objectAccessLogs table.mods {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
table.objectAccessLogs table.mods td, table.objectAccessLogs table.mods th {
border-left: 1px dotted;
}
table.objectAccessLogs table.mods tr {
border: none!important;
}
table.objectAccessLogs .col-attr {
width: 15em;
}
table.objectAccessLogs .col-op {
width: 6em;
}
table.objectAccessLogs .col-value {
width: 25em;
}
table.objectAccessLogs .col-value div {
overflow: scroll;
width: 100%;
margin: 0;
padding: 0;
}

View file

@ -25,37 +25,30 @@ LSerror :: defineError('ACCESSLOG_SUPPORT_01',
); );
$GLOBALS['accesslog_reqTypes'] = array( $GLOBALS['accesslog_reqTypes'] = array(
'add' => ___('Add'), 'add' => _('Add'),
'bind' => ___('Log in'), 'bind' => _('Log in'),
'compare' => ___('Compare'), 'compare' => _('Compare'),
'delete' => ___('Delete'), 'delete' => _('Delete'),
'extended' => ___('Extended'), 'extended' => _('Extended'),
'modify' => ___('Modify'), 'modify' => _('Modify'),
'modrdn' => ___('Modify RDN'), 'modrdn' => _('Modify RDN'),
'search' => ___('Search'), 'search' => _('Search'),
'unbind' => ___('Log out'), 'unbind' => _('Log out'),
); );
$GLOBALS['accesslog_modOps'] = array( $GLOBALS['accesslog_modOps'] = array(
'+' => ___('Add'), '+' => _('Add'),
'-' => ___('Delete'), '-' => _('Delete'),
'=' => ___('Replace'), '=' => _('Replace'),
'' => ___('Replace'), '' => _('Replace'),
'#' => ___('Increment'), '#' => _('Increment'),
); );
function LSaddon_accesslog_support() { function LSaddon_accesslog_support() {
$MUST_DEFINE_CONST= array( if (!defined('LS_ACCESSLOG_BASEDN')) {
'LS_ACCESSLOG_BASEDN', LSerror :: addErrorCode('ACCESSLOG_SUPPORT_01', 'LS_ACCESSLOG_BASEDN');
'LS_ACCESSLOG_LOG_WRITE_EVENTS',
);
foreach($MUST_DEFINE_CONST as $const) {
if (!defined($const) || is_empty(constant($const))) {
LSerror :: addErrorCode('ACCESSLOG_SUPPORT_01', $const);
return false; return false;
} }
}
if (php_sapi_name() === 'cli') { if (php_sapi_name() === 'cli') {
LScli::add_command( LScli::add_command(
'getEntryAccessLog', 'getEntryAccessLog',
@ -64,18 +57,10 @@ function LSaddon_accesslog_support() {
'[entry DN] [page]' '[entry DN] [page]'
); );
} }
elseif (LS_ACCESSLOG_LOG_WRITE_EVENTS && LSsession :: loadLSclass('LSldap')) {
LSldap :: addEvent('updated', 'onEntryUpdated');
LSldap :: addEvent('moved', 'onEntryMoved');
LSldap :: addEvent('user_password_updated', 'onEntryUserPasswordUpdated');
LSldap :: addEvent('deleted', 'onEntryDeleted');
}
return true; return true;
} }
function mapAccessLogEntry(&$entry) { function mapAccessLogEntry(&$entry) {
foreach($entry['attrs'] as $attr => $values)
$entry['attrs'][$attr] = ensureIsArray($values);
$attrs = $entry['attrs']; $attrs = $entry['attrs'];
$entry['start'] = LSldap::parseDate(LSldap::getAttr($attrs, 'reqStart')); $entry['start'] = LSldap::parseDate(LSldap::getAttr($attrs, 'reqStart'));
$entry['end'] = LSldap::parseDate(LSldap::getAttr($attrs, 'reqEnd')); $entry['end'] = LSldap::parseDate(LSldap::getAttr($attrs, 'reqEnd'));
@ -88,23 +73,21 @@ function mapAccessLogEntry(&$entry) {
$entry['type'] = LSldap::getAttr($attrs, 'reqType'); $entry['type'] = LSldap::getAttr($attrs, 'reqType');
$entry['result'] = ldap_err2str(LSldap::getAttr($attrs, 'reqResult')); $entry['result'] = ldap_err2str(LSldap::getAttr($attrs, 'reqResult'));
$entry['message'] = LSldap::getAttr($attrs, 'reqMessage'); $entry['message'] = LSldap::getAttr($attrs, 'reqMessage');
if ($entry['type'] === 'modify' && LSldap::getAttr($attrs, 'reqMod', true)) {
$mods = array(); $mods = array();
foreach(LSldap::getAttr($attrs, 'reqMod', true) as $mod) { foreach(LSldap::getAttr($attrs, 'reqMod', true) as $mod) {
if (preg_match('/^(?P<attr>[^\:]+)\:(?P<op>[^ ]?)( (?P<value>.*))?$/', $mod, $m)) { if (preg_match('/^([^\:]+)\:([^ ]?) (.*)$/', $mod, $m)) {
$attr = $m['attr']; $attr = $m[1];
$op = $m['op']; $op = $m[2];
$value = isset($m['value'])?$m['value']:null; $value = $m[3];
if (!array_key_exists($attr, $mods)) { if (!array_key_exists($attr, $mods)) {
$mods[$attr] = array( $mods[$attr] = array(
'changes' => array(), 'mods' => array(),
'old_values' => array(), 'old_values' => array(),
); );
} }
$mods[$attr]['changes'][] = array( $mods[$attr]['changes'][] = array(
'op' => ( 'op' => array_key_exists($op, $GLOBALS['accesslog_modOps']) ? $GLOBALS['accesslog_modOps'][$op] : $op,
array_key_exists($op, $GLOBALS['accesslog_modOps'])?
_($GLOBALS['accesslog_modOps'][$op]): $op
),
'value' => $value, 'value' => $value,
); );
} }
@ -116,39 +99,23 @@ function mapAccessLogEntry(&$entry) {
} }
} }
} }
if ($mods)
$entry['mods'] = $mods; $entry['mods'] = $mods;
if ($entry['type'] === 'modrdn') {
$new_rdn = LSldap::getAttr($attrs, 'reqNewRDN', false);
$superior_dn = LSldap::getAttr($attrs, 'reqNewSuperior', false);
if (!$superior_dn) {
$superior_dn = parentDn(LSldap::getAttr($attrs, 'reqDN', false));
}
$entry['new_dn'] = "$new_rdn,$superior_dn";
} }
if (array_key_exists($entry['type'], $GLOBALS['accesslog_reqTypes'])) { if (array_key_exists($entry['type'], $GLOBALS['accesslog_reqTypes'])) {
$entry['type'] = _($GLOBALS['accesslog_reqTypes'][$entry['type']]); $entry['type'] = $GLOBALS['accesslog_reqTypes'][$entry['type']];
} }
} }
function sortLogEntriesByDate(&$a, &$b) { function sortLogEntryByDate($a, $b) {
$astart = LSldap::getAttr($a['attrs'], 'reqStart'); return ($a['start'] === $b['start']) ? 0 : ($a['start'] < $b['start']) ? -1 : 1;
$bstart = LSldap::getAttr($b['attrs'], 'reqStart');
return ($astart === $bstart) ? 0 : ($astart < $bstart) ? -1 : 1;
} }
function getEntryAccessLog($dn, $start_date=null) { function getEntryAccessLog($dn) {
$filter = Net_LDAP2_Filter::create('reqDn', 'equals', $dn); $data = LSldap::search(
if ($start_date) { Net_LDAP2_Filter::create('reqDn', 'equals', $dn),
$date_filter = Net_LDAP2_Filter::create('reqStart', 'greaterOrEqual', $start_date);
$filter = Net_LDAP2_Filter::combine('and', array($filter, $date_filter));
}
$entries = LSldap::search(
$filter,
LS_ACCESSLOG_BASEDN, LS_ACCESSLOG_BASEDN,
array( array(
'attributes' => array( 'attributes' => array(
'reqDN',
'reqStart', 'reqStart',
'reqEnd', 'reqEnd',
'reqAuthzID', 'reqAuthzID',
@ -157,33 +124,22 @@ function getEntryAccessLog($dn, $start_date=null) {
'reqMessage', 'reqMessage',
'reqMod', 'reqMod',
'reqOld', 'reqOld',
'reqNewRDN',
'reqNewSuperior',
), ),
) )
); );
if (!is_array($entries)) { if (!is_array($data)) {
return; return;
} }
usort($entries, 'sortLogEntriesByDate');
$logs = array(); $logs = array();
$new_dn = null; foreach($data as $entry) {
$rename_date = null; foreach($entry['attrs'] as $attr => $values) {
foreach($entries as $entry) { $entry['attrs'][$attr] = ensureIsArray($values);
}
mapAccessLogEntry($entry); mapAccessLogEntry($entry);
$logs[] = $entry; $logs[] = $entry;
if (isset($entry['new_dn'])) {
$new_dn = $entry['new_dn'];
$rename_date = LSldap::formatDate($entry['start']);
break;
} }
} usort($logs, 'sortLogEntryByDate');
if ($new_dn) { return array_reverse($logs);
$next_logs = getEntryAccessLog($new_dn, $rename_date);
if (is_array($next_logs))
$logs = array_merge($logs, $next_logs);
}
return $start_date?$logs:array_reverse($logs);
} }
function getEntryAccessLogPage($dn, $page = false, $nbByPage = 30) { function getEntryAccessLogPage($dn, $page = false, $nbByPage = 30) {
@ -227,136 +183,11 @@ function showObjectAccessLogs($obj) {
'action' => 'view', 'action' => 'view',
); );
LStemplate::assign('LSview_actions', $LSview_actions); LStemplate::assign('LSview_actions', $LSview_actions);
LStemplate::addCSSFile('showObjectAccessLogs.css');
LSsession::setTemplate('showObjectAccessLogs.tpl'); LSsession::setTemplate('showObjectAccessLogs.tpl');
LSsession::displayTemplate(); LSsession::displayTemplate();
exit(); exit();
} }
function onEntryUpdated($data) {
$now = LSldap::formatDate();
$dn = "reqStart=$now,".LS_ACCESSLOG_BASEDN;
$new_entry = $data['original_entry']->isNew();
$attrs = array(
'reqStart' => array($now),
'reqEnd' => array($now),
'reqType' => array($new_entry?"add":"modify"),
'reqSession' => array("1024"),
'reqAuthzID' => array(LSsession :: get('authenticated_user_dn')),
'reqDN' => array($data["dn"]),
'reqResult' => array("0"),
);
// Compute modifications
$mods = array();
$olds = array();
if ($new_entry)
foreach(ensureIsArray($data['entry']->getValue('objectClass', 'all')) as $value)
$mods[] = "objectClass:+ $value";
foreach($data['changes'] as $attr => $values) {
if (strtolower($attr) == 'userpassword')
foreach(array_keys($values) as $idx)
$values[$idx] = hashPasswordForLogs($values[$idx]);
if ($values) {
foreach($values as $value)
$mods[] = $new_entry?"$attr:+ $value":"$attr:= $value";
}
else if (!$new_entry) {
$mods[] = "$attr:=";
}
if (!$new_entry)
foreach(ensureIsArray($data['original_entry']->getValue($attr, 'all')) as $value)
$olds[] = "$attr: $value";
}
if (!$mods) return true;
$attrs['reqMod'] = $mods;
if ($olds)
$attrs['reqOld'] = $olds;
LSldap::getNewEntry($dn, array($new_entry?'auditAdd':'auditModify'), $attrs, true);
}
function onEntryUserPasswordUpdated($data) {
$now = LSldap::formatDate();
$dn = "reqStart=$now,".LS_ACCESSLOG_BASEDN; $mods = array();
// Compute modifications
$mods = array();
// Retreive fresh entry to retreive hased/stored password
$attrs = LSldap :: getAttrs($data['dn'], null, array('userPassword'));
$new_passwords = $data["new_passwords"];
if ($attrs)
$new_passwords = LSldap :: getAttr($attrs, 'userPassword', true);
if ($new_passwords) {
foreach($new_passwords as $password)
$mods[] = "userPassword:= ".hashPasswordForLogs($password);
}
else
$mods[] = "userPassword:=";
$attrs = array(
'reqStart' => array($now),
'reqEnd' => array($now),
'reqType' => array("modify"),
'reqSession' => array("1024"),
'reqAuthzID' => array(LSsession :: get('authenticated_user_dn')),
'reqDN' => array($data["dn"]),
'reqResult' => array("0"),
'reqMod' => $mods,
);
LSldap::getNewEntry($dn, array('auditModify'), $attrs, true);
}
function onEntryMoved($data) {
$now = LSldap::formatDate();
$dn = "reqStart=$now,".LS_ACCESSLOG_BASEDN;
$attrs = array(
'reqStart' => array($now),
'reqEnd' => array($now),
'reqType' => array("modrdn"),
'reqSession' => array("1024"),
'reqAuthzID' => array(LSsession :: get('authenticated_user_dn')),
'reqDN' => array($data["old"]),
'reqNewRDN' => array(getRdn($data["new"])),
'reqResult' => array("0"),
);
$new_superior = parentDn($data["new"]);
$old_superior = parentDn($data["old"]);
if ($new_superior != $old_superior)
$attrs['reqNewSuperior'] = array($new_superior);
LSldap::getNewEntry($dn, array('auditModRDN'), $attrs, true);
}
function onEntryDeleted($data) {
$now = LSldap::formatDate();
$dn = "reqStart=$now,".LS_ACCESSLOG_BASEDN;
$attrs = array(
'reqStart' => array($now),
'reqEnd' => array($now),
'reqType' => array("delete"),
'reqSession' => array("1024"),
'reqAuthzID' => array(LSsession :: get('authenticated_user_dn')),
'reqDN' => array($data["dn"]),
'reqResult' => array("0"),
);
LSldap::getNewEntry($dn, array('auditDelete'), $attrs, true);
}
function hashPasswordForLogs($password) {
if (preg_match('/^{[^}]+}.*/', $password))
// Already hashed
return $password;
if(defined('PASSWORD_ARGON2I'))
return '{ARGON2}'.password_hash($password, PASSWORD_ARGON2I);
if(defined('MHASH_SHA512') && function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
mt_srand( (double) microtime() * 1000000 );
$salt = mhash_keygen_s2k(MHASH_SHA512, $password, substr( pack( "h*", md5( mt_rand() ) ), 0, 8 ), 4 );
return "{SSHA512}".base64_encode(mhash($mhash_type, $password.$salt).$salt);
}
return '[not logged]';
}
if (php_sapi_name() !== 'cli') { if (php_sapi_name() !== 'cli') {
return true; return true;
} }

View file

@ -88,54 +88,46 @@ class LScli extends LSlog_staticLoggerClass {
* Show usage message * Show usage message
* *
* @param string|false $error Error message to display before usage message (optional, default: false) * @param string|false $error Error message to display before usage message (optional, default: false)
* @param string $extra_args Optional argument use to compute error message using sprintf (if provided)
* @return void * @return void
**/ **/
public static function usage($error=false, ...$extra_args) { public static function usage($error=false) {
global $argv; global $argv;
if ($error) { if ($error)
if ($extra_args)
$error = call_user_func_array('sprintf', array_merge(array($error), $extra_args));
echo "$error\n\n"; echo "$error\n\n";
}
printf(_( echo "Usage : ".basename($argv[0])." [-h] [-qdC] command\n";
"Usage: %s [-h] [-qdC] command echo " -h Show this message\n";
-h Show this message echo " -q|--quiet Quiet mode: nothing log on console (but keep other logging handler)\n";
-q|--quiet Quiet mode: nothing log on console (but keep other logging handler) echo " -d|--debug Debug mode (set log level to DEBUG, default: WARNING)\n";
-d|--debug Debug mode (set log level to DEBUG, default: WARNING) echo " -v|--verbose Verbose mode (set log level to INFO, default: WARNING)\n";
-v|--verbose Verbose mode (set log level to INFO, default: WARNING) echo " --trace Trace mode (set log level to TRACE, default: WARNING)\n";
--trace Trace mode (set log level to TRACE, default: WARNING) echo " -C|--console Log on console with same log level as other handlers (otherwise, log only errors)\n";
-C|--console Log on console with same log level as other handlers (otherwise, log only errors) echo " -S|--ldap-server Connect to a specific LDAP server: you could specify a LDAP\n";
-S|--ldap-server Connect to a specific LDAP server: you could specify a LDAP echo " server by its declaration order in configuration (default:\n";
server by its declaration order in configuration (default: echo " first one).\n";
first one). echo " -L|--load-class Load specific class to permit access to its CLI commands\n";
-L|--load-class Load specific class to permit access to its CLI commands echo " -A|--load-addons Load specific addon to permit access to its CLI commands\n";
-A|--load-addons Load specific addon to permit access to its CLI commands echo " command Command to run\n";
command Command to run echo "\n";
echo "Available commands :\n";
Available commands:
"), basename($argv[0]));
foreach (self :: $commands as $command => $info) { foreach (self :: $commands as $command => $info) {
if (self :: $current_command and self :: $current_command != $command) if (self :: $current_command and self :: $current_command != $command)
continue; continue;
echo " $command: ".__($info['short_desc'])."\n"; echo " $command : ".$info['short_desc']."\n";
echo " ".basename($argv[0])." $command ".($info['usage_args']?__($info['usage_args']):'')."\n"; echo " ".basename($argv[0])." $command ".($info['usage_args']?$info['usage_args']:'')."\n";
if ($info['long_desc']) { if ($info['long_desc']) {
if (is_array($info['long_desc'])) { if (is_array($info['long_desc']))
$info['long_desc'] = array_map('__', $info['long_desc']);
$info['long_desc'] = implode("\n", $info['long_desc']); $info['long_desc'] = implode("\n", $info['long_desc']);
} echo "\n ".str_replace("\n", "\n ", wordwrap($info['long_desc']))."\n";
echo "\n ".str_replace("\n", "\n ", wordwrap(__($info['long_desc'])))."\n";
} }
echo "\n"; echo "\n";
} }
if (empty(self :: $commands)) if (empty(self :: $commands))
echo " "._("Currently no available command is declared.")."\n"; echo " Currently no available command is declared.\n";
exit($error?1:0); exit(($error?1:0));
} }
/** /**
@ -194,7 +186,7 @@ class LScli extends LSlog_staticLoggerClass {
$i++; $i++;
$ldap_server_id = intval($argv[$i]); $ldap_server_id = intval($argv[$i]);
if(!LSsession :: setLdapServer($ldap_server_id)) if(!LSsession :: setLdapServer($ldap_server_id))
self :: usage(_("Fail to select LDAP server #%s."), $ldap_server_id); self :: usage("Fail to select LDAP server #$ldap_server_id.");
break; break;
case '--sub-dn': case '--sub-dn':
$i++; $i++;
@ -205,14 +197,14 @@ class LScli extends LSlog_staticLoggerClass {
$i++; $i++;
$class = $argv[$i]; $class = $argv[$i];
if(!LSsession :: loadLSclass($class)) if(!LSsession :: loadLSclass($class))
self :: usage(_("Fail to load class '%s'."), $class); self :: usage("Fail to load class '$class'.");
break; break;
case '-A': case '-A':
case '--load-addon': case '--load-addon':
$i++; $i++;
$addon = $argv[$i]; $addon = $argv[$i];
if(!LSsession :: loadLSaddon($addon)) if(!LSsession :: loadLSaddon($addon))
self :: usage(_("Fail to load addon '%s'."), $addon); self :: usage("Fail to load addon '$addon'.");
break; break;
case '--': case '--':
$command_args = array_merge($command_args, array_slice($argv, $i)); $command_args = array_merge($command_args, array_slice($argv, $i));
@ -223,8 +215,7 @@ class LScli extends LSlog_staticLoggerClass {
$command_args[] = $argv[$i]; $command_args[] = $argv[$i];
else else
self :: usage( self :: usage(
_("Invalid parameter \"%s\".\nNote: Command's parameter/argument must be place after the command."), getFData(_("Invalid parameter \"%{parameter}\".\nNote: Command's parameter/argument must be place after the command."), $argv[$i])
$argv[$i]
); );
} }
} }
@ -258,7 +249,7 @@ class LScli extends LSlog_staticLoggerClass {
if ($ldap_server_subDn) { if ($ldap_server_subDn) {
self :: need_ldap_con(); self :: need_ldap_con();
if(!LSsession :: setSubDn($ldap_server_subDn)) if(!LSsession :: setSubDn($ldap_server_subDn))
self :: usage(_("Fail to select sub DN '%s'."), $ldap_server_subDn); self :: usage("Fail to select sub DN '$ldap_server_subDn'.");
} }
if (!$command) { if (!$command) {
@ -268,7 +259,7 @@ class LScli extends LSlog_staticLoggerClass {
// Select LDAP server (if not already done with -S/--ldap-server parameter) // Select LDAP server (if not already done with -S/--ldap-server parameter)
if ($ldap_server_id === false && !LSsession :: setLdapServer(0)) if ($ldap_server_id === false && !LSsession :: setLdapServer(0))
self :: log_fatal(_('Fail to select first LDAP server.')); self :: log_fatal('Fail to select first LDAP server.');
// Run command // Run command
self :: run_command($command, $command_args); self :: run_command($command, $command_args);
@ -388,12 +379,12 @@ class LScli extends LSlog_staticLoggerClass {
**/ **/
public static function confirm($question=null) { public static function confirm($question=null) {
if (is_null($question)) if (is_null($question))
$question = _("Are you sure?"); $question = "Are you sure?";
printf(_("\n%s Type 'yes' to continue: "), $question); echo "\n$question Type 'yes' to continue: ";
$handle = fopen ("php://stdin","r"); $handle = fopen ("php://stdin","r");
$line = fgets($handle); $line = fgets($handle);
if(trim($line) != _('yes')){ if(trim($line) != 'yes'){
echo _("User cancel\n"); echo "User cancel\n";
return false; return false;
} }
echo "\n"; echo "\n";
@ -465,7 +456,7 @@ class LScli extends LSlog_staticLoggerClass {
$ldap_server_id = intval($comp_words[$i]); $ldap_server_id = intval($comp_words[$i]);
self :: unquote_word($ldap_server_id); self :: unquote_word($ldap_server_id);
if(!LSsession :: setLdapServer($ldap_server_id)) if(!LSsession :: setLdapServer($ldap_server_id))
self :: usage(_("Fail to select LDAP server #%s."), $ldap_server_id); self :: usage("Fail to select LDAP server #$ldap_server_id.");
} }
break; break;
case '--sub-dn': case '--sub-dn':
@ -485,7 +476,7 @@ class LScli extends LSlog_staticLoggerClass {
self :: unquote_word($ldap_server_subDn); self :: unquote_word($ldap_server_subDn);
self :: need_ldap_con(); self :: need_ldap_con();
if(!LSsession :: setSubDn($ldap_server_subDn)) if(!LSsession :: setSubDn($ldap_server_subDn))
self :: usage(_("Fail to select sub DN '%s'.", $ldap_server_subDn)); self :: usage("Fail to select sub DN '$ldap_server_subDn'.");
break; break;
case '-L': case '-L':
case '--load-class': case '--load-class':
@ -500,7 +491,7 @@ class LScli extends LSlog_staticLoggerClass {
$class = $comp_words[$i]; $class = $comp_words[$i];
self :: unquote_word($class); self :: unquote_word($class);
if(!LSsession :: loadLSclass($class)) if(!LSsession :: loadLSclass($class))
self :: usage(_("Fail to load class '%s'."), $class); self :: usage("Fail to load class '$class'.");
break; break;
case '-A': case '-A':
case '--load-addon': case '--load-addon':
@ -515,7 +506,7 @@ class LScli extends LSlog_staticLoggerClass {
$addon = $comp_words[$i]; $addon = $comp_words[$i];
self :: unquote_word($addon); self :: unquote_word($addon);
if(!LSsession :: loadLSaddon($addon)) if(!LSsession :: loadLSaddon($addon))
self :: usage(_("Fail to load addon '%s'."), $addon); self :: usage("Fail to load addon '$addon'.");
break; break;
default: default:
if (!in_array($comp_words[$i], $opts)) { if (!in_array($comp_words[$i], $opts)) {
@ -533,7 +524,7 @@ class LScli extends LSlog_staticLoggerClass {
asort($subDns); asort($subDns);
$subDn = key($subDns); $subDn = key($subDns);
if(!LSsession :: setSubDn($subDn)) if(!LSsession :: setSubDn($subDn))
self :: usage(_("Fail to select sub DN '%s'."), $subDn); self :: usage("Fail to select sub DN '$subDn'.");
$opts[] = '--sub-dn'; $opts[] = '--sub-dn';
} }
} }
@ -861,7 +852,7 @@ ___("LScli : The CLI command '%{command}' handler is not callable.")
LScli :: add_command( LScli :: add_command(
'bash_autocomplete', 'bash_autocomplete',
array('LScli', 'bash_autocomplete'), array('LScli', 'bash_autocomplete'),
___('Handle BASH completion'), 'Handle BASH completion',
'[arg num to autocomplete] -- [command args]', '[arg num to autocomplete] -- [command args]',
null, null,
false false

View file

@ -279,16 +279,12 @@ function _cli_interactive_ask($context, $msg) {
} }
// Format question // Format question
$question ="\"$msg\"\n\n => "._("Please enter translated string"); $empty_action = ($copyoriginalvalue?'copy original message':'pass');
$empty_action = ( $question ="\"$msg\"\n\n => Please enter translated string";
$copyoriginalvalue?
_("or leave empty to copy original message"):
_("or leave empty to pass")
);
$question .= " (i"; $question .= " (i";
if (!$copyoriginalvalue) if (!$copyoriginalvalue)
$question .= "/c"; $question .= "/c";
$question .= "/e/q/? $empty_action): "; $question .= "/q/? or leave empty to $empty_action): ";
while (true) { while (true) {
if ($context) if ($context)
@ -307,46 +303,14 @@ function _cli_interactive_ask($context, $msg) {
case 'C': // Copy case 'C': // Copy
if (!$copyoriginalvalue) if (!$copyoriginalvalue)
return $msg; return $msg;
case 'e':
case 'E': // Open editor
$tmp_file = tempnam(sys_get_temp_dir(), 'ldapsaisie_translation');
if ($tmp_file === false) {
fwrite(STDERR, _('Fail to create temporary file.'));
break;
}
$fd = fopen($tmp_file, 'w');
if ($fd === false) {
fwrite(STDERR, _('Fail to open temporary file.'));
break;
}
$nb_lines = 1;
if ($context) {
fwrite($fd, "# $context\n");
$nb_lines++;
}
$lines = explode("\n", $msg);
$nb_lines += count($lines);
fwrite($fd, "# ".implode("\n# ", $lines)."\n\n");
fclose($fd);
system("editor +$nb_lines $tmp_file > `tty`", $exit_code);
$result = array();
foreach(file($tmp_file) as $line)
if (!preg_match('/^# /', $line) || $result)
$result[] = preg_replace("/\n$/", "", $line);
unlink($tmp_file);
return implode("\n", $result);
case '?': // Help message case '?': // Help message
fwrite(STDERR, _("Available choices:\n")); fwrite(STDERR, "Available choices:\n");
fwrite(STDERR, _(" - i: ignore this message\n")); fwrite(STDERR, " - i: ignore this message\n");
if (!$copyoriginalvalue) if (!$copyoriginalvalue)
fwrite(STDERR, _(" - c: copy original message\n")); fwrite(STDERR, " - c: copy original message\n");
fwrite(STDERR, _(" - e: translate message in text editor\n")); fwrite(STDERR, " - q: quit interactive mode and ignore all following untranslated messages\n");
fwrite(STDERR, _(" - q: quit interactive mode and ignore all following untranslated messages\n")); fwrite(STDERR, " - ?: Show this message\n");
fwrite(STDERR, _(" - ?: Show this message\n")); fwrite(STDERR, "Or leave empty to $empty_action.\n");
if ($copyoriginalvalue)
fwrite(STDERR, _("Or leave empty to copy original message.\n"));
else
fwrite(STDERR, _("Or leave empty to pass.\n"));
break; break;
case "": // Empty case "": // Empty
// On copy orignal value mode, return $msg // On copy orignal value mode, return $msg
@ -755,9 +719,9 @@ function cli_generate_lang_file($command_args) {
$i++; $i++;
$without = strtolower($command_args[$i]); $without = strtolower($command_args[$i]);
if (!in_array($without, $available_withouts)) if (!in_array($without, $available_withouts))
LScli :: usage(_("Invalid -W/--without parameter. Must be one of the following values: %s.'"), implode("','", $available_withouts)); LScli :: usage("Invalid -W/--without parameter. Must be one of the following values : '".implode("','", $available_withouts)."'.");
elseif ($only) elseif ($only)
LScli :: usage(_("You could not use -W/--without parameter combined with -O/--only parameter.")); LScli :: usage("You could not use only -W/--without parameter combined with -O/--only parameter.");
$withouts[] = $without; $withouts[] = $without;
break; break;
@ -765,12 +729,12 @@ function cli_generate_lang_file($command_args) {
case '-O': case '-O':
$i++; $i++;
if ($only) if ($only)
LScli :: usage(_("You could specify only one -O/--only parameter.")); LScli :: usage("You could specify only on -O/--only parameter.");
$only = strtolower($command_args[$i]); $only = strtolower($command_args[$i]);
if (!in_array($only, $available_onlys)) if (!in_array($only, $available_onlys))
LScli :: usage(_("Invalid -O/--only parameter. Must be one of the following values: %s.'"), implode("','", $available_onlys)); LScli :: usage("Invalid -O/--only parameter. Must be one of the following values : '".implode("','", $available_onlys)."'.");
elseif ($withouts) elseif ($withouts)
LScli :: usage(_("You could not use -W/--without parameter combined with -O/--only parameter.")); LScli :: usage("You could not use only -O/--only parameter combined with -W/--without parameter.");
break; break;
case '-I': case '-I':
@ -802,7 +766,7 @@ function cli_generate_lang_file($command_args) {
$encoding = $parse_lang[1]; $encoding = $parse_lang[1];
} }
else { else {
LScli :: usage(_("Invalid -l/--lang parameter. Must be compose in format : [lang].[encoding]")); LScli :: usage("Invalid --lang parameter. Must be compose in format : [lang].[encoding]");
} }
break; break;
@ -817,7 +781,7 @@ function cli_generate_lang_file($command_args) {
$i++; $i++;
$format = strtolower($command_args[$i]); $format = strtolower($command_args[$i]);
if (!in_array($format, $available_formats)) { if (!in_array($format, $available_formats)) {
LScli :: usage(_("Invalid -f/--format parameter. Must be one of the following values: %s.'"), implode("','", $available_formats)); LScli :: usage("Invalid -f/--format parameter. Must be one of the following values : '".implode("','", $available_formats)."'.");
} }
break; break;
@ -841,7 +805,7 @@ function cli_generate_lang_file($command_args) {
if (is_file($path)) if (is_file($path))
$load_files[] = $path; $load_files[] = $path;
else else
LScli :: usage(_("%s: Invalid parameter or lang file to load."), $command_args[$i]); LScli :: usage($command_args[$i]." : Invalid parameter or lang file to load.");
} }
} }
@ -1133,32 +1097,29 @@ function cli_generate_lang_file_args_autocompleter($comp_words, $comp_word_num,
LScli :: add_command( LScli :: add_command(
'generate_lang_file', 'generate_lang_file',
'cli_generate_lang_file', 'cli_generate_lang_file',
___('Generate lang.php file'), 'Generate lang.php file',
'-l [lang] [-o output.file] [file1] [file2] [-h] [options]', 'l [lang] [-o output.file] [file1] [file2] [-h] [options]',
array( array(
___( " -W/--without Disable specified messages. Must be one of",
" -W/--without Disable specified messages. Must be one of " the following values :",
the following values:"),
" - ".implode("\n - ", $available_withouts), " - ".implode("\n - ", $available_withouts),
___( " -O/--only Only handle specified messages. Must be one",
" -O/--only Only handle specified messages. Must be one " of the following values :",
of the following values :"),
" - ".implode("\n - ", $available_onlys), " - ".implode("\n - ", $available_onlys),
___( " -I/--include-upstream Include upstream code to message lookup",
" -I/--include-upstream Include upstream code to message lookup " -c/--copy-original-value Copy original value as translated value when",
-c/--copy-original-value Copy original value as translated value when " no translated value exists",
no translated value exists " -i/--interactive Interactive mode : ask user to enter",
-i/--interactive Interactive mode : ask user to enter " translated on each translation needed",
translated on each translation needed " -a/--additional-file-format Additional file format output",
-a/--additional-file-format Additional file format output " -l/--lang Load the specify lang",
-l/--lang Language of the translation " Format: [lang].[encoding]",
Format: [lang].[encoding] " -o/--output Output file (default: stdout)",
-o/--output Output file (default: stdout) " -f/--format Output file format : php or pot",
-f/--format Output file format : php or pot " (default: php)",
(default: php) " -K/--keep-unused Keep unused translations in resulting file",
-K/--keep-unused Keep unused translations in resulting file " -F/--fix-utf8 Try to load and fix broken UTF-8 characters in",
-F/--fix-utf8 Try to load and fix broken UTF-8 characters " existing lang files."
in existing lang files.")
), ),
false, // This command does not need LDAP connection false, // This command does not need LDAP connection
'cli_generate_lang_file_args_autocompleter' 'cli_generate_lang_file_args_autocompleter'
@ -1249,16 +1210,16 @@ function cli_generate_ldapsaisie_pot($command_args) {
LScli :: add_command( LScli :: add_command(
'generate_ldapsaisie_pot', 'generate_ldapsaisie_pot',
'cli_generate_ldapsaisie_pot', 'cli_generate_ldapsaisie_pot',
___('Generate POT files:'), 'Generate ldapsaisie.pot files :',
null, null,
array( array(
___("This command generate 3 POT files:"), "This command generate 3 POT files:",
" - ".LS_I18N_DIR_PATH."/ldapsaisie-main.pot", " - ".LS_I18N_DIR_PATH."/ldapsaisie-main.pot",
___(" => contains messages from PHP files"), " => contains messages from PHP files",
" - ".LS_I18N_DIR_PATH."/ldapsaisie-templates.pot", " - ".LS_I18N_DIR_PATH."/ldapsaisie-templates.pot",
___(" => contains messages from templates files"), " => contains messages from templates files",
" - ".LS_I18N_DIR_PATH."/ldapsaisie.pot", " - ".LS_I18N_DIR_PATH."/ldapsaisie.pot",
___(" => contains all messages"), " => contains all messages",
), ),
false // This command does not need LDAP connection false // This command does not need LDAP connection
); );

View file

@ -51,14 +51,6 @@ class LSldap extends LSlog_staticLoggerClass {
*/ */
private static $cnx = NULL; private static $cnx = NULL;
/**
* Registered events
* @see self::addEvent()
* @see self::fireEvent()
* @var array
*/
private static $_events = array();
/** /**
* Set configuration * Set configuration
* *
@ -89,16 +81,12 @@ class LSldap extends LSlog_staticLoggerClass {
if ($config) { if ($config) {
self :: setConfig($config); self :: setConfig($config);
} }
if (!self :: fireEvent('connecting'))
return false;
self :: $cnx = Net_LDAP2::connect(self :: $config); self :: $cnx = Net_LDAP2::connect(self :: $config);
if (Net_LDAP2::isError(self :: $cnx)) { if (Net_LDAP2::isError(self :: $cnx)) {
self :: fireEvent('connection_failure', array('error' => self :: $cnx -> getMessage()));
LSerror :: addErrorCode('LSldap_01',self :: $cnx -> getMessage()); LSerror :: addErrorCode('LSldap_01',self :: $cnx -> getMessage());
self :: $cnx = NULL; self :: $cnx = NULL;
return false; return false;
} }
self :: fireEvent('connected');
return true; return true;
} }
@ -124,19 +112,12 @@ class LSldap extends LSlog_staticLoggerClass {
$config = self :: $config; $config = self :: $config;
$config['binddn'] = $dn; $config['binddn'] = $dn;
$config['bindpw'] = $pwd; $config['bindpw'] = $pwd;
if (!self :: fireEvent('reconnecting', array('dn' => $dn)))
return false;
self :: $cnx = Net_LDAP2::connect($config); self :: $cnx = Net_LDAP2::connect($config);
if (Net_LDAP2::isError(self :: $cnx)) { if (Net_LDAP2::isError(self :: $cnx)) {
self :: fireEvent(
'reconnection_failure',
array('dn' => $dn, 'error' => self :: $cnx -> getMessage())
);
LSerror :: addErrorCode('LSldap_01', self :: $cnx -> getMessage()); LSerror :: addErrorCode('LSldap_01', self :: $cnx -> getMessage());
self :: $cnx = NULL; self :: $cnx = NULL;
return false; return false;
} }
self :: fireEvent('reconnected', array('dn' => $dn));
return true; return true;
} }
@ -153,8 +134,6 @@ class LSldap extends LSlog_staticLoggerClass {
if (!self :: $cnx) { if (!self :: $cnx) {
self :: connect(); self :: connect();
} }
if (!self :: fireEvent('setting_authz_proxy', array('dn' => $dn)))
return false;
$result = self :: $cnx -> setOption( $result = self :: $cnx -> setOption(
'LDAP_OPT_SERVER_CONTROLS', 'LDAP_OPT_SERVER_CONTROLS',
array ( array (
@ -168,11 +147,9 @@ class LSldap extends LSlog_staticLoggerClass {
// Also check user exists to validate the connection with // Also check user exists to validate the connection with
// authz proxy control. // authz proxy control.
if ($result !== True || !self :: exists($dn)) { if ($result !== True || !self :: exists($dn)) {
self :: fireEvent('setting_authz_proxy_failure', array('dn' => $dn));
LSerror :: addErrorCode('LSldap_09'); LSerror :: addErrorCode('LSldap_09');
return False; return False;
} }
self :: fireEvent('set_authz_proxy', array('dn' => $dn));
return True; return True;
} }
@ -186,11 +163,8 @@ class LSldap extends LSlog_staticLoggerClass {
* @return void * @return void
*/ */
public static function close() { public static function close() {
if (!self :: fireEvent('closing'))
return;
self :: $cnx -> done(); self :: $cnx -> done();
self :: $cnx = null; self :: $cnx = null;
self :: fireEvent('closed');
} }
/** /**
@ -332,27 +306,6 @@ class LSldap extends LSlog_staticLoggerClass {
); );
} }
/**
* Format a Datetime object as LDAP date string
*
* @param DateTime|null $datetime The DateTime object to format (optional, default: now)
* @param bool $utc Force UTC timezone (optional, default: false)
*
* @return string|false LDAP date string, or false
*/
public static function formatDate($datetime=null, $utc=true) {
if (is_null($datetime))
$datetime = new DateTime('now');
elseif (!$datetime instanceof DateTime)
return false;
$datetime -> setTimezone(timezone_open($utc?'utc':date_default_timezone_get()));
$datetime_string = $datetime -> format('YmdHis.uO');
// Replace +0000 or -0000 end by Z
$datetime_string = preg_replace('/[\+\-]0000$/', 'Z', $datetime_string);
return $datetime_string;
}
/** /**
* Check if an attribute exists in specified attributes collection * Check if an attribute exists in specified attributes collection
* *
@ -380,13 +333,12 @@ class LSldap extends LSlog_staticLoggerClass {
* @param string $name Name of a attribute * @param string $name Name of a attribute
* @param boolean $multiple true if we must return array * @param boolean $multiple true if we must return array
* *
* @return ($multiple is True ? array<int,string> : string|null) Found value (or array of values) or null * @return mixed Found value (or array of values) or null
*/ */
public static function getAttr($attrs, $name, $multiple=false) { public static function getAttr($attrs, $name, $multiple=false) {
$name = strtolower($name); $name = strtolower($name);
foreach ($attrs as $k => $v) { foreach ($attrs as $k => $v) {
if (strtolower($k) === $name) { if (strtolower($k) === $name) {
$v = ensureIsArray($v);
return $multiple ? $v : $v[0]; return $multiple ? $v : $v[0];
} }
} }
@ -504,12 +456,12 @@ class LSldap extends LSlog_staticLoggerClass {
* *
* @param string $object_type The object type * @param string $object_type The object type
* @param string $dn DN of the LDAP object * @param string $dn DN of the LDAP object
* @param array $changes Array of object attributes changes * @param array $change Array of object attributes changes
* *
* @return boolean True if object was updated, False otherwise. * @return boolean True if object was updated, False otherwise.
*/ */
public static function update($object_type, $dn, $changes) { public static function update($object_type, $dn, $change) {
self :: log_trace("update($object_type, $dn): change=".varDump($changes)); self :: log_trace("update($object_type, $dn): change=".varDump($change));
// Retrieve current LDAP entry // Retrieve current LDAP entry
$entry = self :: getEntry($object_type, $dn); $entry = self :: getEntry($object_type, $dn);
@ -518,18 +470,10 @@ class LSldap extends LSlog_staticLoggerClass {
return false; return false;
} }
if (
!self :: fireEvent(
'updating',
array('object_type' => $object_type, 'dn' => $dn, 'entry' => &$entry, 'changes' => $changes)
)
)
return false;
// Distinguish drop attributes from change attributes // Distinguish drop attributes from change attributes
$changed_attrs = array(); $changed_attrs = array();
$dropped_attrs = array(); $dropped_attrs = array();
foreach($changes as $attrName => $attrVal) { foreach($change as $attrName => $attrVal) {
$drop = true; $drop = true;
if (is_array($attrVal)) { if (is_array($attrVal)) {
foreach($attrVal as $val) { foreach($attrVal as $val) {
@ -563,9 +507,6 @@ class LSldap extends LSlog_staticLoggerClass {
} }
} }
// Keep original entry (to provide to hooks)
$original_entry = clone $entry;
// Handle attributes changes (if need) // Handle attributes changes (if need)
if ($changed_attrs) { if ($changed_attrs) {
@ -580,26 +521,10 @@ class LSldap extends LSlog_staticLoggerClass {
} }
if (Net_LDAP2::isError($ret)) { if (Net_LDAP2::isError($ret)) {
self :: fireEvent(
'update_failure',
array(
'object_type' => $object_type, 'dn' => $dn,
'original_entry' => &$original_entry, 'entry' => &$entry,
'changes' => $changed_attrs, 'error' => $ret->getMessage()
)
);
LSerror :: addErrorCode('LSldap_05',$dn); LSerror :: addErrorCode('LSldap_05',$dn);
LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage()); LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage());
return false; return false;
} }
self :: fireEvent(
'updated',
array(
'object_type' => $object_type, 'dn' => $dn,
'original_entry' => &$original_entry, 'entry' => &$entry,
'changes' => $changed_attrs
)
);
} }
elseif ($entry -> isNew()) { elseif ($entry -> isNew()) {
self :: log_error("update($object_type, $dn): no changed attribute but it's a new entry..."); self :: log_error("update($object_type, $dn): no changed attribute but it's a new entry...");
@ -635,26 +560,10 @@ class LSldap extends LSlog_staticLoggerClass {
// Check result // Check result
if (Net_LDAP2::isError($ret)) { if (Net_LDAP2::isError($ret)) {
self :: fireEvent(
'update_failure',
array(
'object_type' => $object_type, 'dn' => $dn,
'original_entry' => &$original_entry, 'entry' => &$entry,
'changes' => $replace_attrs, 'error' => $ret->getMessage()
)
);
LSerror :: addErrorCode('LSldap_06'); LSerror :: addErrorCode('LSldap_06');
LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage()); LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage());
return false; return false;
} }
self :: fireEvent(
'updated',
array(
'object_type' => $object_type, 'dn' => $dn,
'original_entry' => &$original_entry, 'entry' => &$entry,
'changes' => $replace_attrs
)
);
} }
return true; return true;
} }
@ -697,15 +606,11 @@ class LSldap extends LSlog_staticLoggerClass {
* @return boolean True if object was removed, False otherwise. * @return boolean True if object was removed, False otherwise.
*/ */
public static function remove($dn) { public static function remove($dn) {
if (!self :: fireEvent('removing', array('dn' => $dn)))
return false;
$ret = self :: $cnx -> delete($dn,array('recursive' => true)); $ret = self :: $cnx -> delete($dn,array('recursive' => true));
if (Net_LDAP2::isError($ret)) { if (Net_LDAP2::isError($ret)) {
self :: fireEvent('remove_failure', array('dn' => $dn, 'error' => $ret->getMessage()));
LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage()); LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage());
return false; return false;
} }
self :: fireEvent('removed', array('dn' => $dn));
return true; return true;
} }
@ -718,19 +623,12 @@ class LSldap extends LSlog_staticLoggerClass {
* @return boolean True if object was moved, False otherwise. * @return boolean True if object was moved, False otherwise.
*/ */
public static function move($old, $new) { public static function move($old, $new) {
if (!self :: fireEvent('moving', array('old' => $old, 'new' => $new)))
return false;
$ret = self :: $cnx -> move($old, $new); $ret = self :: $cnx -> move($old, $new);
if (Net_LDAP2::isError($ret)) { if (Net_LDAP2::isError($ret)) {
self :: fireEvent(
'move_failure',
array('old' => $old, 'new' => $new, 'error' => $ret->getMessage())
);
LSerror :: addErrorCode('LSldap_07'); LSerror :: addErrorCode('LSldap_07');
LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage()); LSerror :: addErrorCode(0,'NetLdap-Error : '.$ret->getMessage());
return false; return false;
} }
self :: fireEvent('moved', array('old' => $old, 'new' => $new));
return true; return true;
} }
@ -822,63 +720,22 @@ class LSldap extends LSlog_staticLoggerClass {
_('It is too soon to change the password'), _('It is too soon to change the password'),
_('This password was recently used and cannot be used again'), _('This password was recently used and cannot be used again'),
); );
self :: log_debug("updateUserPassword($object_type, $dn): update entry userPassword attribute"); self :: log_debug("update($object_type, $dn): update entry for userPassword");
$changes = array('userPassword' => self :: getAttr($changed_attrs, 'userPassword', true));
if (
!self :: fireEvent(
'user_password_updating',
array(
'object_type' => $object_type, 'dn' => $dn,
'new_passwords' => $changes['userPassword']
)
)
)
return false;
$ldap = self :: $cnx->getLink(); $ldap = self :: $cnx->getLink();
$attr = array('userPassword' => self :: getAttr($changed_attrs, 'userPassword'));
$ctrlRequest = array(array('oid' => LDAP_CONTROL_PASSWORDPOLICYREQUEST)); $ctrlRequest = array(array('oid' => LDAP_CONTROL_PASSWORDPOLICYREQUEST));
$r = ldap_mod_replace_ext($ldap, $dn, $changes, $ctrlRequest); $r = ldap_mod_replace_ext($ldap, $dn, $attr, $ctrlRequest);
if ($r && ldap_parse_result($ldap, $r, $errcode, $matcheddn, $errmsg, $ref, $ctrlResponse)) { if ($r && ldap_parse_result($ldap, $r, $errcode, $matcheddn, $errmsg, $ref, $ctrlResponse)) {
if ($errcode !== 0 && isset($ctrlResponse[LDAP_CONTROL_PASSWORDPOLICYRESPONSE])) { if ($errcode !== 0 && isset($ctrlResponse[LDAP_CONTROL_PASSWORDPOLICYRESPONSE])) {
self :: fireEvent( LSerror :: addErrorCode('LSldap_10', $ppolicyErrorMsg[$ctrlResponse[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value']['error']]);
'user_password_update_failure',
array(
'object_type' => $object_type, 'dn' => $dn,
'error' => $ppolicyErrorMsg[
$ctrlResponse[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value']['error']
]
)
);
LSerror :: addErrorCode(
'LSldap_10',
$ppolicyErrorMsg[$ctrlResponse[LDAP_CONTROL_PASSWORDPOLICYRESPONSE]['value']['error']]
);
return false; return false;
} }
// Password updated // If everything OK, remove userPassword to prevent it from being processed by Net_LDAP2
self :: fireEvent(
'user_password_updated',
array(
'object_type' => $object_type, 'dn' => $dn,
'new_passwords' => $changes['userPassword']
)
);
// Remove userPassword to prevent it from being processed by update()
unset($changed_attrs['userPassword']); unset($changed_attrs['userPassword']);
} } else {
else {
self :: fireEvent(
'user_password_update_failure',
array(
'object_type' => $object_type, 'dn' => $dn,
'error' => ldap_errno($ldap) !== 0?ldap_error($ldap):'unknown'
)
);
if (ldap_errno($ldap) !== 0) { if (ldap_errno($ldap) !== 0) {
LSerror :: addErrorCode('LSldap_10', ldap_error($ldap)); LSerror :: addErrorCode('LSldap_10', ldap_error($ldap));
} } else {
else {
LSerror :: addErrorCode('LSldap_11'); LSerror :: addErrorCode('LSldap_11');
} }
return false; return false;
@ -898,66 +755,6 @@ class LSldap extends LSlog_staticLoggerClass {
private static function getConfig($param, $default=null, $cast=null) { private static function getConfig($param, $default=null, $cast=null) {
return LSconfig :: get($param, $default, $cast, self :: $config); return LSconfig :: get($param, $default, $cast, self :: $config);
} }
/**
* Registered an action on a specific event
*
* @param string $event The event name
* @param callable $callable The callable to run on event
* @param array $params Paremeters that will be pass to the callable
*
* @return void
*/
public static function addEvent($event, $callable, $params=NULL) {
self :: $_events[$event][] = array(
'callable' => $callable,
'params' => is_array($params)?$params:array(),
);
}
/**
* Run triggered actions on specific event
*
* @param string $event Event name
* @param mixed $data Event data
*
* @return boolean True if all triggered actions succefully runned, false otherwise
*/
public static function fireEvent($event, $data=null) {
$return = true;
// Binding via addEvent
if (isset(self :: $_events[$event]) && is_array(self :: $_events[$event])) {
foreach (self :: $_events[$event] as $e) {
if (is_callable($e['callable'])) {
try {
call_user_func_array(
$e['callable'],
array_merge(
array($data), $e['params']
)
);
}
catch(Exception $er) {
LSerror :: addErrorCode(
'LSldap_13',
array('callable' => format_callable($e['callable']), 'event' => $event)
);
$return = false;
}
}
else {
LSerror :: addErrorCode(
'LSldap_12',
array('callable' => format_callable($e['callable']), 'event' => $event)
);
$return = false;
}
}
}
return $return;
}
} }
/* /*
@ -996,9 +793,3 @@ LSerror :: defineError('LSldap_10',
LSerror :: defineError('LSldap_11', LSerror :: defineError('LSldap_11',
___("LSldap: Unknown LDAP error while updating user password") ___("LSldap: Unknown LDAP error while updating user password")
); );
LSerror :: defineError('LSldap_12',
___("LSldap: Fail to execute trigger %{callable} on event %{event} : is not callable.")
);
LSerror :: defineError('LSldap_13',
___("LSldap: Error during the execution of the trigger %{callable} on event %{event}.")
);

View file

@ -497,6 +497,13 @@ class LSsession {
) )
)) ))
return False; return False;
LStemplate :: addHelpInfo(
'LSdefault',
array(
'copy_to_clipboard' => _('Copy to clipboard'),
'copied' => _('Copied!'),
)
);
return True; return True;
} }
return False; return False;

View file

@ -416,13 +416,6 @@ class LStemplate extends LSlog_staticLoggerClass {
**/ **/
public static function assignCommonVars() { public static function assignCommonVars() {
// JS config // JS config
LStemplate :: addHelpInfo(
'LSdefault',
array(
'copy_to_clipboard' => _('Copy to clipboard'),
'copied' => _('Copied!'),
)
);
LStemplate :: assign('LSjsConfig', base64_encode(json_encode(self :: $JSconfigParams))); LStemplate :: assign('LSjsConfig', base64_encode(json_encode(self :: $JSconfigParams)));
// JS files // JS files

View file

@ -405,35 +405,6 @@ function sumDn($dn1,$dn2) {
return $basedn; return $basedn;
} }
/**
* Extract and retreive RDN from DN
* @param string $dn
* @param bool $with_attr If true, include the RDN attribute name (optional, default: true)
* @return string|null|false The parent object DN, null if no parent or false in case of error
*/
function getRdn($dn, $with_attr=true) {
$parts = ldap_explode_dn($dn, 0);
if (!is_array($parts) || !isset($parts['count'])) return false;
if ($with_attr)
return $parts[0];
$equal_pos = strpos($parts[0], '=');
if ($equal_pos !== false)
return substr($parts[0], $equal_pos+1);
return $parts[0];
}
/**
* Retreive parent object DN
* @param string $dn
* @return string|null|false The parent object DN, null if no parent or false in case of error
*/
function parentDn($dn) {
$parts = ldap_explode_dn($dn, 0);
if (!is_array($parts) || !isset($parts['count'])) return false;
if ($parts['count'] == 1) return null;
return implode(',', array_slice($parts, 2));
}
function checkEmail($value,$domain=NULL,$checkDns=true) { function checkEmail($value,$domain=NULL,$checkDns=true) {
$log = LSlog :: get_logger('checkEmail'); $log = LSlog :: get_logger('checkEmail');
$regex = '/^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/'; $regex = '/^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/';
@ -810,29 +781,3 @@ function timestamp2LdapDate($value, $timezone=null, $format=null) {
return dateTime2LdapDate($datetime, $timezone, $format); return dateTime2LdapDate($datetime, $timezone, $format);
return false; return false;
} }
/**
* Generate an UUID
* @return string
*/
function generate_uuid() {
return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
// 16 bits for "time_mid"
mt_rand( 0, 0xffff ),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand( 0, 0x0fff ) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand( 0, 0x3fff ) | 0x8000,
// 48 bits for "node"
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
);
}

View file

@ -76,12 +76,6 @@ var LSdefault = new Class({
this.initializeLang(); this.initializeLang();
document.getElements('.copyable').each(function(el) { document.getElements('.copyable').each(function(el) {
if (el.hasClass('copyable-no-btn')) {
el.addEvent('click', this.onCopyBtnClick.bind(this, {btn: null, element: el}));
el.setStyle('cursor', 'copy');
this.addHelpInfo(el, 'LSdefault', 'copy_to_clipboard');
return;
}
var btn = new Element('img'); var btn = new Element('img');
btn.setProperties({ btn.setProperties({
src: this.imagePath('copy') src: this.imagePath('copy')

File diff suppressed because it is too large Load diff

View file

@ -217,7 +217,7 @@ msgid "Download"
msgstr "" msgstr ""
#: includes/addons/LSaddons.showSupportInfo.php:78 #: includes/addons/LSaddons.showSupportInfo.php:78
#: includes/addons/LSaddons.accesslog.php:225 #: includes/addons/LSaddons.accesslog.php:181
#: includes/addons/LSaddons.showTechInfo.php:117 #: includes/addons/LSaddons.showTechInfo.php:117
msgid "Go back" msgid "Go back"
msgstr "" msgstr ""
@ -350,8 +350,8 @@ msgstr ""
msgid "Increment" msgid "Increment"
msgstr "" msgstr ""
#: includes/addons/LSaddons.accesslog.php:220 #: includes/addons/LSaddons.accesslog.php:176
#: includes/class/class.LSsession.php:1855 includes/routes.php:157 #: includes/class/class.LSsession.php:1862 includes/routes.php:157
#: includes/routes.php:470 templates/default/select.tpl:29 #: includes/routes.php:470 templates/default/select.tpl:29
msgid "Refresh" msgid "Refresh"
msgstr "" msgstr ""
@ -390,15 +390,15 @@ msgstr ""
msgid "SUPANN: Fail to load nomenclature %{nomenclature}." msgid "SUPANN: Fail to load nomenclature %{nomenclature}."
msgstr "" msgstr ""
#: includes/addons/LSaddons.supann.php:447 #: includes/addons/LSaddons.supann.php:376
msgid "Entity %{id} (unrecognized)" msgid "Entity %{id} (unrecognized)"
msgstr "" msgstr ""
#: includes/addons/LSaddons.supann.php:519 #: includes/addons/LSaddons.supann.php:448
msgid "Godfather %{dn} (unrecognized)" msgid "Godfather %{dn} (unrecognized)"
msgstr "" msgstr ""
#: includes/addons/LSaddons.supann.php:646 #: includes/addons/LSaddons.supann.php:575
#: includes/class/class.LSformElement_select.php:58 #: includes/class/class.LSformElement_select.php:58
#: includes/class/class.LSformElement_select_object.php:108 #: includes/class/class.LSformElement_select_object.php:108
msgid "%{value} (unrecognized value)" msgid "%{value} (unrecognized value)"
@ -740,7 +740,7 @@ msgid ""
msgstr "" msgstr ""
#: includes/class/class.LSformElement.php:262 #: includes/class/class.LSformElement.php:262
#: templates/default/showObjectAccessLogs.tpl:29 #: templates/default/showObjectAccessLogs.tpl:28
msgid "Attribute" msgid "Attribute"
msgstr "" msgstr ""
@ -918,149 +918,6 @@ msgstr ""
msgid "Clear selected date." msgid "Clear selected date."
msgstr "" msgstr ""
#: includes/class/class.LSlang.php:282
msgid "Please enter translated string"
msgstr ""
#: includes/class/class.LSlang.php:285
msgid "or leave empty to copy original message"
msgstr ""
#: includes/class/class.LSlang.php:286
msgid "or leave empty to pass"
msgstr ""
#: includes/class/class.LSlang.php:314
msgid "Fail to create temporary file."
msgstr ""
#: includes/class/class.LSlang.php:319
msgid "Fail to open temporary file."
msgstr ""
#: includes/class/class.LSlang.php:339
msgid "Available choices:\n"
msgstr ""
#: includes/class/class.LSlang.php:340
msgid " - i: ignore this message\n"
msgstr ""
#: includes/class/class.LSlang.php:342
msgid " - c: copy original message\n"
msgstr ""
#: includes/class/class.LSlang.php:343
msgid " - e: translate message in text editor\n"
msgstr ""
#: includes/class/class.LSlang.php:344
msgid ""
" - q: quit interactive mode and ignore all following untranslated messages\n"
msgstr ""
#: includes/class/class.LSlang.php:345
msgid " - ?: Show this message\n"
msgstr ""
#: includes/class/class.LSlang.php:347
msgid "Or leave empty to copy original message.\n"
msgstr ""
#: includes/class/class.LSlang.php:349
msgid "Or leave empty to pass.\n"
msgstr ""
#: includes/class/class.LSlang.php:758
#, php-format
msgid ""
"Invalid -W/--without parameter. Must be one of the following values: %s.'"
msgstr ""
#: includes/class/class.LSlang.php:760 includes/class/class.LSlang.php:773
msgid ""
"You could not use -W/--without parameter combined with -O/--only parameter."
msgstr ""
#: includes/class/class.LSlang.php:768
msgid "You could specify only one -O/--only parameter."
msgstr ""
#: includes/class/class.LSlang.php:771
#, php-format
msgid "Invalid -O/--only parameter. Must be one of the following values: %s.'"
msgstr ""
#: includes/class/class.LSlang.php:805
msgid ""
"Invalid -l/--lang parameter. Must be compose in format : [lang].[encoding]"
msgstr ""
#: includes/class/class.LSlang.php:820
#, php-format
msgid ""
"Invalid -f/--format parameter. Must be one of the following values: %s.'"
msgstr ""
#: includes/class/class.LSlang.php:844
#, php-format
msgid "%s: Invalid parameter or lang file to load."
msgstr ""
#: includes/class/class.LSlang.php:1136
msgid "Generate lang.php file"
msgstr ""
#: includes/class/class.LSlang.php:1140
msgid ""
" -W/--without Disable specified messages. Must be one of\n"
" the following values:"
msgstr ""
#: includes/class/class.LSlang.php:1144
msgid ""
" -O/--only Only handle specified messages. Must be one\n"
" of the following values :"
msgstr ""
#: includes/class/class.LSlang.php:1148
msgid ""
" -I/--include-upstream Include upstream code to message lookup\n"
" -c/--copy-original-value Copy original value as translated value when\n"
" no translated value exists\n"
" -i/--interactive Interactive mode : ask user to enter\n"
" translated on each translation needed\n"
" -a/--additional-file-format Additional file format output\n"
" -l/--lang Language of the translation\n"
" Format: [lang].[encoding]\n"
" -o/--output Output file (default: stdout)\n"
" -f/--format Output file format : php or pot\n"
" (default: php)\n"
" -K/--keep-unused Keep unused translations in resulting file\n"
" -F/--fix-utf8 Try to load and fix broken UTF-8 characters\n"
" in existing lang files."
msgstr ""
#: includes/class/class.LSlang.php:1252
msgid "Generate POT files:"
msgstr ""
#: includes/class/class.LSlang.php:1255
msgid "This command generate 3 POT files:"
msgstr ""
#: includes/class/class.LSlang.php:1257
msgid " => contains messages from PHP files"
msgstr ""
#: includes/class/class.LSlang.php:1259
msgid " => contains messages from templates files"
msgstr ""
#: includes/class/class.LSlang.php:1261
msgid " => contains all messages"
msgstr ""
#: includes/class/class.LStemplate.php:160 #: includes/class/class.LStemplate.php:160
msgid "LStemplate : compile directory is not writable (dir : %{dir})" msgid "LStemplate : compile directory is not writable (dir : %{dir})"
msgstr "" msgstr ""
@ -1087,46 +944,38 @@ msgid ""
"upgrade documentation to adapt your templates." "upgrade documentation to adapt your templates."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:422 #: includes/class/class.LStemplate.php:478
msgid "Copy to clipboard"
msgstr ""
#: includes/class/class.LStemplate.php:423
msgid "Copied!"
msgstr ""
#: includes/class/class.LStemplate.php:485
msgid "Smarty - An exception occured displaying template '%{template}'" msgid "Smarty - An exception occured displaying template '%{template}'"
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:505 #: includes/class/class.LStemplate.php:498
msgid "Smarty - An exception occured fetching template '%{template}'" msgid "Smarty - An exception occured fetching template '%{template}'"
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:521 #: includes/class/class.LStemplate.php:514
#: includes/class/class.LStemplate.php:535 #: includes/class/class.LStemplate.php:528
msgid "A fatal error occured. If problem persist, please contact support." msgid "A fatal error occured. If problem persist, please contact support."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:531 #: includes/class/class.LStemplate.php:524
msgid "<h1>Loop detected displaying this error:</h1><pre>%{error}</pre>" msgid "<h1>Loop detected displaying this error:</h1><pre>%{error}</pre>"
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:534 #: includes/class/class.LStemplate.php:527
msgid "A fatal error occured." msgid "A fatal error occured."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:731 #: includes/class/class.LStemplate.php:724
msgid "LStemplate : Template %{file} not found." msgid "LStemplate : Template %{file} not found."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:734 #: includes/class/class.LStemplate.php:727
msgid "" msgid ""
"LStemplate : Fail to execute trigger %{callable} on event %{event} : is not " "LStemplate : Fail to execute trigger %{callable} on event %{event} : is not "
"callable." "callable."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:737 #: includes/class/class.LStemplate.php:730
msgid "" msgid ""
"LStemplate : Error during the execution of the trigger %{callable} on event " "LStemplate : Error during the execution of the trigger %{callable} on event "
"%{event}." "%{event}."
@ -1274,157 +1123,165 @@ msgstr ""
msgid "Clear" msgid "Clear"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:1640 #: includes/class/class.LSsession.php:503
msgid "Copy to clipboard"
msgstr ""
#: includes/class/class.LSsession.php:504
msgid "Copied!"
msgstr ""
#: includes/class/class.LSsession.php:1647
msgid "Connection" msgid "Connection"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:1660 #: includes/class/class.LSsession.php:1667
msgid "Recovery of your credentials" msgid "Recovery of your credentials"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:1669 #: includes/class/class.LSsession.php:1676
msgid "Please fill the identifier field to proceed recovery procedure" msgid "Please fill the identifier field to proceed recovery procedure"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:1674 #: includes/class/class.LSsession.php:1681
msgid "" msgid ""
"An email has been sent to %{mail}. Please follow the instructions on it." "An email has been sent to %{mail}. Please follow the instructions on it."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:1683 #: includes/class/class.LSsession.php:1690
msgid "Your new password has been sent to %{mail}." msgid "Your new password has been sent to %{mail}."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:2945 templates/default/select.tpl:20 #: includes/class/class.LSsession.php:2952 templates/default/select.tpl:20
#: templates/default/recoverpassword.tpl:17 templates/default/login.tpl:16 #: templates/default/recoverpassword.tpl:17 templates/default/login.tpl:16
msgid "Level" msgid "Level"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3113 #: includes/class/class.LSsession.php:3120
msgid "LSsession : The constant '%{const}' is not defined." msgid "LSsession : The constant '%{const}' is not defined."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3116 #: includes/class/class.LSsession.php:3123
msgid "" msgid ""
"LSsession : The addon '%{addon}' support is uncertain. Verify system " "LSsession : The addon '%{addon}' support is uncertain. Verify system "
"compatibility and the add-on configuration." "compatibility and the add-on configuration."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3119 #: includes/class/class.LSsession.php:3126
msgid "" msgid ""
"LSsession : LDAP server's configuration data are invalid. Can't connect." "LSsession : LDAP server's configuration data are invalid. Can't connect."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3122 #: includes/class/class.LSsession.php:3129
msgid "LSsession : Failed to load LSobject type '%{type}' : unknon type." msgid "LSsession : Failed to load LSobject type '%{type}' : unknon type."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3125 #: includes/class/class.LSsession.php:3132
msgid "LSsession : Failed to load LSclass '%{class}'." msgid "LSsession : Failed to load LSclass '%{class}'."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3128 #: includes/class/class.LSsession.php:3135
msgid "LSsession : Login or password incorrect." msgid "LSsession : Login or password incorrect."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3131 #: includes/class/class.LSsession.php:3138
msgid "LSsession : Impossible to identify you : Duplication of identities." msgid "LSsession : Impossible to identify you : Duplication of identities."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3134 #: includes/class/class.LSsession.php:3141
msgid "LSsession : Can't load class of authentification (%{class})." msgid "LSsession : Can't load class of authentification (%{class})."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3137 #: includes/class/class.LSsession.php:3144
msgid "LSsession : Can't connect to LDAP server." msgid "LSsession : Can't connect to LDAP server."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3140 #: includes/class/class.LSsession.php:3147
msgid "LSsession : Impossible to authenticate you." msgid "LSsession : Impossible to authenticate you."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3143 #: includes/class/class.LSsession.php:3150
msgid "LSsession : Your are not authorized to do this action." msgid "LSsession : Your are not authorized to do this action."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3146 #: includes/class/class.LSsession.php:3153
msgid "LSsession : Some informations are missing to display this page." msgid "LSsession : Some informations are missing to display this page."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3149 #: includes/class/class.LSsession.php:3156
msgid "" msgid ""
"LSsession : The function '%{function}' of the custom action " "LSsession : The function '%{function}' of the custom action "
"'%{customAction}' does not exists or is not configured." "'%{customAction}' does not exists or is not configured."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3152 #: includes/class/class.LSsession.php:3159
msgid "LSsession : Fail to retrieve user's LDAP credentials from LSauth." msgid "LSsession : Fail to retrieve user's LDAP credentials from LSauth."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3155 #: includes/class/class.LSsession.php:3162
msgid "" msgid ""
"LSsession : Fail to reconnect to LDAP server with user's LDAP credentials." "LSsession : Fail to reconnect to LDAP server with user's LDAP credentials."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3158 #: includes/class/class.LSsession.php:3165
msgid "LSsession : No import/export format define for this object type." msgid "LSsession : No import/export format define for this object type."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3161 #: includes/class/class.LSsession.php:3168
msgid "" msgid ""
"LSsession : Error during creation of list of levels. Contact administrators. " "LSsession : Error during creation of list of levels. Contact administrators. "
"(Code : %{code})" "(Code : %{code})"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3164 #: includes/class/class.LSsession.php:3171
msgid "LSsession : The password recovery is disabled for this LDAP server." msgid "LSsession : The password recovery is disabled for this LDAP server."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3167 #: includes/class/class.LSsession.php:3174
msgid "" msgid ""
"LSsession : Some informations are missing to recover your password. Contact " "LSsession : Some informations are missing to recover your password. Contact "
"administrators." "administrators."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3170 #: includes/class/class.LSsession.php:3177
msgid "" msgid ""
"LSsession : Error during password recovery. Contact administrators.(Step : " "LSsession : Error during password recovery. Contact administrators.(Step : "
"%{step})" "%{step})"
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3173 #: includes/class/class.LSsession.php:3180
msgid "" msgid ""
"LSsession : The function '%{func}' configured for the view '%{view}' of the " "LSsession : The function '%{func}' configured for the view '%{view}' of the "
"LSaddon '%{addon}' is not declared in the LSaddon file." "LSaddon '%{addon}' is not declared in the LSaddon file."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3176 #: includes/class/class.LSsession.php:3183
msgid "LSsession : Failed to load resource file '%{file}'." msgid "LSsession : Failed to load resource file '%{file}'."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3179 #: includes/class/class.LSsession.php:3186
msgid "" msgid ""
"LSsession : The function '%{func}' configured for the view '%{view}' of the " "LSsession : The function '%{func}' configured for the view '%{view}' of the "
"LSaddon '%{addon}' doesn't exist." "LSaddon '%{addon}' doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3182 #: includes/class/class.LSsession.php:3189
msgid "LSsession : invalid related object's DN pass in parameter." msgid "LSsession : invalid related object's DN pass in parameter."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3185 #: includes/class/class.LSsession.php:3192
msgid "" msgid ""
"LSsession : the LSaddon %{addon} keep using old-style addon view URL. Please " "LSsession : the LSaddon %{addon} keep using old-style addon view URL. Please "
"upgrade it." "upgrade it."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3188 #: includes/class/class.LSsession.php:3195
msgid "" msgid ""
"LSsession : You have been redirect from an old-style URL %{url}. Please " "LSsession : You have been redirect from an old-style URL %{url}. Please "
"upgrade this link." "upgrade this link."
msgstr "" msgstr ""
#: includes/class/class.LSsession.php:3191 #: includes/class/class.LSsession.php:3198
msgid "" msgid ""
"LSsession : You always seem to use %{old} in your custom code: Please " "LSsession : You always seem to use %{old} in your custom code: Please "
"upgrade it and use %{new}.<pre>\n" "upgrade it and use %{new}.<pre>\n"
@ -1437,199 +1294,199 @@ msgstr ""
msgid "Invalid file type (%{type})." msgid "Invalid file type (%{type})."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:577 #: includes/class/class.LSldapObject.php:566
msgid "The attribute %{attr} is not valid." msgid "The attribute %{attr} is not valid."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3150 #: includes/class/class.LSldapObject.php:3139
msgid "LSldapObject : Object type unknown." msgid "LSldapObject : Object type unknown."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3153 #: includes/class/class.LSldapObject.php:3142
msgid "LSldapObject : Update form is not defined for the object %{obj}." msgid "LSldapObject : Update form is not defined for the object %{obj}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3156 #: includes/class/class.LSldapObject.php:3145
msgid "LSldapObject : No form exists for the object %{obj}." msgid "LSldapObject : No form exists for the object %{obj}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3159 #: includes/class/class.LSldapObject.php:3148
msgid "" msgid ""
"LSldapObject : The function %{func} to validate the attribute %{attr} the " "LSldapObject : The function %{func} to validate the attribute %{attr} the "
"object %{obj} is unknow." "object %{obj} is unknow."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3162 #: includes/class/class.LSldapObject.php:3151
msgid "" msgid ""
"LSldapObject : Configuration data are missing to validate the attribute " "LSldapObject : Configuration data are missing to validate the attribute "
"%{attr} of the object %{obj}." "%{attr} of the object %{obj}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3166 #: includes/class/class.LSldapObject.php:3155
msgid "" msgid ""
"LSldapObject : The function %{func} to be executed on the object event " "LSldapObject : The function %{func} to be executed on the object event "
"%{event} doesn't exist." "%{event} doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3169 #: includes/class/class.LSldapObject.php:3158
msgid "" msgid ""
"LSldapObject : The %{func} execution on the object event %{event} failed." "LSldapObject : The %{func} execution on the object event %{event} failed."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3173 #: includes/class/class.LSldapObject.php:3162
msgid "" msgid ""
"LSldapObject : Class %{class}, which method %{meth} to be executed on the " "LSldapObject : Class %{class}, which method %{meth} to be executed on the "
"object event %{event}, doesn't exist." "object event %{event}, doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3176 #: includes/class/class.LSldapObject.php:3165
msgid "" msgid ""
"LSldapObject : Method %{meth} within %{class} class to be executed on object " "LSldapObject : Method %{meth} within %{class} class to be executed on object "
"event %{event}, doesn't exist." "event %{event}, doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3179 #: includes/class/class.LSldapObject.php:3168
msgid "" msgid ""
"LSldapObject : Error during execute %{meth} method within %{class} class, to " "LSldapObject : Error during execute %{meth} method within %{class} class, to "
"be executed on object event %{event}." "be executed on object event %{event}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3183 #: includes/class/class.LSldapObject.php:3172
msgid "" msgid ""
"LSldapObject : Some configuration data of the object type %{obj} are missing " "LSldapObject : Some configuration data of the object type %{obj} are missing "
"to generate the DN of the new object." "to generate the DN of the new object."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3186 #: includes/class/class.LSldapObject.php:3175
msgid "" msgid ""
"LSldapObject : The attibute %{attr} of the object is not yet defined. Can't " "LSldapObject : The attibute %{attr} of the object is not yet defined. Can't "
"generate DN." "generate DN."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3189 #: includes/class/class.LSldapObject.php:3178
msgid "LSldapObject : Without DN, the object could not be changed." msgid "LSldapObject : Without DN, the object could not be changed."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3192 #: includes/class/class.LSldapObject.php:3181
msgid "" msgid ""
"LSldapObject : The attribute %{attr_depend} depending on the attribute " "LSldapObject : The attribute %{attr_depend} depending on the attribute "
"%{attr} doesn't exist." "%{attr} doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3195 #: includes/class/class.LSldapObject.php:3184
msgid "LSldapObject : Error during deleting the object %{objectname}." msgid "LSldapObject : Error during deleting the object %{objectname}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3199 #: includes/class/class.LSldapObject.php:3188
msgid "" msgid ""
"LSldapObject : Error during actions to be executed before renaming the objet." "LSldapObject : Error during actions to be executed before renaming the objet."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3202 #: includes/class/class.LSldapObject.php:3191
msgid "" msgid ""
"LSldapObject : Error during actions to be executed after renaming the objet." "LSldapObject : Error during actions to be executed after renaming the objet."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3206 #: includes/class/class.LSldapObject.php:3195
msgid "" msgid ""
"LSldapObject : Error during actions to be executed before deleting the objet." "LSldapObject : Error during actions to be executed before deleting the objet."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3209 #: includes/class/class.LSldapObject.php:3198
msgid "" msgid ""
"LSldapObject : Error during actions to be executed after deleting the objet." "LSldapObject : Error during actions to be executed after deleting the objet."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3213 #: includes/class/class.LSldapObject.php:3202
msgid "" msgid ""
"LSldapObject : Error during the actions to be executed before creating the " "LSldapObject : Error during the actions to be executed before creating the "
"object." "object."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3216 #: includes/class/class.LSldapObject.php:3205
msgid "" msgid ""
"LSldapObject : Error during the actions to be executed after creating the " "LSldapObject : Error during the actions to be executed after creating the "
"object. It was created anyway." "object. It was created anyway."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3220 #: includes/class/class.LSldapObject.php:3209
msgid "" msgid ""
"LSldapObject : The function %{func} to be executed before creating the " "LSldapObject : The function %{func} to be executed before creating the "
"object doesn't exist." "object doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3223 #: includes/class/class.LSldapObject.php:3212
msgid "" msgid ""
"LSldapObject : Error executing the function %{func} to be execute after " "LSldapObject : Error executing the function %{func} to be execute after "
"deleting the object." "deleting the object."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3226 #: includes/class/class.LSldapObject.php:3215
msgid "" msgid ""
"LSldapObject : The function %{func} to be executed after deleting the object " "LSldapObject : The function %{func} to be executed after deleting the object "
"doesn't exist." "doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3229 #: includes/class/class.LSldapObject.php:3218
msgid "" msgid ""
"LSldapObject : Error executing the function %{func} to be execute after " "LSldapObject : Error executing the function %{func} to be execute after "
"creating the object." "creating the object."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3233 #: includes/class/class.LSldapObject.php:3222
msgid "" msgid ""
"LSldapObject : %{func} function, to be executed on object event %{event}, " "LSldapObject : %{func} function, to be executed on object event %{event}, "
"doesn't exist." "doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3236 #: includes/class/class.LSldapObject.php:3225
msgid "" msgid ""
"LSldapObject : Error during the execution of %{func} function on object " "LSldapObject : Error during the execution of %{func} function on object "
"event %{event}." "event %{event}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3240 #: includes/class/class.LSldapObject.php:3229
msgid "" msgid ""
"LSldapObject : %{meth} method, to be executed on object event %{event}, " "LSldapObject : %{meth} method, to be executed on object event %{event}, "
"doesn't exist." "doesn't exist."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3243 #: includes/class/class.LSldapObject.php:3232
msgid "" msgid ""
"LSldapObject : Error during execution of %{meth} method on object event " "LSldapObject : Error during execution of %{meth} method on object event "
"%{event}." "%{event}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3246 #: includes/class/class.LSldapObject.php:3235
msgid "LSldapObject : Error during generate LDAP filter for %{LSobject}." msgid "LSldapObject : Error during generate LDAP filter for %{LSobject}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3250 #: includes/class/class.LSldapObject.php:3239
msgid "" msgid ""
"LSldapObject : Error during execution of the custom action %{customAction} " "LSldapObject : Error during execution of the custom action %{customAction} "
"on %{objectname}." "on %{objectname}."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3254 #: includes/class/class.LSldapObject.php:3243
msgid "LSldapObject : Fail to retrieve container DN." msgid "LSldapObject : Fail to retrieve container DN."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3257 #: includes/class/class.LSldapObject.php:3246
msgid "" msgid ""
"LSldapObject : The function %{func} to generate container DN is not callable." "LSldapObject : The function %{func} to generate container DN is not callable."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3260 #: includes/class/class.LSldapObject.php:3249
msgid "LSldapObject : Error during generating container DN : %{error}" msgid "LSldapObject : Error during generating container DN : %{error}"
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3263 #: includes/class/class.LSldapObject.php:3252
msgid "" msgid ""
"LSldapObject : An LDAP object with the same DN as generated for this new one " "LSldapObject : An LDAP object with the same DN as generated for this new one "
"already exists. Please verify your configuration." "already exists. Please verify your configuration."
msgstr "" msgstr ""
#: includes/class/class.LSldapObject.php:3268 #: includes/class/class.LSldapObject.php:3257
msgid "" msgid ""
"LSrelation : Some parameters are missing in the call of methods to handle " "LSrelation : Some parameters are missing in the call of methods to handle "
"standard relations (Method : %{meth})." "standard relations (Method : %{meth})."
@ -1659,98 +1516,86 @@ msgid ""
"(begining by '/' caracter)." "(begining by '/' caracter)."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:815 #: includes/class/class.LSldap.php:713
msgid "The password expired" msgid "The password expired"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:816 #: includes/class/class.LSldap.php:714
msgid "The account is locked" msgid "The account is locked"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:817 #: includes/class/class.LSldap.php:715
msgid "The password was reset and must be changed" msgid "The password was reset and must be changed"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:818 #: includes/class/class.LSldap.php:716
msgid "It is not possible to modify the password" msgid "It is not possible to modify the password"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:819 #: includes/class/class.LSldap.php:717
msgid "The old password must be supplied" msgid "The old password must be supplied"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:820 #: includes/class/class.LSldap.php:718
msgid "The password does not meet the quality requirements" msgid "The password does not meet the quality requirements"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:821 #: includes/class/class.LSldap.php:719
msgid "The password is too short" msgid "The password is too short"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:822 #: includes/class/class.LSldap.php:720
msgid "It is too soon to change the password" msgid "It is too soon to change the password"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:823 #: includes/class/class.LSldap.php:721
msgid "This password was recently used and cannot be used again" msgid "This password was recently used and cannot be used again"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:967 #: includes/class/class.LSldap.php:764
msgid "LSldap: Error during the LDAP server connection (%{msg})." msgid "LSldap: Error during the LDAP server connection (%{msg})."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:970 #: includes/class/class.LSldap.php:767
msgid "LSldap: Error during the LDAP search (%{msg})." msgid "LSldap: Error during the LDAP search (%{msg})."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:973 #: includes/class/class.LSldap.php:770
msgid "LSldap: Object type unknown." msgid "LSldap: Object type unknown."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:976 #: includes/class/class.LSldap.php:773
msgid "LSldap: Error while fetching the LDAP entry." msgid "LSldap: Error while fetching the LDAP entry."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:979 #: includes/class/class.LSldap.php:776
msgid "LSldap: Error while changing the LDAP entry (DN : %{dn})." msgid "LSldap: Error while changing the LDAP entry (DN : %{dn})."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:982 #: includes/class/class.LSldap.php:779
msgid "LSldap: Error while deleting empty attributes." msgid "LSldap: Error while deleting empty attributes."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:985 #: includes/class/class.LSldap.php:782
msgid "LSldap: Error while changing the DN of the object." msgid "LSldap: Error while changing the DN of the object."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:988 #: includes/class/class.LSldap.php:785
msgid "LSldap: LDAP server base DN not configured." msgid "LSldap: LDAP server base DN not configured."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:991 #: includes/class/class.LSldap.php:788
msgid "LSldap: Fail to set authz proxy option on LDAP server connection." msgid "LSldap: Fail to set authz proxy option on LDAP server connection."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:994 #: includes/class/class.LSldap.php:791
msgid "LSldap: Error while changing the user password: %{msg}." msgid "LSldap: Error while changing the user password: %{msg}."
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:997 #: includes/class/class.LSldap.php:794
msgid "LSldap: Unknown LDAP error while updating user password" msgid "LSldap: Unknown LDAP error while updating user password"
msgstr "" msgstr ""
#: includes/class/class.LSldap.php:1000
msgid ""
"LSldap: Fail to execute trigger %{callable} on event %{event} : is not "
"callable."
msgstr ""
#: includes/class/class.LSldap.php:1003
msgid ""
"LSldap: Error during the execution of the trigger %{callable} on event "
"%{event}."
msgstr ""
#: includes/class/class.LSformRule_ldapSearchURI.php:59 #: includes/class/class.LSformRule_ldapSearchURI.php:59
msgid "Invalid LDAP server URI (%{uri})" msgid "Invalid LDAP server URI (%{uri})"
msgstr "" msgstr ""
@ -2558,100 +2403,20 @@ msgstr ""
msgid "Role" msgid "Role"
msgstr "" msgstr ""
#: includes/class/class.LScli.php:104 #: includes/class/class.LScli.php:218
#, php-format
msgid "" msgid ""
"Usage: %s [-h] [-qdC] command\n" "Invalid parameter \"%{parameter}\".\n"
" -h Show this message\n"
" -q|--quiet Quiet mode: nothing log on console (but keep other "
"logging handler)\n"
" -d|--debug Debug mode (set log level to DEBUG, default: WARNING)\n"
" -v|--verbose Verbose mode (set log level to INFO, default: WARNING)\n"
" --trace Trace mode (set log level to TRACE, default: WARNING)\n"
" -C|--console Log on console with same log level as other handlers "
"(otherwise, log only errors)\n"
" -S|--ldap-server Connect to a specific LDAP server: you could specify a "
"LDAP\n"
" server by its declaration order in configuration "
"(default:\n"
" first one).\n"
" -L|--load-class Load specific class to permit access to its CLI "
"commands\n"
" -A|--load-addons Load specific addon to permit access to its CLI "
"commands\n"
" command Command to run\n"
"\n"
" Available commands:\n"
msgstr ""
#: includes/class/class.LScli.php:136
msgid "Currently no available command is declared."
msgstr ""
#: includes/class/class.LScli.php:197 includes/class/class.LScli.php:468
#, php-format
msgid "Fail to select LDAP server #%s."
msgstr ""
#: includes/class/class.LScli.php:208 includes/class/class.LScli.php:503
#, php-format
msgid "Fail to load class '%s'."
msgstr ""
#: includes/class/class.LScli.php:215 includes/class/class.LScli.php:518
#, php-format
msgid "Fail to load addon '%s'."
msgstr ""
#: includes/class/class.LScli.php:226
#, php-format
msgid ""
"Invalid parameter \"%s\".\n"
"Note: Command's parameter/argument must be place after the command." "Note: Command's parameter/argument must be place after the command."
msgstr "" msgstr ""
#: includes/class/class.LScli.php:261 includes/class/class.LScli.php:488 #: includes/class/class.LScli.php:843
#: includes/class/class.LScli.php:536
#, php-format
msgid "Fail to select sub DN '%s'."
msgstr ""
#: includes/class/class.LScli.php:271
msgid "Fail to select first LDAP server."
msgstr ""
#: includes/class/class.LScli.php:391
msgid "Are you sure?"
msgstr ""
#: includes/class/class.LScli.php:392
#, php-format
msgid ""
"\n"
"%s Type 'yes' to continue: "
msgstr ""
#: includes/class/class.LScli.php:395 templates/default/import.tpl:26
#: templates/default/import.tpl:32
msgid "yes"
msgstr ""
#: includes/class/class.LScli.php:396
msgid "User cancel\n"
msgstr ""
#: includes/class/class.LScli.php:852
msgid "LScli : The CLI command '%{command}' already exists." msgid "LScli : The CLI command '%{command}' already exists."
msgstr "" msgstr ""
#: includes/class/class.LScli.php:855 #: includes/class/class.LScli.php:846
msgid "LScli : The CLI command '%{command}' handler is not callable." msgid "LScli : The CLI command '%{command}' handler is not callable."
msgstr "" msgstr ""
#: includes/class/class.LScli.php:864
msgid "Handle BASH completion"
msgstr ""
#: includes/class/class.LSioFormatCSV.php:294 #: includes/class/class.LSioFormatCSV.php:294
msgid "LSioFormatCSV: function fputcsv is not available." msgid "LSioFormatCSV: function fputcsv is not available."
msgstr "" msgstr ""
@ -3032,7 +2797,7 @@ msgstr ""
msgid "Nb / page :" msgid "Nb / page :"
msgstr "" msgstr ""
#: templates/default/showObjectAccessLogs.tpl:71 #: templates/default/showObjectAccessLogs.tpl:70
msgid "No access log found for this object." msgid "No access log found for this object."
msgstr "" msgstr ""
@ -3052,7 +2817,7 @@ msgstr ""
msgid "Object classes" msgid "Object classes"
msgstr "" msgstr ""
#: templates/default/showObjectAccessLogs.tpl:30 #: templates/default/showObjectAccessLogs.tpl:31
msgid "Old value(s)" msgid "Old value(s)"
msgstr "" msgstr ""
@ -3061,7 +2826,7 @@ msgid "Only validate data"
msgstr "" msgstr ""
#: templates/default/showObjectAccessLogs.tpl:11 #: templates/default/showObjectAccessLogs.tpl:11
#: templates/default/showObjectAccessLogs.tpl:28 #: templates/default/showObjectAccessLogs.tpl:29
msgid "Operation" msgid "Operation"
msgstr "" msgstr ""
@ -3165,14 +2930,18 @@ msgstr ""
msgid "Valid" msgid "Valid"
msgstr "" msgstr ""
#: templates/default/showObjectAccessLogs.tpl:31 #: templates/default/showObjectAccessLogs.tpl:30
msgid "Value" msgid "Value"
msgstr "" msgstr ""
#: templates/default/showObjectAccessLogs.tpl:76 #: templates/default/showObjectAccessLogs.tpl:75
msgid "event(s) found for this object." msgid "event(s) found for this object."
msgstr "" msgstr ""
#: templates/default/import.tpl:27 templates/default/import.tpl:33 #: templates/default/import.tpl:27 templates/default/import.tpl:33
msgid "no" msgid "no"
msgstr "" msgstr ""
#: templates/default/import.tpl:26 templates/default/import.tpl:32
msgid "yes"
msgstr ""

View file

@ -3,7 +3,7 @@
<h1>{$pagetitle}</h1> <h1>{$pagetitle}</h1>
{include file='ls:LSview_actions.tpl'} {include file='ls:LSview_actions.tpl'}
<table class='LStable objectAccessLogs'> <table class='LStable'>
<thead> <thead>
<tr> <tr>
<th>{tr msg="Date"}</th> <th>{tr msg="Date"}</th>
@ -22,23 +22,23 @@
<td class="center">{$log.result}{if $log.message} <img class='LStips' src="{img name='help'}" alt="?" title='{$log.message|escape:quotes}'/>{/if}</td> <td class="center">{$log.result}{if $log.message} <img class='LStips' src="{img name='help'}" alt="?" title='{$log.message|escape:quotes}'/>{/if}</td>
<td> <td>
{if $log.mods} {if $log.mods}
<table class="mods"> <table style='margin: auto'>
<thead> <thead>
<tr> <tr>
<th class="col-op">{tr msg="Operation"}</th> <th>{tr msg="Attribute"}</th>
<th class="col-attr">{tr msg="Attribute"}</th> <th>{tr msg="Operation"}</th>
<th class="col-value">{tr msg="Old value(s)"}</th> <th>{tr msg="Value"}</th>
<th class="col-value">{tr msg="Value"}</th> <th>{tr msg="Old value(s)"}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{foreach $log.mods as $attr => $info} {foreach $log.mods as $attr => $info}
<tr> <tr>
<td class="col-op center" {if count($info.changes)>1}rowspan={$info.changes|count}{/if}>{$info.changes.0.op|escape:htmlall}</td> <td class="center" {if count($info.changes)>1}rowspan={$info.changes|count}{/if}>{$attr}</td>
<td class="col-attr center" {if count($info.changes)>1}rowspan={$info.changes|count}{/if}>{$attr}</td> <td class="center">{$info.changes.0.op|escape:htmlall}</td>
<td class="col-value" {if count($info.changes)>1}rowspan={$info.changes|count}{/if}> <td>{$info.changes.0.value|escape:htmlall}</td>
<td {if count($info.changes)>1}rowspan={$info.changes|count}{/if}>
{if $info.old_values} {if $info.old_values}
<div class="copyable copyable-no-btn">
{if count($info.old_values) == 1} {if count($info.old_values) == 1}
{$info.old_values[0]|escape:'htmlall'} {$info.old_values[0]|escape:'htmlall'}
{else} {else}
@ -48,15 +48,14 @@
{/foreach} {/foreach}
</ul> </ul>
{/if} {/if}
</div>
{/if} {/if}
</td> </td>
<td class="col-value"><div class="copyable copyable-no-btn">{$info.changes.0.value|escape:htmlall}</div></td>
</tr> </tr>
{if count($info.changes) > 1} {if count($info.changes) > 1}
{section name=change loop=$info.changes step=1 start=1} {section name=change loop=$info.changes step=1 start=1}
<tr> <tr>
<td class="col-value"><div class="copyable copyable-no-btn">{$info.changes[change].value|escape:htmlall}</div></td> <td>{$info.changes[change].op|escape:htmlall}</td>
<td>{$info.changes[change].value|escape:htmlall}</td>
</tr> </tr>
{/section} {/section}
{/if} {/if}