diff --git a/account.php b/account.php index 657f0983153d4c47eca69838e712812c2186b996..295073f881172d251c46a29d5e10300b0a19204f 100644 --- a/account.php +++ b/account.php @@ -98,14 +98,13 @@ elseif ($_POST) { $acct->sendConfirmEmail(); break; case 'import': - foreach (UserAuthenticationBackend::allRegistered() as $bk) { - if ($bk::$id == $_POST['backend']) { - $cl = new ClientSession(new EndUser($user)); - $acct->confirm(); - if ($user = $bk->login($cl, $bk)) - Http::redirect('tickets.php'); - break; - } + if ($bk = UserAuthenticationBackend::getBackend($_POST['backend'])) { + $cl = new ClientSession(new EndUser($user)); + if (!$bk->supportsInteractiveAuthentication()) + $acct->set('backend', null); + $acct->confirm(); + if ($user = $bk->login($cl, $bk)) + Http::redirect('tickets.php'); } break; } diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css index 3c558720ba239b9e2ef28648102d5f5aaa6737b1..8a3ea45df2bd5e24e0af7cd2c37dc186c8a500b4 100644 --- a/assets/default/css/theme.css +++ b/assets/default/css/theme.css @@ -522,7 +522,7 @@ body { color: #555; } #ticketForm div.clear, -#clientLogin div { +#clientLogin div.clear { clear: both; padding: 3px 0; overflow: hidden; @@ -651,6 +651,16 @@ label.required { width: 120px; margin-right: 0; } +#clientLogin input[type=text], +#clientLogin input[type=password] { + padding: 5px; + border-radius: 4px; + margin-bottom: 15px; +} +#clientLogin input[type=submit] { + padding: 3px 10px; + border-radius: 4px; +} #reply { margin-top: 20px; padding: 10px 5px; @@ -876,3 +886,37 @@ table.padded tr > th { height: 20px; padding-bottom: 5px; } + +.external-auth + .external-auth { + margin-top: 4px; +} + +a.external-sign-in { + text-decoration: none; +} +.external-auth-box { + vertical-align: middle; + border-radius: 4px; + border: 1px solid #777; +} +.external-auth-icon { + display: inline-block; + color: #333; + width: 30px; + padding: 5px 10px; + border-right: 1px solid #ddd; +} +.external-auth-name { + color: #333; + width: 100px; + padding: 5px 10px; + line-height:30px; + font-size: 11pt; +} +img.sign-in-image { + border: none; + max-height: 40px; + max-width: 200px; + width: auto; + height: auto; +} diff --git a/include/class.auth.php b/include/class.auth.php index e77fec723db46db8c56d56460b1b0068d44afad7..39498a474578f4c87bf4f77bac651408421de4c5 100644 --- a/include/class.auth.php +++ b/include/class.auth.php @@ -223,6 +223,9 @@ abstract class AuthenticationBackend { return $result; } + elseif ($result instanceof ClientCreateRequest + && $bk instanceof UserAuthenticationBackend) + return $result; elseif ($result instanceof AccessDenied) { break; } diff --git a/include/class.user.php b/include/class.user.php index 083368fc6afd91b3147624d057dedd80400eee9b..17408aa3384ec52248de6892feaba79abe6c7389 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -917,8 +917,13 @@ class UserAccount extends UserAccountModel { return $this->save(true); } - static function createForUser($user) { - return static::create(array('user_id'=>$user->getId())); + static function createForUser($user, $defaults=false) { + $acct = static::create(array('user_id'=>$user->getId())); + if ($defaults && is_array($defaults)) { + foreach ($defaults as $k => $v) + $acct->set($k, $v); + } + return $acct; } static function lookupByUsername($username) { diff --git a/include/client/login.inc.php b/include/client/login.inc.php index fd1d7bc80abac91077654ae8a58d2cfc285b0444..2430a77c0abb05fc587e3df388de248b3a543fbb 100644 --- a/include/client/login.inc.php +++ b/include/client/login.inc.php @@ -21,16 +21,13 @@ if ($content) { <form action="login.php" method="post" id="clientLogin"> <?php csrf_token(); ?> <div style="display:table-row"> - <div style="width:40%;display:table-cell;box-shadow: 12px 0 15px -15px rgba(0,0,0,0.4);padding-left: 2em;"> + <div style="width:40%;display:table-cell;box-shadow: 12px 0 15px -15px rgba(0,0,0,0.4);padding:15px;"> <strong><?php echo Format::htmlchars($errors['login']); ?></strong> - <br> <div> - <label for="username">Username:</label> - <input id="username" type="text" name="luser" size="30" value="<?php echo $email; ?>"> + <input id="username" placeholder="username" type="text" name="luser" size="30" value="<?php echo $email; ?>"> </div> <div> - <label for="passwd">Password:</label> - <input id="passwd" type="password" name="lpasswd" size="30" value="<?php echo $passwd; ?>"></td> + <input id="passwd" placeholder="password" type="password" name="lpasswd" size="30" value="<?php echo $passwd; ?>"></td> </div> <p> <input class="btn" type="submit" value="Sign In"> @@ -39,9 +36,22 @@ if ($content) { <?php } ?> </p> </div> - <div style="display:table-cell;padding-left: 2em;"> -<?php if ($cfg && $cfg->isClientRegistrationEnabled()) { ?> - Not yet registered? <a href="account.php?do=create">Create an account</a> + <div style="display:table-cell;padding: 15px;vertical-align:top"> +<?php + +$ext_bks = array(); +foreach (UserAuthenticationBackend::allRegistered() as $bk) + if ($bk instanceof ExternalAuthentication) + $ext_bks[] = $bk; + +if (count($ext_bks)) { + foreach ($ext_bks as $bk) { ?> +<div class="external-auth"><?php $bk->renderExternalLink(); ?></div><?php + } +} +if ($cfg && $cfg->isClientRegistrationEnabled()) { + if (count($ext_bks)) echo '<hr style="width:70%"/>'; ?> + Not yet registered? <a href="account.php?do=create">Create an account</a> <?php } ?> </div> </div> diff --git a/login.php b/login.php index 5d1faa1ecd24944e76a4b453731ffb164a425301..e0fe762645f6bc9e1c92ec24fcb03ef1221621cb 100644 --- a/login.php +++ b/login.php @@ -71,6 +71,55 @@ elseif ($_POST && isset($_POST['lticket'])) { $errors['err'] = 'Invalid email or ticket number - try again!'; } } +elseif (isset($_GET['do'])) { + switch($_GET['do']) { + case 'ext': + // Lookup external backend + if ($bk = UserAuthenticationBackend::getBackend($_GET['bk'])) + $bk->triggerAuth(); + } +} +elseif ($user = UserAuthenticationBackend::processSignOn($errors, false)) { + // Users from the ticket access link + if ($user && $user instanceof TicketUser && $user->getTicketId()) + Http::redirect('tickets.php?id='.$user->getTicketId()); + // Users imported from an external auth backend + elseif ($user instanceof ClientCreateRequest) { + if ($cfg && $cfg->isClientRegistrationEnabled()) { + // Attempt to automatically register + $user_form = UserForm::getUserForm()->getForm($user->getInfo()); + $bk = $user->getBackend(); + $defaults = array( + 'timezone_id' => $cfg->getDefaultTimezoneId(), + 'dst' => $cfg->observeDaylightSaving(), + 'username' => $user->getUsername(), + ); + if ($bk->supportsInteractiveAuthentication()) + $defaults['backend'] = $bk::$id; + if ($user_form->isValid(function($f) { return !$f->get('private'); }) + && ($U = User::fromVars($user_form->getClean())) + && ($acct = ClientAccount::createForUser($U, $defaults)) + // Confirm and save the account + && $acct->confirm() + // Login, since `tickets.php` will not attempt SSO + && ($cl = new ClientSession(new EndUser($U))) + && ($bk->login($cl, $bk))) + Http::redirect('tickets.php'); + + // Unable to auto-register. Fill in what we have and let the + // user complete the info + $inc = 'register.inc.php'; + } + else { + $errors['err'] = 'Access Denied. Contact your help desk + administrator to have an account registered for you'; + // fall through to show login page again + } + } + elseif ($user instanceof AuthenticatedUser) { + Http::redirect('tickets.php'); + } +} if (!$nav) { $nav = new UserNav();