diff --git a/include/class.auth.php b/include/class.auth.php index 213730e67b06748a6057afb10e34393b18124a18..efab40230af3da62f98219a86c174f29435af4aa 100644 --- a/include/class.auth.php +++ b/include/class.auth.php @@ -158,7 +158,7 @@ abstract class AuthenticationBackend { $backends = static::getAllowedBackends($username); foreach (static::allRegistered() as $bk) { if ($backends //Allowed backends - && $bk->supportsAuthentication() + && $bk->supportsInteractiveAuthentication() && !in_array($bk::$id, $backends)) // User cannot be authenticated against this backend continue; @@ -250,7 +250,7 @@ abstract class AuthenticationBackend { * Indicates if the backed supports authentication. Useful if the * backend is used for logging or lockout only */ - function supportsAuthentication() { + function supportsInteractiveAuthentication() { return true; } @@ -369,7 +369,7 @@ abstract class StaffAuthenticationBackend extends AuthenticationBackend { Signal::send('auth.login.succeeded', $staff); - if ($bk->supportsAuthentication()) + if ($bk->supportsInteractiveAuthentication()) $staff->cancelResetTokens(); return true; @@ -507,7 +507,7 @@ abstract class UserAuthenticationBackend extends AuthenticationBackend { $user->getUserName(), $user->getId(), $_SERVER['REMOTE_ADDR']); $ost->logDebug('User login', $msg); - if ($bk->supportsAuthentication() && ($acct=$user->getAccount())) + if ($bk->supportsInteractiveAuthentication() && ($acct=$user->getAccount())) $acct->cancelResetTokens(); return true; @@ -598,7 +598,7 @@ abstract class AuthStrikeBackend extends AuthenticationBackend { return null; } - function supportsAuthentication() { + function supportsInteractiveAuthentication() { return false; } @@ -763,7 +763,7 @@ StaffAuthenticationBackend::register('osTicketAuthentication'); class PasswordResetTokenBackend extends StaffAuthenticationBackend { static $id = "pwreset.staff"; - function supportsAuthentication() { + function supportsInteractiveAuthentication() { return false; } @@ -831,9 +831,13 @@ class AuthTokenAuthentication extends UserAuthenticationBackend { return $user; } + function supportsInteractiveAuthentication() { + return false; + } + protected function getAuthKey($user) { - if (!$this->supportsAuthentication() || !$user) + if (!$user) return null; //Generate authkey based the type of ticket user @@ -912,7 +916,9 @@ class AccessLinkAuthentication extends UserAuthenticationBackend { function login($user, $bk) { return true; } - + function supportsInteractiveAuthentication() { + return false; + } } UserAuthenticationBackend::register('AccessLinkAuthentication'); @@ -938,7 +944,7 @@ UserAuthenticationBackend::register('osTicketClientAuthentication'); class ClientPasswordResetTokenBackend extends UserAuthenticationBackend { static $id = "pwreset.client"; - function supportsAuthentication() { + function supportsInteractiveAuthentication() { return false; } @@ -976,7 +982,7 @@ UserAuthenticationBackend::register('ClientPasswordResetTokenBackend'); class ClientAcctConfirmationTokenBackend extends UserAuthenticationBackend { static $id = "confirm.client"; - function supportsAuthentication() { + function supportsInteractiveAuthentication() { return false; } diff --git a/include/class.client.php b/include/class.client.php index 707418456e3e15b1ebefc53d2f10d0ba360b258d..3ad25fa3947e6001cc3d7c0a3f73e97ff16cc1b5 100644 --- a/include/class.client.php +++ b/include/class.client.php @@ -306,12 +306,6 @@ class ClientAccount extends UserAccount { unset($_SESSION['_client']['reset-token']); } - function getInfo() { - $base = parent::getInfo(); - $base['tz_offset'] = $this->timezone; - return $base; - } - function update($vars, &$errors) { $rtoken = $_SESSION['_client']['reset-token']; if ($vars['passwd1'] || $vars['passwd2'] || $vars['cpasswd'] || $rtoken) { @@ -362,7 +356,7 @@ class ClientAccount extends UserAccount { $info = array('password' => $vars['passwd1']); Signal::send('auth.pwchange', $this, $info); $this->cancelResetTokens(); - $this->_clearStatus(self::PASSWD_RESET_REQUIRED); + $this->clearStatus(self::REQUIRE_PASSWD_RESET); } return $this->save(); diff --git a/include/class.user.php b/include/class.user.php index ba4a19401827f5216d977f92e333984794e5a7c6..d51c61639fb8a5509c7f0fefdd049664f8ec0653 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -547,7 +547,8 @@ class UserAccount extends UserAccountModel { const CONFIRMED = 0x0001; const LOCKED = 0x0002; - const PASSWD_RESET_REQUIRED = 0x0004; + const REQUIRE_PASSWD_RESET = 0x0004; + const FORBID_PASSWD_RESET = 0x0008; protected function hasStatus($flag) { return 0 !== ($this->get('status') & $flag); @@ -580,12 +581,16 @@ class UserAccount extends UserAccountModel { } function forcePasswdReset() { - $this->setStatus(self::PASSWD_RESET_REQUIRED); + $this->setStatus(self::REQUIRE_PASSWD_RESET); return $this->save(); } function isPasswdResetForced() { - return $this->hasStatus(self::PASSWD_RESET_REQUIRED); + return $this->hasStatus(self::REQUIRE_PASSWD_RESET); + } + + function isPasswdResetEnabled() { + return !$this->hasStatus(self::FORBID_PASSWD_RESET); } function hasPassword() { @@ -737,15 +742,16 @@ class UserAccount extends UserAccountModel { } // Set flags - if ($vars['pwreset-flag']) - $this->setStatus(self::PASSWD_RESET_REQUIRED); - else - $this->clearStatus(self::PASSWD_RESET_REQUIRED); - - if ($vars['locked-flag']) - $this->setStatus(self::LOCKED); - else - $this->clearStatus(self::LOCKED); + foreach (array( + 'pwreset-flag'=> self::REQUIRE_PASSWD_RESET, + 'locked-flag'=> self::LOCKED, + 'forbid-pwchange-flag'=> self::FORBID_PASSWD_RESET + ) as $ck=>$flag) { + if ($vars[$ck]) + $this->setStatus($flag); + else + $this->clearStatus($flag); + } return $this->save(true); } @@ -763,13 +769,14 @@ class UserAccount extends UserAccountModel { return $user; } - static function register($user, $vars, &$errors) { + static function register($user, $vars, &$errors) { if (!$user || !$vars) return false; //Require temp password. - if (!isset($vars['sendemail'])) { + if ((!$vars['backend'] || $vars['backend'] != 'client') + && !isset($vars['sendemail'])) { if (!$vars['passwd1']) $errors['passwd1'] = 'Temp. password required'; elseif ($vars['passwd1'] && strlen($vars['passwd1'])<6) @@ -786,15 +793,18 @@ class UserAccount extends UserAccountModel { $account->set('dst', isset($vars['dst'])?1:0); $account->set('timezone_id', $vars['timezone_id']); + $account->set('backend', $vars['backend']); if ($vars['username'] && strcasecmp($vars['username'], $user->getEmail())) $account->set('username', $vars['username']); if ($vars['passwd1'] && !$vars['sendemail']) { - $account->set('passwd', Password::hash($vars['passwd1'])); + $account->set('passwd', Passwd::hash($vars['passwd1'])); $account->setStatus(self::CONFIRMED); if ($vars['pwreset-flag']) - $account->setStatus(self::PASSWD_RESET_REQUIRED); + $account->setStatus(self::REQUIRE_PASSWD_RESET); + if ($vars['forbid-pwreset-flag']) + $account->setStatus(self::FORBID_PASSWD_RESET); } $account->save(true); diff --git a/include/client/profile.inc.php b/include/client/profile.inc.php index d5651031cdaac3a0a5975edd862384a18d69bfe6..8586c3976f1a117c4887b44670e905c1ee073b8f 100644 --- a/include/client/profile.inc.php +++ b/include/client/profile.inc.php @@ -50,6 +50,7 @@ if ($acct = $thisclient->getAccount()) { <em>(Current Time: <strong><?php echo Format::date($cfg->getDateTimeFormat(),Misc::gmtime(),$info['tz_offset'],$info['dst']); ?></strong>)</em> </td> </tr> +<?php if ($acct->isPasswdResetEnabled()) { ?> <tr> <td colspan=2"> <div><hr><h3>Access Credentials</h3></div> @@ -85,6 +86,7 @@ if ($acct = $thisclient->getAccount()) { </td> </tr> <?php } ?> +<?php } ?> </table> <hr> <p style="text-align: center;"> diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php index 954aaa8f106eda30b116f8c8ef84d3af9c0793c4..c40b2d56be54bc1c883c73de32c65094c4893bae 100644 --- a/include/staff/staff.inc.php +++ b/include/staff/staff.inc.php @@ -142,7 +142,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); "> <option value="">— Use any available backend —</option> <?php foreach (StaffAuthenticationBackend::allRegistered() as $ab) { - if (!$ab->supportsAuthentication()) continue; ?> + if (!$ab->supportsInteractiveAuthentication()) continue; ?> <option value="<?php echo $ab::$id; ?>" <?php if ($info['backend'] == $ab::$id) echo 'selected="selected"'; ?>><?php diff --git a/include/staff/templates/user-account.tmpl.php b/include/staff/templates/user-account.tmpl.php index 5a08e8e4cf3696c44efbdcd59d3a5530b7850dfd..8304d8afa975f9d08c48ff1e0717f6e0308eb907 100644 --- a/include/staff/templates/user-account.tmpl.php +++ b/include/staff/templates/user-account.tmpl.php @@ -143,6 +143,9 @@ if ($info['error']) { <div><input type="checkbox" name="pwreset-flag" value="1" <?php echo $account->isPasswdResetForced() ? 'checked="checked"' : ''; ?>> Password Reset Required</div> + <div><input type="checkbox" name="forbid-pwchange-flag" value="1" <?php + echo !$account->isPasswdResetEnabled() ? + 'checked="checked"' : ''; ?>> User Cannot Change Password</div> </td> </tr> </tbody> diff --git a/include/staff/templates/user-register.tmpl.php b/include/staff/templates/user-register.tmpl.php index 8f87c41a3453add53001dc3d1bf62f2671a07bf4..99fbc3f348259f3cab5b7e21fc97b2c76ed5cc71 100644 --- a/include/staff/templates/user-register.tmpl.php +++ b/include/staff/templates/user-register.tmpl.php @@ -41,13 +41,30 @@ $user->getName()->getOriginal(); ?></b>.</p></div> </th> </tr> <tr> - <td width="180"> - Status: - </td> + <td>Authentication Sources:</td> <td> - <input type="checkbox" id="sendemail" name="sendemail" value="1" - <?php echo $info['sendemail'] ? 'checked="checked"' : ''; ?> > - Send account activation email to <?php echo $user->getEmail(); ?>. + <select name="backend" id="backend-selection" onchange="javascript: + if (this.value != '' && this.value != 'client') { + $('#activation').hide(); + $('#password').hide(); + } + else { + $('#activation').show(); + if ($('#sendemail').is(':checked')) + $('#password').hide(); + else + $('#password').show(); + } + "> + <option value="">— Use any available backend —</option> + <?php foreach (UserAuthenticationBackend::allRegistered() as $ab) { + if (!$ab->supportsInteractiveAuthentication()) continue; ?> + <option value="<?php echo $ab::$id; ?>" <?php + if ($info['backend'] == $ab::$id) + echo 'selected="selected"'; ?>><?php + echo $ab::$name; ?></option> + <?php } ?> + </select> </td> </tr> <tr> @@ -60,6 +77,18 @@ $user->getName()->getOriginal(); ?></b>.</p></div> </td> </tr> </tbody> + <tbody id="activation"> + <tr> + <td width="180"> + Status: + </td> + <td> + <input type="checkbox" id="sendemail" name="sendemail" value="1" + <?php echo $info['sendemail'] ? 'checked="checked"' : ''; ?> > + Send account activation email to <?php echo $user->getEmail(); ?>. + </td> + </tr> + </tbody> <tbody id="password" style="<?php echo $info['sendemail'] ? 'display:none;' : ''; ?>" > @@ -89,6 +118,9 @@ $user->getName()->getOriginal(); ?></b>.</p></div> <td colspan=2> <input type="checkbox" name="pwreset-flag" value="1" <?php echo $info['pwreset-flag'] ? 'checked="checked"' : ''; ?>> Require password change on login + <br/> + <input type="checkbox" name="forbid-pwreset-flag" value="1" <?php + echo $info['forbid-pwreset-flag'] ? 'checked="checked"' : ''; ?>> User cannot change password </td> </tr> </tbody> diff --git a/pwreset.php b/pwreset.php index 6fb51b48728df6292ca5daddc24586434bca39c6..7b2a636e5cc4322dcaae1de656791c530a9329a6 100644 --- a/pwreset.php +++ b/pwreset.php @@ -19,6 +19,10 @@ if($_POST) { if (!$acct->hasPassword()) { $banner = 'Unable to reset password. Contact your administrator'; } + elseif (!$acct->isPasswdResetEnabled()) { + $banner = 'Password reset is not enabled for your account. ' + .'Contact your administrator'; + } elseif (!$acct->sendResetEmail()) { $inc = 'pwreset.sent.php'; }