diff --git a/lam/HISTORY b/lam/HISTORY index cd67bb00..20255fc8 100644 --- a/lam/HISTORY +++ b/lam/HISTORY @@ -1,5 +1,6 @@ September 2020 - PHP 7.4 compatibility + - Windows users: group display format can be configured (cn/dn) 01.05.2020 7.2 - Unix: allow to create group with same name during user creation diff --git a/lam/lib/account.inc b/lam/lib/account.inc index d71f2698..1d53eb3a 100644 --- a/lam/lib/account.inc +++ b/lam/lib/account.inc @@ -1487,8 +1487,9 @@ function getDefaultLDAPErrorString($server) { logNewMessage(LOG_DEBUG, 'Password change failed because of ' . $extError); $extError = _('Your password does not meet the password strength qualifications. Please retry with another one.'); } - $message = _('LDAP error, server says:') . ' ' . ldap_error($server); - if (!empty($extError)) { + $genericErrorMessage = ldap_error($server); + $message = _('LDAP error, server says:') . ' ' . $genericErrorMessage; + if (!empty($extError) && ($genericErrorMessage != $extError)) { $message .= ' - ' . $extError; } return $message; diff --git a/lam/lib/ldap.inc b/lam/lib/ldap.inc index db99d3a9..5c7db093 100644 --- a/lam/lib/ldap.inc +++ b/lam/lib/ldap.inc @@ -67,19 +67,19 @@ class Ldap{ } /** - * Connects to the server using the given username and password - * - * @param string $user user name - * @param string $passwd password - * @param boolean $allowAnonymous specifies if anonymous binds are allowed - * @return mixed if connect succeeds the 0 is returned, else false or error number - */ + * Connects to the server using the given username and password + * + * @param string $user user name + * @param string $passwd password + * @param boolean $allowAnonymous specifies if anonymous binds are allowed + * @throws LAMException unable to connect + */ public function connect($user, $passwd, $allowAnonymous=false) { // close any prior connection @$this->close(); // do not allow anonymous bind if (!$allowAnonymous && ((!$user)||($user == "")||(!$passwd))) { - return false; + throw new LAMException(_("Cannot connect to specified LDAP server. Please try again.")); } // save password und username encrypted $this->encrypt_login($user, $passwd); @@ -94,17 +94,29 @@ class Ldap{ if ($bind) { $return = ldap_errno($this->server); $this->is_connected = true; - // return success number - return $return; + return; } // return error number + $errorNumber = ldap_errno($this->server); + $clientSource = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']; + if (($errorNumber === False) + || ($errorNumber == 81)) { + // connection failed + logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (LDAP error: ' . getDefaultLDAPErrorString($this->server) . ').'); + throw new LAMException(_("Cannot connect to specified LDAP server. Please try again.")); + } + elseif ($errorNumber == 49) { + // user name/password invalid. Return to login page. + logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (wrong password). ' . getDefaultLDAPErrorString($this->server)); + throw new LAMException(_("Wrong password/user name combination. Please try again."), getDefaultLDAPErrorString($this->server)); + } else { - return ldap_errno($this->server); + // other errors + logNewMessage(LOG_ERR, 'User ' . $user . ' (' . $clientSource . ') failed to log in (LDAP error: ' . getDefaultLDAPErrorString($this->server) . ').'); + throw new LAMException(_("LDAP error, server says:"), "($errorNumber) " . getDefaultLDAPErrorString($this->server)); } } - else { - return false; - } + throw new LAMException(_("Cannot connect to specified LDAP server. Please try again.")); } /** Closes connection to server */ @@ -121,8 +133,13 @@ class Ldap{ */ public function server() { if (!$this->is_connected) { - $this->connect($this->getUserName(), $this->getPassword()); - $this->is_connected = true; + try { + $this->connect($this->getUserName(), $this->getPassword()); + $this->is_connected = true; + } + catch (LAMException $e) { + logNewMessage(LOG_ERR, $e->getTitle() . ' ' . $e->getMessage()); + } } return $this->server; } diff --git a/lam/lib/modules/posixAccount.inc b/lam/lib/modules/posixAccount.inc index bf04640d..bf268d81 100644 --- a/lam/lib/modules/posixAccount.inc +++ b/lam/lib/modules/posixAccount.inc @@ -631,7 +631,7 @@ class posixAccount extends baseModule implements passwordService { // Remove primary group from additional groups if (!isset($this->moduleSettings['posixAccount_primaryGroupAsSecondary'][0]) || ($this->moduleSettings['posixAccount_primaryGroupAsSecondary'][0] != 'true')) { - for ($i=0; $igroups); $i++) { + for ($i = 0; $i < count($this->groups); $i++) { if ($this->groups[$i] == $this->getGroupName($this->attributes['gidNumber'][0])) { unset($this->groups[$i]); } @@ -639,8 +639,21 @@ class posixAccount extends baseModule implements passwordService { } else { // add user as memberuid in primary group - if (!in_array($this->getGroupName($this->attributes['gidNumber'][0]), $this->groups)) { - $this->groups[] = $this->getGroupName($this->attributes['gidNumber'][0]); + $primaryGroupName = $this->getGroupName($this->attributes['gidNumber'][0]); + if (!in_array($primaryGroupName, $this->groups)) { + $this->groups[] = $primaryGroupName; + } + // add user as member in group of names if auto-sync is activated + if ($this->isBooleanConfigOptionSet('posixGroup_autoSyncGon')) { + $allGons = $this->findGroupOfNames(); + foreach ($allGons as $gonDn => $gonData) { + if (in_array_ignore_case('posixGroup', $gonData['objectclass'])) { + $gonCn = $gonData['cn'][0]; + if (($gonCn === $primaryGroupName) && !in_array($gonDn, $this->gonList)) { + $this->gonList[] = $gonDn; + } + } + } } } @@ -1034,6 +1047,21 @@ class posixAccount extends baseModule implements passwordService { if (!empty($oldGroupName) && !empty($newGroupName)) { $this->groups = array_delete(array($oldGroupName), $this->groups); $this->groups[] = $newGroupName; + // sync group of names if needed + if ($this->isBooleanConfigOptionSet('posixGroup_autoSyncGon')) { + $allGons = $this->findGroupOfNames(); + foreach ($allGons as $gonDn => $gonData) { + if (in_array_ignore_case('posixGroup', $gonData['objectclass'])) { + $gonCn = $gonData['cn'][0]; + if (($gonCn === $newGroupName) && !in_array($gonDn, $this->gonList)) { + $this->gonList[] = $gonDn; + } + if (($gonCn === $oldGroupName) && in_array($gonDn, $this->gonList)) { + $this->gonList = array_delete(array($gonDn), $this->gonList); + } + } + } + } } } } diff --git a/lam/lib/modules/posixGroup.inc b/lam/lib/modules/posixGroup.inc index 76828ab3..cdd146d2 100644 --- a/lam/lib/modules/posixGroup.inc +++ b/lam/lib/modules/posixGroup.inc @@ -1006,12 +1006,12 @@ class posixGroup extends baseModule implements passwordService { } $added = array_delete($oldValues, $this->attributes['memberUid']); if (!empty($added)) { - $return[] = array('INFO', _('Added users'), htmlspecialchars(implode($added, ', '))); + $return[] = array('INFO', _('Added users'), htmlspecialchars(implode(', ', $added))); } if ($delete) { $deleted = array_delete($this->attributes['memberUid'], $oldValues); if (!empty($deleted)) { - $return[] = array('INFO', _('Removed users'), htmlspecialchars(implode($deleted, ', '))); + $return[] = array('INFO', _('Removed users'), htmlspecialchars(implode(', ', $deleted))); } } return $return; @@ -1049,12 +1049,12 @@ class posixGroup extends baseModule implements passwordService { } $added = array_delete($oldValues, $this->attributes['memberUid']); if (!empty($added)) { - $return[] = array('INFO', _('Added users'), htmlspecialchars(implode($added, ', '))); + $return[] = array('INFO', _('Added users'), htmlspecialchars(implode(', ', $added))); } if ($delete) { $deleted = array_delete($this->attributes['memberUid'], $oldValues); if (!empty($deleted)) { - $return[] = array('INFO', _('Removed users'), htmlspecialchars(implode($deleted, ', '))); + $return[] = array('INFO', _('Removed users'), htmlspecialchars(implode(', ', $deleted))); } } return $return; diff --git a/lam/lib/modules/quota.inc b/lam/lib/modules/quota.inc index 8e54c25b..4577e1e4 100644 --- a/lam/lib/modules/quota.inc +++ b/lam/lib/modules/quota.inc @@ -267,13 +267,13 @@ class quota extends baseModule { return $value; } if ($value >= $tebibytes) { - return round($value / $tebibytes, 3) . 'T'; + return round($value / $tebibytes, 2) . 'T'; } if ($value >= $gibibytes) { - return round($value / $gibibytes, 3) . 'G'; + return round($value / $gibibytes, 2) . 'G'; } if ($value >= $mebibytes) { - return round($value / $mebibytes, 3) . 'M'; + return round($value / $mebibytes, 2) . 'M'; } return $value; } @@ -322,16 +322,16 @@ class quota extends baseModule { return $value; } if ($value >= $trillion) { - return round($value / $trillion, 3) . 't'; + return round($value / $trillion, 2) . 't'; } if ($value >= $billion) { - return round($value / $billion, 3) . 'g'; + return round($value / $billion, 2) . 'g'; } if ($value >= $million) { - return round($value / $million, 3) . 'm'; + return round($value / $million, 2) . 'm'; } if ($value >= $kilo) { - return round($value / $kilo, 3) . 'k'; + return round($value / $kilo, 2) . 'k'; } return $value; } diff --git a/lam/lib/modules/windowsUser.inc b/lam/lib/modules/windowsUser.inc index 43915805..353bc200 100644 --- a/lam/lib/modules/windowsUser.inc +++ b/lam/lib/modules/windowsUser.inc @@ -45,6 +45,11 @@ class windowsUser extends baseModule implements passwordService { /** account is disabled */ const AC_ACCOUNT_DISABLED = 0x00000002; + /** display groups as dn */ + const DISPLAY_GROUPS_DN = 'DN'; + /** display groups as cn */ + const DISPLAY_GROUPS_CN = 'CN'; + /** current group list */ private $groupList = array(); /** original group list */ @@ -412,6 +417,10 @@ class windowsUser extends baseModule implements passwordService { "Headline" => _("Workstations"), 'attr' => 'userWorkstations', "Text" => _("Comma separated list of workstations the user is allowed to login. Empty means every workstation."). ' '. _("Can be left empty.") ), + 'displayGroups' => array( + "Headline" => _('Display format'), + "Text" => _('Specifies how groups are displayed.') + ), ); // upload fields $return['upload_columns'] = array( @@ -1359,24 +1368,62 @@ class windowsUser extends baseModule implements passwordService { $containerRight->add(new htmlAccountPageButton(get_class($this), 'group', 'edit', _('Edit groups')), 12); $containerRight->addVerticalSpacer('1rem'); $groupsList = new htmlGroup(); - $groupCNs = array(); - for ($i = 0; $i < sizeof($this->groupList); $i++) { - $groupCNs[] = extractRDNValue($this->groupList[$i]); + $groupNames = array(); + if ($this->groupDisplayContainsDn()) { + usort($this->groupList, 'compareDN'); } - natcasesort($groupCNs); - foreach ($groupCNs as $cn) { + foreach ($this->groupList as $groupDn) { + $groupCn = extractRDNValue($groupDn); + $groupNames[] = $this->formatGroupName($groupCn, $groupDn); + } + if (!$this->groupDisplayContainsDn()) { + natcasesort($groupNames); + } + foreach ($groupNames as $cn) { $groupsList->addElement(new htmlOutputText($cn)); $groupsList->addElement(new htmlOutputText('
', false)); } - $containerRight->add($groupsList, 12); + $groupsListClass = $this->groupDisplayContainsDn() ? 'rightToLeftText' : ''; + $groupsListDiv = new htmlDiv(null, $groupsList, array($groupsListClass)); + $containerRight->add($groupsListDiv, 12); $container = new htmlResponsiveRow(); - $container->add($containerLeft, 12, 7); - $container->add(new htmlSpacer('1rem', null), 0, 1); - $container->add($containerRight, 12, 4); + $container->add($containerLeft, 12, 12, 7); + $container->add(new htmlSpacer('1rem', null), 0, 0, 1); + $container->add($containerRight, 12, 12, 4); return $container; } + /** + * Formats a group name for the display. + * + * @param string $cn common name + * @param string $dn DN + * @return string formatted name + */ + private function formatGroupName($cn, $dn) { + $mode = empty($this->moduleSettings['windowsUser_displayGroups'][0]) ? 'dn' : $this->moduleSettings['windowsUser_displayGroups'][0]; + switch ($mode) { + case self::DISPLAY_GROUPS_CN: + return $cn; + break; + case self::DISPLAY_GROUPS_DN: + default: + return getAbstractDN($dn); + break; + } + } + + /** + * Returns if the group display name contains the DN. + * + * @return bool contains DN. + */ + private function groupDisplayContainsDn() { + $mode = empty($this->moduleSettings['windowsUser_displayGroups'][0]) ? 'dn' : $this->moduleSettings['windowsUser_displayGroups'][0]; + return ($mode == self::DISPLAY_GROUPS_DN); + } + /** * Returns if any of the work details attributes should be managed. * @@ -1820,26 +1867,45 @@ class windowsUser extends baseModule implements passwordService { $return->setCSSClasses(array('maxrow')); $return->add(new htmlSubTitle(_("Groups")), 12); $groups = $this->findGroups(); + $groupDisplayContainsDn = $this->groupDisplayContainsDn(); // sort by DN - usort($groups, 'compareDN'); + if ($groupDisplayContainsDn) { + usort($groups, 'compareDN'); + } $selectedGroups = array(); // sort by DN - usort($this->groupList, 'compareDN'); + if ($groupDisplayContainsDn) { + usort($this->groupList, 'compareDN'); + } for ($i = 0; $i < sizeof($this->groupList); $i++) { if (in_array($this->groupList[$i], $groups)) { - $selectedGroups[getAbstractDN($this->groupList[$i])] = $this->groupList[$i]; + $groupDn = $this->groupList[$i]; + $groupCn = extractRDNValue($groupDn); + $displayName = $this->formatGroupName($groupCn, $groupDn); + $selectedGroups[$displayName] = $groupDn; } } $availableGroups = array(); foreach ($groups as $dn) { if (!in_array($dn, $this->groupList)) { - $availableGroups[getAbstractDN($dn)] = $dn; + $groupCn = extractRDNValue($dn); + $displayName = $this->formatGroupName($groupCn, $dn); + $availableGroups[$displayName] = $dn; } } + if (!$groupDisplayContainsDn) { + $selectedGroups = array_flip($selectedGroups); + natcasesort($selectedGroups); + $selectedGroups = array_flip($selectedGroups); + $availableGroups = array_flip($availableGroups); + natcasesort($availableGroups); + $availableGroups = array_flip($availableGroups); + } + $this->addDoubleSelectionArea($return, _("Selected groups"), _("Available groups"), - $selectedGroups, null, $availableGroups, null, 'groups', true, true); + $selectedGroups, null, $availableGroups, null, 'groups', $groupDisplayContainsDn, true); // sync options $typeManager = new TypeManager(); @@ -3689,6 +3755,13 @@ class windowsUser extends baseModule implements passwordService { // configuration options $configContainer = new htmlResponsiveRow(); $configContainer->add(new htmlResponsiveInputTextarea('windowsUser_domains', '', 30, 3, _('Domains'), 'domains'), 12); + $displayOptions = array( + 'dn' => self::DISPLAY_GROUPS_DN, + 'cn' => self::DISPLAY_GROUPS_CN, + ); + $groupDisplaySelect = new htmlResponsiveSelect('windowsUser_displayGroups', $displayOptions, array(), _('Display format'), 'displayGroups'); + $groupDisplaySelect->setHasDescriptiveElements(true); + $configContainer->add($groupDisplaySelect, 12); $configHiddenGroup = new htmlGroup(); $configHiddenGroup->addElement(new htmlOutputText(_('Hidden options'))); $configHiddenGroup->addElement(new htmlHelpLink('hiddenOptions')); diff --git a/lam/lib/profiles.inc b/lam/lib/profiles.inc index 3a9711b1..72f3cfa4 100644 --- a/lam/lib/profiles.inc +++ b/lam/lib/profiles.inc @@ -114,7 +114,7 @@ function readAccountProfileFile($fileName) { if ($file) { while (!feof($file)) { $line = fgets($file, 1024); - if (($line == '') || ($line == "\n") || ($line[0] == "#")) { + if (($line === false) || ($line == '') || ($line == "\n") || ($line[0] == "#")) { continue; // ignore comments } // search keywords diff --git a/lam/templates/login.php b/lam/templates/login.php index 4cb74df6..29281410 100644 --- a/lam/templates/login.php +++ b/lam/templates/login.php @@ -11,6 +11,7 @@ use \htmlGroup; use \htmlInputCheckbox; use \htmlButton; use \htmlStatusMessage; +use LAMException; use \Ldap; use \htmlResponsiveRow; use \htmlDiv; @@ -170,12 +171,13 @@ $manifestUrl = preg_replace('/\\?.*/', '', $manifestUrl); $_SESSION['header'] .= ''; /** -* Displays the login window. -* -* @param \LAM\ENV\LAMLicenseValidator $licenseValidator license validator -* @param string $error_message error message to display -*/ -function display_LoginPage($licenseValidator, $error_message) { + * Displays the login window. + * + * @param \LAM\ENV\LAMLicenseValidator $licenseValidator license validator + * @param string $error_message error message to display + * @param string $errorDetails error details + */ +function display_LoginPage($licenseValidator, $error_message, $errorDetails = null) { $config_object = $_SESSION['config']; $cfgMain = $_SESSION["cfgMain"]; logNewMessage(LOG_DEBUG, "Display login page"); @@ -405,7 +407,7 @@ function display_LoginPage($licenseValidator, $error_message) { // error message if(!empty($error_message)) { $row->add(new \htmlSpacer(null, '5px'), 12); - $message = new htmlStatusMessage('ERROR', $error_message); + $message = new htmlStatusMessage('ERROR', $error_message, $errorDetails); $message->colspan = 3; $row->add($message, 12); } @@ -506,7 +508,7 @@ if(isset($_POST['checklogin'])) { // search user in LDAP if needed if ($_SESSION['config']->getLoginMethod() == LAMConfig::LOGIN_SEARCH) { $searchFilter = $_SESSION['config']->getLoginSearchFilter(); - $searchFilter = str_replace('%USER%', $username ,$searchFilter); + $searchFilter = str_replace('%USER%', $username, $searchFilter); $searchDN = ''; $searchPassword = ''; $configLoginSearchDn = $_SESSION['config']->getLoginSearchDN(); @@ -517,57 +519,58 @@ if(isset($_POST['checklogin'])) { $searchSuccess = true; $searchError = ''; $searchLDAP = new Ldap($_SESSION['config']); - $searchLDAPResult = $searchLDAP->connect($searchDN, $searchPassword, true); - if (! ($searchLDAPResult == 0)) { - $searchSuccess = false; - $searchError = _('Cannot connect to specified LDAP server. Please try again.') . ' ' . getDefaultLDAPErrorString($searchLDAP->server()); - } - else { - $searchResult = ldap_search($searchLDAP->server(), $_SESSION['config']->getLoginSearchSuffix(), $searchFilter, array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); - if ($searchResult) { - $searchInfo = ldap_get_entries($searchLDAP->server(), $searchResult); - if ($searchInfo) { - cleanLDAPResult($searchInfo); - if (sizeof($searchInfo) == 0) { - $searchSuccess = false; - $searchError = _('Wrong password/user name combination. Please try again.'); - } - elseif (sizeof($searchInfo) > 1) { - $searchSuccess = false; - $searchError = _('The given user name matches multiple LDAP entries.'); - } - else { - $username = $searchInfo[0]['dn']; - } - } - else { - $searchSuccess = false; - $searchError = _('Unable to find the user name in LDAP.'); - if (ldap_errno($searchLDAP->server()) != 0) { - $searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server()); - } - } + try { + $searchLDAP->connect($searchDN, $searchPassword, true); + $searchResult = ldap_search($searchLDAP->server(), $_SESSION['config']->getLoginSearchSuffix(), $searchFilter, array('dn'), 0, 0, 0, LDAP_DEREF_NEVER); + if ($searchResult) { + $searchInfo = ldap_get_entries($searchLDAP->server(), $searchResult); + if ($searchInfo) { + cleanLDAPResult($searchInfo); + if (sizeof($searchInfo) == 0) { + $searchSuccess = false; + $searchError = _('Wrong password/user name combination. Please try again.'); + } + elseif (sizeof($searchInfo) > 1) { + $searchSuccess = false; + $searchError = _('The given user name matches multiple LDAP entries.'); + } + else { + $username = $searchInfo[0]['dn']; + } + } + else { + $searchSuccess = false; + $searchError = _('Unable to find the user name in LDAP.'); + if (ldap_errno($searchLDAP->server()) != 0) { + $searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server()); + } + } + } + else { + $searchSuccess = false; + $searchError = _('Unable to find the user name in LDAP.'); + if (ldap_errno($searchLDAP->server()) != 0) { + $searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server()); + } + } + if (!$searchSuccess) { + $error_message = $searchError; + logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in. ' . $searchError . ''); + $searchLDAP->close(); + display_LoginPage($licenseValidator, $error_message); + exit(); } - else { - $searchSuccess = false; - $searchError = _('Unable to find the user name in LDAP.'); - if (ldap_errno($searchLDAP->server()) != 0) { - $searchError .= ' ' . getDefaultLDAPErrorString($searchLDAP->server()); - } - } - } - if (!$searchSuccess) { - $error_message = $searchError; - logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in. ' . $searchError . ''); $searchLDAP->close(); - display_LoginPage($licenseValidator, $error_message); - exit(); } - $searchLDAP->close(); + catch (LAMException $e) { + $searchLDAP->close(); + display_LoginPage($licenseValidator, $e->getTitle(), $e->getMessage()); + exit(); + } } // try to connect to LDAP - $result = $_SESSION['ldap']->connect($username, $password); // Connect to LDAP server for verifying username/password - if($result === 0) {// Username/password correct. Do some configuration and load main frame. + try { + $_SESSION['ldap']->connect($username, $password); // Connect to LDAP server for verifying username/password $_SESSION['loggedIn'] = true; // set security settings for session $_SESSION['sec_session_id'] = session_id(); @@ -586,26 +589,10 @@ if(isset($_POST['checklogin'])) { } die(); } - else { - if (($result === False) - || ($result == 81)) { - // connection failed - $error_message = _("Cannot connect to specified LDAP server. Please try again."); - logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); - } - elseif ($result == 49) { - // user name/password invalid. Return to login page. - $error_message = _("Wrong password/user name combination. Please try again."); - logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (wrong password).'); - } - else { - // other errors - $error_message = _("LDAP error, server says:") . "\n
($result) " . ldap_err2str($result); - logNewMessage(LOG_ERR, 'User ' . $username . ' (' . $clientSource . ') failed to log in (LDAP error: ' . ldap_err2str($result) . ').'); - } - display_LoginPage($licenseValidator, $error_message); + catch (LAMException $e) { + display_LoginPage($licenseValidator, $e->getTitle(), $e->getMessage()); exit(); - } + } } //displays the login window diff --git a/lam/tests/lib/modules/quotaTest.php b/lam/tests/lib/modules/quotaTest.php index cab644a6..d1b40f6b 100644 --- a/lam/tests/lib/modules/quotaTest.php +++ b/lam/tests/lib/modules/quotaTest.php @@ -56,10 +56,10 @@ class QuotaTest extends TestCase { $this->assertEquals('123G', $quota->formatBlockUsage(1024*1024*123)); $this->assertEquals('123M', $quota->formatBlockUsage(1024*123)); $this->assertEquals('123', $quota->formatBlockUsage(123)); - $this->assertEquals('1.001M', $quota->formatBlockUsage(1025)); - $this->assertEquals('4.883T', $quota->formatBlockUsage(1024*1024*5000)); - $this->assertEquals('4.883G', $quota->formatBlockUsage(1024*5000)); - $this->assertEquals('4.883M', $quota->formatBlockUsage(5000)); + $this->assertEquals('1M', $quota->formatBlockUsage(1025)); + $this->assertEquals('4.88T', $quota->formatBlockUsage(1024*1024*5000)); + $this->assertEquals('4.88G', $quota->formatBlockUsage(1024*5000)); + $this->assertEquals('4.88M', $quota->formatBlockUsage(5000)); } public function testAddInodeUnits() { @@ -85,11 +85,11 @@ class QuotaTest extends TestCase { $this->assertEquals('123m', $quota->formatInodeUsage(1000*1000*123)); $this->assertEquals('123k', $quota->formatInodeUsage(1000*123)); $this->assertEquals('123', $quota->formatInodeUsage(123)); - $this->assertEquals('1.025k', $quota->formatInodeUsage(1025)); - $this->assertEquals('5.001t', $quota->formatInodeUsage(1000*1000*1000*5001)); - $this->assertEquals('5.001g', $quota->formatInodeUsage(1000*1000*5001)); - $this->assertEquals('5.001m', $quota->formatInodeUsage(1000*5001)); - $this->assertEquals('5.001k', $quota->formatInodeUsage(5001)); + $this->assertEquals('1.03k', $quota->formatInodeUsage(1025)); + $this->assertEquals('5t', $quota->formatInodeUsage(1000*1000*1000*5001)); + $this->assertEquals('5g', $quota->formatInodeUsage(1000*1000*5001)); + $this->assertEquals('5m', $quota->formatInodeUsage(1000*5001)); + $this->assertEquals('5k', $quota->formatInodeUsage(5001)); } }