Merge pull request #23947 from owncloud/login-to-ctrl

Move login form into controller
This commit is contained in:
Lukas Reschke 2016-04-18 11:47:57 +02:00
commit 14fdafaede
9 changed files with 398 additions and 49 deletions

View File

@ -28,6 +28,7 @@ namespace OC\Core;
use OC\AppFramework\Utility\SimpleContainer;
use OC\AppFramework\Utility\TimeFactory;
use OC\Core\Controller\LoginController;
use \OCP\AppFramework\App;
use OC\Core\Controller\LostController;
use OC\Core\Controller\UserController;
@ -89,6 +90,16 @@ class Application extends App {
$c->query('Logger')
);
});
$container->registerService('LoginController', function(SimpleContainer $c) {
return new LoginController(
$c->query('AppName'),
$c->query('Request'),
$c->query('UserManager'),
$c->query('Config'),
$c->query('Session'),
$c->query('UserSession')
);
});
/**
* Core class wrappers
@ -114,6 +125,9 @@ class Application extends App {
$container->registerService('AvatarManager', function(SimpleContainer $c) {
return $c->query('ServerContainer')->getAvatarManager();
});
$container->registerService('Session', function(SimpleContainer $c) {
return $c->query('ServerContainer')->getSession();
});
$container->registerService('UserSession', function(SimpleContainer $c) {
return $c->query('ServerContainer')->getUserSession();
});

View File

@ -0,0 +1,138 @@
<?php
/**
* @author Lukas Reschke <lukas@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Controller;
use OC\Setup;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
class LoginController extends Controller {
/** @var IUserManager */
private $userManager;
/** @var IConfig */
private $config;
/** @var ISession */
private $session;
/** @var IUserSession */
private $userSession;
/**
* @param string $appName
* @param IRequest $request
* @param IUserManager $userManager
* @param IConfig $config
* @param ISession $session
* @param IUserSession $userSession
*/
function __construct($appName,
IRequest $request,
IUserManager $userManager,
IConfig $config,
ISession $session,
IUserSession $userSession) {
parent::__construct($appName, $request);
$this->userManager = $userManager;
$this->config = $config;
$this->session = $session;
$this->userSession = $userSession;
}
/**
* @PublicPage
* @NoCSRFRequired
* @UseSession
*
* @param string $user
* @param string $redirect_url
* @param string $remember_login
*
* @return TemplateResponse
*/
public function showLoginForm($user,
$redirect_url,
$remember_login) {
if($this->userSession->isLoggedIn()) {
return new RedirectResponse(\OC_Util::getDefaultPageUrl());
}
$parameters = array();
$loginMessages = $this->session->get('loginMessages');
$errors = [];
$messages = [];
if(is_array($loginMessages)) {
list($errors, $messages) = $loginMessages;
}
$this->session->remove('loginMessages');
foreach ($errors as $value) {
$parameters[$value] = true;
}
$parameters['messages'] = $messages;
if (!is_null($user) && $user !== '') {
$parameters['loginName'] = $user;
$parameters['user_autofocus'] = false;
} else {
$parameters['loginName'] = '';
$parameters['user_autofocus'] = true;
}
if (!empty($redirect_url)) {
$parameters['redirect_url'] = $redirect_url;
}
$parameters['canResetPassword'] = true;
if (!$this->config->getSystemValue('lost_password_link')) {
if (!is_null($user) && $user !== '') {
$userObj = $this->userManager->get($user);
if ($userObj instanceof IUser) {
$parameters['canResetPassword'] = $userObj->canChangePassword();
}
}
}
$parameters['alt_login'] = \OC_App::getAlternativeLogIns();
$parameters['rememberLoginAllowed'] = \OC_Util::rememberLoginAllowed();
$parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0;
if (!is_null($user) && $user !== '') {
$parameters['loginName'] = $user;
$parameters['user_autofocus'] = false;
} else {
$parameters['loginName'] = '';
$parameters['user_autofocus'] = true;
}
return new TemplateResponse(
$this->appName,
'login',
$parameters,
'guest'
);
}
}

View File

@ -42,6 +42,7 @@ $application->registerRoutes($this, [
['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
]
]);

View File

