diff --git a/lam/graphics/expired.png b/lam/graphics/expired.png new file mode 100644 index 00000000..f6cbf891 Binary files /dev/null and b/lam/graphics/expired.png differ diff --git a/lam/lib/modules/shadowAccount.inc b/lam/lib/modules/shadowAccount.inc index 49107aaf..7a2b9c53 100644 --- a/lam/lib/modules/shadowAccount.inc +++ b/lam/lib/modules/shadowAccount.inc @@ -4,7 +4,7 @@ $Id$ This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) Copyright (C) 2003 - 2006 Tilo Lutz - Copyright (C) 2007 - 2016 Roland Gruber + Copyright (C) 2007 - 2017 Roland Gruber This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -784,7 +784,7 @@ class shadowAccount extends baseModule implements passwordService { } $time = new DateTime('@' . $attrs['shadowexpire'][0] * 24 * 3600, new DateTimeZone('UTC')); $now = new DateTime(null, getTimeZone()); - return ($time > $now); + return ($time < $now); } } diff --git a/lam/lib/types/user.inc b/lam/lib/types/user.inc index 9ca5c3c3..ede0a5d8 100644 --- a/lam/lib/types/user.inc +++ b/lam/lib/types/user.inc @@ -346,7 +346,25 @@ class user extends baseType { if ($isEditable) { $onClick = 'onclick="showConfirmationDialog(\'' . _('Change account status') . '\', \'' . _('Ok') . '\', \'' . _('Cancel') . '\', \'lam_accountStatusDialog\', \'inputForm\', \'lam_accountStatusResult\');"'; } - return $dialogDiv . 'status   '; + $dialogDiv .= 'status   '; + // expiration status + $expiredLabels = array(); + $shadowModule = $container->getAccountModule('shadowAccount'); + if ($shadowModule != null) { + $shadowAttrs = $shadowModule->getAttributes(); + if (shadowAccount::isAccountExpired($shadowAttrs)) { + $expiredLabels[] = _('Shadow'); + } + } + if (!empty($expiredLabels)) { + $expiredTip = ''; + foreach ($expiredLabels as $label) { + $expiredTip .= ''; + } + $expiredTip .= '
' . $label . '
'; + $dialogDiv .= 'expired   '; + } + return $dialogDiv; } /** @@ -899,6 +917,7 @@ class lamUserList extends lamList { $attrs[] = 'lockoutTime'; $attrs[] = 'nsAccountLock'; $attrs[] = 'accountUnlockTime'; + $attrs[] = 'shadowExpire'; $attrs[] = 'objectClass'; } return $attrs; @@ -978,16 +997,25 @@ class lamUserList extends lamList { && (!$sambaAvailable || $sambaLocked) && (!$ppolicyAvailable || $ppolicyLocked) && (!$windowsAvailable || $windowsLocked); + $shadowExpired = shadowAccount::isAccountExpired($attrs); + $expired = $shadowExpired; $icon = 'unlocked.png'; - if ($fullyLocked) { + if ($expired) { + $icon = 'expired.png'; + } + elseif ($fullyLocked) { $icon = 'lock.png'; } elseif ($partiallyLocked) { $icon = 'partiallyLocked.png'; } // print icon and detail tooltips - if ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsDeactivated) { + if ($unixAvailable || $sambaAvailable || $ppolicyAvailable || $windowsAvailable || $is389dsDeactivated || $expired) { $tipContent = ''; + // Shadow expired + if ($shadowExpired) { + $tipContent .= ''; + } // Unix if ($unixAvailable) { $unixIcon = 'unlocked.png'; @@ -1049,6 +1077,16 @@ class lamUserList extends lamList { return (isset($attrs['objectclass']) && in_array_ignore_case('posixAccount', $attrs['objectclass']) && isset($attrs['userpassword'][0])); } + /** + * Returns if the Shadow part exists. + * + * @param array $attrs LDAP attributes + * @return boolean Shadow part exists + */ + public static function isShadowAvailable(&$attrs) { + return (isset($attrs['objectclass']) && in_array_ignore_case('shadowAccount', $attrs['objectclass'])); + } + /** * Returns if the Unix part is locked. * diff --git a/lam/tests/lib/modules/shadowAccountTest.php b/lam/tests/lib/modules/shadowAccountTest.php index bfcacd30..f46a0f3c 100644 --- a/lam/tests/lib/modules/shadowAccountTest.php +++ b/lam/tests/lib/modules/shadowAccountTest.php @@ -21,13 +21,50 @@ */ -if (is_readable('lam/lib/passwordExpirationJob.inc')) { - include_once 'lam/lib/baseModule.inc'; include_once 'lam/lib/modules.inc'; - include_once 'lam/lib/passwordExpirationJob.inc'; + if (is_readable('lam/lib/passwordExpirationJob.inc')) { + include_once 'lam/lib/passwordExpirationJob.inc'; + } include_once 'lam/lib/modules/shadowAccount.inc'; + /** + * Checks the shadowAccount class. + * + * @author Roland Gruber + */ + class ShadowAccountTest extends PHPUnit_Framework_TestCase { + + public function test_isAccountExpired_noAttr() { + $attrs = array('objectClass' => array('shadowAccount')); + + $this->assertFalse(shadowAccount::isAccountExpired($attrs)); + } + + public function test_isAccountExpired_notExpired() { + $expire = intval(time() / (24*3600)) + 10000; + $attrs = array( + 'objectClass' => array('shadowAccount'), + 'sHadoweXpirE' => array(0 => $expire) + ); + + $this->assertFalse(shadowAccount::isAccountExpired($attrs)); + } + + public function test_isAccountExpired_expired() { + $expire = intval(time() / (24*3600)) - 10000; + $attrs = array( + 'objectClass' => array('shadowAccount'), + 'sHadoweXpirE' => array(0 => $expire) + ); + + $this->assertTrue(shadowAccount::isAccountExpired($attrs)); + } + + } + +if (is_readable('lam/lib/passwordExpirationJob.inc')) { + /** * Checks the shadow expire job. *
' . _('Shadow') . '