@ -9,7 +9,7 @@ script('core', [
?>
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]-->
<form method="post" name="login">
<form method="post" name="login" action="<?php p(OC::$WEBROOT) ?>/">
<fieldset>
<?php if (!empty($_['redirect_url'])) {
print_unescaped('<input type="hidden" name="redirect_url" value="' . \OCP\Util::sanitizeHTML($_['redirect_url']) . '">');
@ -41,7 +41,7 @@ script('core', [
<p class="grouptop">
<input type="text" name="user" id="user"
placeholder="<?php p($l->t('Username')); ?>"
value="<?php p($_['username']); ?>"
value="<?php p($_['loginName']); ?>"
<?php p($_['user_autofocus'] ? 'autofocus' : ''); ?>
autocomplete="on" autocapitalize="off" autocorrect="off" required>
<label for="user" class="infield"><?php p($l->t('Username')); ?></label>

View File

@ -951,7 +951,18 @@ class OC {
$error[] = 'internalexception';
}
OC_Util::displayLoginPage(array_unique($error), $messages);
if(!\OC::$server->getUserSession()->isLoggedIn()) {
$loginMessages = array(array_unique($error), $messages);
\OC::$server->getSession()->set('loginMessages', $loginMessages);
// Read current user and append if possible
$args = [];
if(isset($_POST['user'])) {
$args['user'] = $_POST['user'];
}
$redirectionTarget = \OC::$server->getURLGenerator()->linkToRoute('core.login.showLoginForm', $args);
header('Location: ' . $redirectionTarget);
}
}
/**

View File

@ -192,9 +192,12 @@ class SecurityMiddleware extends Middleware {
);
} else {
if($exception instanceof NotLoggedInException) {
// TODO: replace with link to route
$url = $this->urlGenerator->getAbsoluteURL('index.php');
$url .= '?redirect_url=' . urlencode($this->request->server['REQUEST_URI']);
$url = $this->urlGenerator->linkToRoute(
'core.login.showLoginForm',
[
'redirect_url' => urlencode($this->request->server['REQUEST_URI']),
]
);
$response = new RedirectResponse($url);
} else {
$response = new TemplateResponse('core', '403', ['file' => $exception->getMessage()], 'guest');

View File

@ -946,44 +946,6 @@ class OC_Util {
return $errors;
}
/**
* @param array $errors
* @param string[] $messages
*/
public static function displayLoginPage($errors = array(), $messages = []) {
$parameters = array();
foreach ($errors as $value) {
$parameters[$value] = true;
}
$parameters['messages'] = $messages;
if (!empty($_REQUEST['user'])) {
$parameters["username"] = $_REQUEST['user'];
$parameters['user_autofocus'] = false;
} else {
$parameters["username"] = '';
$parameters['user_autofocus'] = true;
}
if (isset($_REQUEST['redirect_url'])) {
$parameters['redirect_url'] = $_REQUEST['redirect_url'];
}
$parameters['canResetPassword'] = true;
if (!\OC::$server->getSystemConfig()->getValue('lost_password_link')) {
if (isset($_REQUEST['user'])) {
$user = \OC::$server->getUserManager()->get($_REQUEST['user']);
if ($user instanceof IUser) {
$parameters['canResetPassword'] = $user->canChangePassword();
}
}
}
$parameters['alt_login'] = OC_App::getAlternativeLogIns();
$parameters['rememberLoginAllowed'] = self::rememberLoginAllowed();
$parameters['rememberLoginState'] = isset($_POST['remember_login']) ? $_POST['remember_login'] : 0;
\OC_Hook::emit('OC_Util', 'pre_displayLoginPage', array('parameters' => $parameters));
OC_Template::printGuestPage("", "login", $parameters);
}
/**
* Check if the user is logged in, redirects to home if not. With
* redirect URL parameter to the request URI.
@ -993,7 +955,8 @@ class OC_Util {
public static function checkLoggedIn() {
// Check if we are a user
if (!OC_User::isLoggedIn()) {
header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php',
header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute(
'core.login.showLoginForm',
[
'redirect_url' => \OC::$server->getRequest()->getRequestUri()
]

View File

@ -0,0 +1,214 @@
<?php
/**
* @author Lukas Reschke <lukas@owncloud.com>
*
* @copyright Copyright (c) 2016, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Controller;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IConfig;
use OCP\IRequest;
use OCP\ISession;
use OCP\IUserManager;
use OCP\IUserSession;
use Test\TestCase;
class LoginControllerTest extends TestCase {
/** @var LoginController */
private $loginController;
/** @var IRequest */
private $request;
/** @var IUserManager */
private $userManager;
/** @var IConfig */
private $config;
/** @var ISession */
private $session;
/** @var IUserSession */
private $userSession;
public function setUp() {
parent::setUp();
$this->request = $this->getMock('\\OCP\\IRequest');
$this->userManager = $this->getMock('\\OCP\\IUserManager');
$this->config = $this->getMock('\\OCP\\IConfig');
$this->session = $this->getMock('\\OCP\\ISession');
$this->userSession = $this->getMock('\\OCP\\IUserSession');
$this->loginController = new LoginController(
'core',
$this->request,
$this->userManager,
$this->config,
$this->session,
$this->userSession
);
}
public function testShowLoginFormForLoggedInUsers() {
$this->userSession
->expects($this->once())
->method('isLoggedIn')
->willReturn(true);
$expectedResponse = new RedirectResponse(\OC_Util::getDefaultPageUrl());
$this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', ''));
}
public function testShowLoginFormWithErrorsInSession() {
$this->userSession
->expects($this->once())
->method('isLoggedIn')
->willReturn(false);
$this->session
->expects($this->once())
->method('get')
->with('loginMessages')
->willReturn(
[
[
'ErrorArray1',
'ErrorArray2',
],
[
'MessageArray1',
'MessageArray2',
],
]
);
$expectedResponse = new TemplateResponse(
'core',
'login',
[
'ErrorArray1' => true,
'ErrorArray2' => true,
'messages' => [
'MessageArray1',
'MessageArray2',
],
'loginName' => '',
'user_autofocus' => true,
'canResetPassword' => true,
'alt_login' => [],
'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(),
'rememberLoginState' => 0,
],
'guest'
);
$this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', ''));
}
/**
* @return array
*/
public function passwordResetDataProvider() {
return [
[
true,
true,
],
[
false,
false,
],
];
}
/**
* @dataProvider passwordResetDataProvider
*/
public function testShowLoginFormWithPasswordResetOption($canChangePassword,
$expectedResult) {
$this->userSession
->expects($this->once())
->method('isLoggedIn')
->willReturn(false);
$this->config
->expects($this->once())
->method('getSystemValue')
->with('lost_password_link')
->willReturn(false);
$user = $this->getMock('\\OCP\\IUser');
$user
->expects($this->once())
->method('canChangePassword')
->willReturn($canChangePassword);
$this->userManager
->expects($this->once())
->method('get')
->with('LdapUser')
->willReturn($user);
$expectedResponse = new TemplateResponse(
'core',
'login',
[
'messages' => [],
'loginName' => 'LdapUser',
'user_autofocus' => false,
'canResetPassword' => $expectedResult,
'alt_login' => [],
'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(),
'rememberLoginState' => 0,
],
'guest'
);
$this->assertEquals($expectedResponse, $this->loginController->showLoginForm('LdapUser', '', ''));
}
public function testShowLoginFormForUserNamedNull() {
$this->userSession
->expects($this->once())
->method('isLoggedIn')
->willReturn(false);
$this->config
->expects($this->once())
->method('getSystemValue')
->with('lost_password_link')
->willReturn(false);
$user = $this->getMock('\\OCP\\IUser');
$user
->expects($this->once())
->method('canChangePassword')
->willReturn(false);
$this->userManager
->expects($this->once())
->method('get')
->with('0')
->willReturn($user);
$expectedResponse = new TemplateResponse(
'core',
'login',
[
'messages' => [],
'loginName' => '0',
'user_autofocus' => false,
'canResetPassword' => false,
'alt_login' => [],
'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(),
'rememberLoginState' => 0,
],
'guest'
);
$this->assertEquals($expectedResponse, $this->loginController->showLoginForm('0', '', ''));
}
}

View File

@ -343,9 +343,14 @@ class SecurityMiddlewareTest extends \Test\TestCase {
$this->middleware = $this->getMiddleware(false, false);
$this->urlGenerator
->expects($this->once())
->method('getAbsoluteURL')
->with('index.php')
->will($this->returnValue('http://localhost/index.php'));
->method('linkToRoute')
->with(
'core.login.showLoginForm',
[
'redirect_url' => 'owncloud%2Findex.php%2Fapps%2Fspecialapp',
]
)
->will($this->returnValue('http://localhost/index.php/login?redirect_url=owncloud%2Findex.php%2Fapps%2Fspecialapp'));
$this->logger
->expects($this->once())
->method('debug')
@ -356,7 +361,7 @@ class SecurityMiddlewareTest extends \Test\TestCase {
new NotLoggedInException()
);
$expected = new RedirectResponse('http://localhost/index.php?redirect_url=owncloud%2Findex.php%2Fapps%2Fspecialapp');
$expected = new RedirectResponse('http://localhost/index.php/login?redirect_url=owncloud%2Findex.php%2Fapps%2Fspecialapp');
$this->assertEquals($expected , $response);
}