add /login/authenticate/

remove  login/authenticate controller

add generateEmail function

move parent::tearDownAfterClass at the end od the function

use twitter bootstrap alert component

Update doc blocks & fix issues

add XMLHTTPRequest to PhraseanetPHPUNIt framework

fix tests

remove var_dump

refactor postlog process

fix URI's

fix redirection URI
This commit is contained in:
Nicolas Le Goff
2012-08-02 12:14:41 +02:00
parent 0ecdf87260
commit 367cf7c2a4
18 changed files with 377 additions and 304 deletions

View File

@@ -57,7 +57,6 @@ return call_user_func(function() {
$app->mount('/feeds/', new RSSFeeds());
$app->mount('/account/', new Account());
$app->mount('/login/authenticate/', new AuthenticateController());
$app->mount('/login/', new Login());
$app->mount('/developers/', new Developers());

View File

@@ -1,113 +0,0 @@
<?php
namespace Alchemy\Phrasea\Controller\Login;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
class Authenticate implements ControllerProviderInterface
{
public function connect(Application $app)
{
$controllers = $app['controllers_factory'];
$controllers->post('/', __CLASS__ . '::authenticate')
->before(function() use ($app) {
return $app['phraseanet.core']['Firewall']->requireNotAuthenticated($app);
});
return $controllers;
}
public function authenticate(Application $app, Request $request)
{
/* @var $Core \Alchemy\Phrasea\Core */
$Core = $app['phraseanet.core'];
$appbox = \appbox::get_instance($Core);
$session = $appbox->get_session();
$registry = $appbox->get_registry();
if ($registry->get('GV_captchas')
&& trim($registry->get('GV_captcha_private_key')) !== ''
&& trim($registry->get('GV_captcha_public_key')) !== '')
include($registry->get('GV_RootPath') . 'lib/vendor/recaptcha/recaptchalib.php');
$is_guest = false;
if (null !== $request->get('nolog') && \phrasea::guest_allowed()) {
$is_guest = true;
}
if ((null !== $request->get('login') && null !== $request->get('pwd')) || $is_guest) {
/**
* @todo dispatch an event that can be used to tweak the authentication
* (LDAP....)
*/
// $app['dispatcher']->dispatch();
try {
if ($is_guest) {
$auth = new \Session_Authentication_Guest($appbox);
} else {
$captcha = false;
if ($registry->get('GV_captchas')
&& trim($registry->get('GV_captcha_private_key')) !== ''
&& trim($registry->get('GV_captcha_public_key')) !== ''
&& ! is_null($request->get("recaptcha_challenge_field")
&& ! is_null($request->get("recaptcha_response_field")))) {
$checkCaptcha = recaptcha_check_answer($registry->get('GV_captcha_private_key'), $_SERVER["REMOTE_ADDR"], $request->get("recaptcha_challenge_field"), $request->get("recaptcha_response_field"));
if ($checkCaptcha->is_valid) {
$captcha = true;
}
}
$auth = new \Session_Authentication_Native($appbox, $request->get('login'), $request->get('pwd'));
$auth->set_captcha_challenge($captcha);
}
$session->authenticate($auth);
} catch (\Exception_Session_StorageClosed $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=session");
} catch (\Exception_Session_RequireCaptcha $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=captcha");
} catch (\Exception_Unauthorized $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=auth");
} catch (\Exception_Session_MailLocked $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=mail-not-confirmed&usr=" . $e->get_usr_id());
} catch (\Exception_Session_WrongToken $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=token");
} catch (\Exception_InternalServerError $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=session");
} catch (\Exception_ServiceUnavailable $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=maintenance");
} catch (\Exception_Session_BadSalinity $e) {
$date = new \DateTime('5 minutes');
$usr_id = \User_Adapter::get_usr_id_from_login($request->get('login'));
$url = \random::getUrlToken(\random::TYPE_PASSWORD, $usr_id, $date);
$url = '/account/forgot-password/?token=' . $url . '&salt=1';
return $app->redirect($url);
} catch (\Exception $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=" . _('An error occured'));
}
if ($app['browser']->isMobile()) {
return $app->redirect("/lightbox/");
} elseif ($request->get('redirect')) {
return $app->redirect($request->get('redirect'));
} elseif (true !== $app['browser']->isNewGeneration()) {
return $app->redirect('/client/');
} else {
return $app->redirect('/prod/');
}
} else {
return $app->redirect("/login/");
}
}
}

View File

@@ -13,7 +13,9 @@ namespace Alchemy\Phrasea\Controller\Root;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
/**
@@ -45,7 +47,8 @@ class Account implements ControllerProviderInterface
*
* return : HTML Response
*/
$controllers->get('/', $this->call('displayAccount'))->bind('account');
$controllers->get('/', $this->call('displayAccount'))
->bind('account');
/**
* Update account route
@@ -152,7 +155,8 @@ class Account implements ControllerProviderInterface
*
* return : HTML Response
*/
$controllers->get('/access/', $this->call('accountAccess'))->bind('account_access');
$controllers->get('/access/', $this->call('accountAccess'))
->bind('account_access');
/**
* Give authorized applications that can access user informations
@@ -167,7 +171,8 @@ class Account implements ControllerProviderInterface
*
* return : HTML Response
*/
$controllers->post('/reset-email/', $this->call('resetEmail'))->bind('reset_email');
$controllers->post('/reset-email/', $this->call('resetEmail'))
->bind('reset_email');
/**
* Grant access to an authorized app
@@ -182,7 +187,8 @@ class Account implements ControllerProviderInterface
*
* return : HTML Response
*/
$controllers->get('/reset-password/', $this->call('resetPassword'))->bind('reset_password');
$controllers->get('/reset-password/', $this->call('resetPassword'))
->bind('reset_password');
/**
* Give account open sessions
@@ -239,9 +245,9 @@ class Account implements ControllerProviderInterface
/**
* Reset Password
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app
* @param Request $request
* @return Response
*/
public function resetPassword(Application $app, Request $request)
{
@@ -267,9 +273,9 @@ class Account implements ControllerProviderInterface
/**
* Reset Email
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\JsonResponse
* @param Application $app
* @param Request $request
* @return RedirectResponse
*/
public function resetEmail(Application $app, Request $request)
{
@@ -326,9 +332,9 @@ class Account implements ControllerProviderInterface
/**
* Display reset email form
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\JsonResponse
* @param Application $app
* @param Request $request
* @return Response
*/
public function displayResetEmailForm(Application $app, Request $request)
{
@@ -374,7 +380,7 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return Response
* @return RedirectResponse
*/
public function renewPassword(Application $app, Request $request)
{
@@ -412,8 +418,7 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
* @return JsonResponse
*/
public function grantAccess(Application $app, Request $request, $application_id)
{
@@ -444,7 +449,6 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function accountAccess(Application $app, Request $request)
@@ -461,7 +465,6 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function accountAuthorizedApps(Application $app, Request $request)
@@ -476,7 +479,6 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function accountSessionsAccess(Application $app, Request $request)
@@ -489,7 +491,6 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function displayAccount(Application $app, Request $request)
@@ -530,7 +531,6 @@ class Account implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function updateAccount(Application $app, Request $request)
@@ -550,7 +550,7 @@ class Account implements ControllerProviderInterface
$register->add_request($user, \collection::get_from_base_id($baseId));
$notice = 'demand-ok';
} catch (\Exception $e) {
exit($e->getMessage());
}
}
}
@@ -630,7 +630,7 @@ class Account implements ControllerProviderInterface
$notifId = $notification['id'];
$notifName = sprintf('notification_%d', $notifId);
if (in_array($notifId, $requestedNotifications)) {
if (isset($requestedNotifications[$notifId])) {
$user->setPrefs($notifName, '1');
} else {
$user->setPrefs($notifName, '0');

View File

@@ -13,7 +13,9 @@ namespace Alchemy\Phrasea\Controller\Root;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
/**
@@ -178,8 +180,7 @@ class Developers implements ControllerProviderInterface
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @param integer $id The application id
*
* @return Response
* @return JsonResponse
*/
public function deleteApp(Application $app, Request $request, $id)
{
@@ -205,8 +206,7 @@ class Developers implements ControllerProviderInterface
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @param integer $id The application id
*
* @return Response
* @return JsonResponse
*/
public function renewAppCallback(Application $app, Request $request, $id)
{
@@ -237,8 +237,7 @@ class Developers implements ControllerProviderInterface
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @param integer $id The application id
*
* @return Response
* @return JsonResponse
*/
public function renewAccessToken(Application $app, Request $request, $id)
{
@@ -276,8 +275,7 @@ class Developers implements ControllerProviderInterface
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @param integer $id The application id
*
* @return Response
* @return JsonResponse
*/
public function authorizeGrantpassword(Application $app, Request $request, $id)
{
@@ -302,12 +300,11 @@ class Developers implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function newApp(Application $app, Request $request)
{
if ($request->get('type') == "desktop") {
if ($request->get('type') === \API_OAuth2_Application::DESKTOP_TYPE) {
$form = new \API_OAuth2_Form_DevAppDesktop($app['request']);
} else {
$form = new \API_OAuth2_Form_DevAppInternet($app['request']);
@@ -339,7 +336,6 @@ class Developers implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function listApps(Application $app, Request $request)
@@ -355,7 +351,6 @@ class Developers implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
*
* @return Response
*/
public function displayFormApp(Application $app, Request $request)
@@ -373,7 +368,6 @@ class Developers implements ControllerProviderInterface
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @param integer $id The application id
*
* @return Response
*/
public function getApp(Application $app, Request $request, $id)

View File

@@ -15,6 +15,7 @@ use Alchemy\Phrasea\Core;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
/**
@@ -44,18 +45,47 @@ class Login implements ControllerProviderInterface
*/
$controllers->get('/', $this->call('login'))
->before(function() use ($app) {
//
// if ( ! $app['phraseanet.appbox']->get_session()->isset_postlog()
// && $app['phraseanet.core']->isAuthenticated()
// && $app['request']->get('error') != 'no-connection') {
//
// return $app->redirect($app['request']->get('redirect', '/prod/'));
// }
return $app['phraseanet.core']['Firewall']->requireNotAuthenticated($app);
if (null !== $app['request']->get('postlog')) {
// if isset postlog parameter, set cookie and log out current user
// then post login operation like getting baskets from an invit session
// could be done by Session_handler authentication process
$app['phraseanet.appbox']->get_session()->set_postlog();
return $app->redirect("/login/logout/?redirect=" . $app['request']->get('redirect', 'prod'));
}
if ($app['phraseanet.core']->isAuthenticated()) {
return $app->redirect('/' . $app['request']->get('redirect', 'prod') . '/');
}
})
->bind('homepage');
/**
* Authenticate
*
* name : login_authenticate
*
* description : authenticate to phraseanet
*
* method : POST
*
* parameters : none
*
* return : HTML Response
*/
$controllers->post('/authenticate/', $this->call('authenticate'))
->before(function() use ($app) {
if ($app['phraseanet.core']->isAuthenticated()) {
return $app->redirect('/prod/');
}
})
->bind('login_authenticate');
/**
* Logout
*
@@ -174,9 +204,9 @@ class Login implements ControllerProviderInterface
/**
* Send a confirmation mail after register
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return RedirectResponse
*/
public function sendConfirmMail(Application $app, Request $request)
{
@@ -201,9 +231,9 @@ class Login implements ControllerProviderInterface
/**
* Validation of email adress
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return RedirectResponse
*/
public function registerConfirm(Application $app, Request $request)
{
@@ -264,7 +294,7 @@ class Login implements ControllerProviderInterface
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return Response
* @return RedirectResponse
*/
public function renewPassword(Application $app, Request $request)
{
@@ -398,9 +428,9 @@ class Login implements ControllerProviderInterface
/**
* Get the register form
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return Response
*/
public function displayRegisterForm(Application $app, Request $request)
{
@@ -458,9 +488,9 @@ class Login implements ControllerProviderInterface
/**
* Get the register form
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return RedirectResponse
*/
public function register(Application $app, Request $request)
{
@@ -617,9 +647,9 @@ class Login implements ControllerProviderInterface
/**
* Logout from Phraseanet
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return RedirectResponse
*/
public function logout(Application $app, Request $request)
{
@@ -640,27 +670,20 @@ class Login implements ControllerProviderInterface
/**
* Login into Phraseanet
*
* @param \Silex\Application $app
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\Response
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return Response
*/
public function login(Application $app, Request $request)
{
$appbox = $app['phraseanet.appbox'];
$session = $appbox->get_session();
$registry = $appbox->get_registry();
$registry = $app['phraseanet.core']['Registry'];
require_once($registry->get('GV_RootPath') . 'lib/classes/deprecated/inscript.api.php');
if ($registry->get('GV_captchas') && trim($registry->get('GV_captcha_private_key')) !== '' && trim($registry->get('GV_captcha_public_key')) !== '') {
include($registry->get('GV_RootPath') . 'lib/vendor/recaptcha/recaptchalib.php');
}
if ($request->get('postlog')) {
$session->set_postlog(true);
return $app->redirect("/login/?redirect=" . $request->get('redirect'));
}
$warning = $request->get('error', '');
try {
@@ -758,6 +781,97 @@ class Login implements ControllerProviderInterface
));
}
/**
* Authenticate to phraseanet
*
* @param Application $app A Silex application where the controller is mounted on
* @param Request $request The current request
* @return RedirectResponse
*/
public function authenticate(Application $app, Request $request)
{
$appbox = $app['phraseanet.appbox'];
$session = $appbox->get_session();
$registry = $app['phraseanet.core']['Registry'];
$is_guest = false;
if (null !== $request->get('nolog') && \phrasea::guest_allowed()) {
$is_guest = true;
}
if (((null !== $login = $request->get('login')) && (null !== $pwd = $request->get('pwd'))) || $is_guest) {
/**
* @todo dispatch an event that can be used to tweak the authentication
* (LDAP....)
*/
// $app['dispatcher']->dispatch();
try {
if ($is_guest) {
$auth = new \Session_Authentication_Guest($appbox);
} else {
$captcha = false;
if ($registry->get('GV_captchas')
&& '' !== $privateKey = trim($registry->get('GV_captcha_private_key'))
&& trim($registry->get('GV_captcha_public_key')) !== ''
&& null !== $challenge = $request->get("recaptcha_challenge_field")
&& null !== $captachResponse = $request->get("recaptcha_response_field")) {
include($registry->get('GV_RootPath') . 'lib/vendor/recaptcha/recaptchalib.php');
$checkCaptcha = recaptcha_check_answer($privateKey, $_SERVER["REMOTE_ADDR"], $challenge, $captachResponse);
if ($checkCaptcha->is_valid) {
$captcha = true;
}
}
$auth = new \Session_Authentication_Native($appbox, $login, $pwd);
$auth->set_captcha_challenge($captcha);
}
$session->authenticate($auth);
} catch (\Exception_Session_StorageClosed $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=session");
} catch (\Exception_Session_RequireCaptcha $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=captcha");
} catch (\Exception_Unauthorized $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=auth");
} catch (\Exception_Session_MailLocked $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=mail-not-confirmed&usr=" . $e->get_usr_id());
} catch (\Exception_Session_WrongToken $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=token");
} catch (\Exception_InternalServerError $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=session");
} catch (\Exception_ServiceUnavailable $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=maintenance");
} catch (\Exception_Session_BadSalinity $e) {
$date = new \DateTime('5 minutes');
$usr_id = \User_Adapter::get_usr_id_from_login($request->get('login'));
$url = '/account/forgot-password/?token=' . \random::getUrlToken(\random::TYPE_PASSWORD, $usr_id, $date) . '&salt=1';
return $app->redirect($url);
} catch (\Exception $e) {
return $app->redirect("/login/?redirect=" . $request->get('redirect') . "&error=" . _('An error occured'));
}
if ($app['browser']->isMobile()) {
return $app->redirect("/lightbox/");
} elseif ($request->get('redirect')) {
return $app->redirect($request->get('redirect'));
} elseif (true !== $app['browser']->isNewGeneration()) {
return $app->redirect('/client/');
} else {
return $app->redirect('/prod/');
}
} else {
return $app->redirect("/login/");
}
}
/**
* Prefix the method to call with the controller class name
*
@@ -772,7 +886,7 @@ class Login implements ControllerProviderInterface
/**
* Get required fields configuration
*
* @param \Alchemy\Phrasea\Core $core
* @param Core $core
* @return boolean
*/
private function getRegisterFieldConfiguration(Core $core)
@@ -799,14 +913,13 @@ class Login implements ControllerProviderInterface
"demand" => true
);
//on va chercher le fichier de configuration
$registerFieldConfigurationFile = $core['Registry']->get('GV_RootPath') . 'config/register-fields.php';
if (is_file($registerFieldConfigurationFile)) {
include $registerFieldConfigurationFile;
}
//on force les champs vraiment obligatoires si le mec a fumé en faisant sa conf
//Override mandatory fields
$arrayVerif['form_login'] = true;
$arrayVerif['form_password'] = true;
$arrayVerif['form_password_confirm'] = true;

View File

@@ -180,7 +180,7 @@ class Manage extends Helper
$registry = \bootstrap::getCore()->getRegistry();
if (false !== $urlToken) {
$url = sprintf('%slogin/forgotpwd.php?token=%s', $registry->get('GV_ServerName'), $urlToken);
$url = sprintf('%slogin/forgot-password/?token=%s', $registry->get('GV_ServerName'), $urlToken);
\mail::send_credentials($url, $createdUser->get_login(), $createdUser->get_email());
}
}

View File

@@ -34,11 +34,4 @@ class Firewall
return $app->redirect('/login/logout/');
}
}
public function requireNotAuthenticated(Application $app)
{
if ($app['phraseanet.core']->isAuthenticated()) {
return $app->redirect('/prod/');
}
}
}

View File

@@ -246,7 +246,7 @@ class eventsmanager_notify_autoregister extends eventsmanager_notifyAbstract
$body .= "</ul>\n";
$body .= "<br/>\n<div><a href='/login/?redirect=/admin' target='_blank'>"
$body .= "<br/>\n<div><a href='/login/?redirect=admin' target='_blank'>"
. _('admin::register: vous pourrez consulter son compte en ligne via l\'interface d\'administration')
. "</a></div>\n";

View File

@@ -250,7 +250,7 @@ class eventsmanager_notify_register extends eventsmanager_notifyAbstract
$body .= "</ul>\n";
$body .= "<br/>\n<div><a href='" . $this->registry->get('GV_ServerName')
. "login/admin' target='_blank'>"
. "login/?redirect=admin' target='_blank'>"
. _('admin::register: vous pourrez traiter ses demandes en ligne via l\'interface d\'administration')
. "</a></div>\n";

View File

@@ -48,8 +48,10 @@ $(document).ready(function() {
{% block content %}
{% if updateMsg is not none %}
<div class='update-msg' style="margin-top:100px;">{{ updateMsg }}</div>
<div class="alert alert-info">
<div>{{ updateMsg }}</div>
<a href="/account/" target="_self">{% trans 'admin::compte-utilisateur retour a mon compte'%}</a>
</div>
{% else %}
{% if noticeMsg is not none %}

View File

@@ -56,7 +56,10 @@
{% block content %}
<form method="POST" action="/account/reset-password/" id="mainform" class="form-horizontal">
{% if passwordMsg is not none %}
<p class="password-msg form_alert help-block">{{ passwordMsg }}</p>
<div class="alert alert-error">
<a class="close" data-dismiss="alert" href="#">×</a>
{{ passwordMsg }}
</div>
{% endif %}
<div class="control-group">
<label class="form_label control-label" for="form_login">{% trans 'admin::compte-utilisateur identifiant' %}</label>

View File

@@ -124,7 +124,10 @@
{% if not tokenize %}
<form name="send" action="/login/forgot-password/" method="POST" style="width: 600px; margin: 0 auto;">
{% if errorMsg is not none %}
<div class='error-msg' style="background:#00a8FF;">{{ errorMsg }}</div>
<div class="alert alert-error">
<a class="close" data-dismiss="alert" href="#">×</a>
{{ errorMsg }}
</div>
{% endif %}
{% if sentMsg is not none %}

View File

@@ -19,11 +19,11 @@ class AccountTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
public static function tearDownAfterClass()
{
parent::tearDownAfterClass();
if (self::$authorizedApp) {
self::$authorizedApp->delete();
}
parent::tearDownAfterClass();
}
public function setUp()
@@ -246,7 +246,7 @@ class AccountTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertTrue($this->client->getResponse()->isOk());
$this->assertEquals(1, $crawler->filter('.update-msg')->count());
$this->assertEquals(1, $crawler->filter('.alert-info')->count());
}
public function updateMsgProvider()
@@ -307,7 +307,7 @@ class AccountTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertTrue($response->isOk());
$this->assertEquals(1, $crawler->filter('.password-msg')->count());
$this->assertEquals(1, $crawler->filter('.alert-error')->count());
}
public function passwordMsgProvider()

View File

@@ -127,10 +127,7 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testDeleteAppError()
{
$this->client->request('DELETE', '/developers/application/0/', array(), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest'
));
$this->XMLHTTPRequest('DELETE', '/developers/application/0/');
$this->assertTrue($this->client->getResponse()->isOk());
$content = json_decode($this->client->getResponse()->getContent());
@@ -144,11 +141,7 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
$oauthApp = \API_OAuth2_Application::create(\appbox::get_instance(\bootstrap::getCore()), self::$user, 'test app');
$this->client->request('DELETE', '/developers/application/' . $oauthApp->get_id() . '/', array(), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest'
)
);
$this->XMLHTTPRequest('DELETE', '/developers/application/' . $oauthApp->get_id() . '/');
$this->assertTrue($this->client->getResponse()->isOk());
@@ -174,11 +167,8 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testRenewAppCallbackError()
{
$this->client->request('POST', '/developers/application/0/callback/', array(
$this->XMLHTTPRequest('POST', '/developers/application/0/callback/', array(
'callback' => 'my.callback.com'
), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->assertTrue($this->client->getResponse()->isOk());
@@ -193,12 +183,7 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
$oauthApp = \API_OAuth2_Application::create(\appbox::get_instance(\bootstrap::getCore()), self::$user, 'test app');
$this->client->request('POST', '/developers/application/'.$oauthApp->get_id().'/callback/', array(
'callback' => null
), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->XMLHTTPRequest('POST', '/developers/application/'.$oauthApp->get_id().'/callback/');
$this->assertTrue($this->client->getResponse()->isOk());
$content = json_decode($this->client->getResponse()->getContent());
@@ -212,11 +197,8 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
$oauthApp = \API_OAuth2_Application::create(\appbox::get_instance(\bootstrap::getCore()), self::$user, 'test app');
$this->client->request('POST', '/developers/application/' . $oauthApp->get_id() . '/callback/', array(
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->get_id() . '/callback/', array(
'callback' => 'my.callback.com'
), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->assertTrue($this->client->getResponse()->isOk());
@@ -240,11 +222,8 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testRenewAccessTokenError()
{
$this->client->request('POST', '/developers/application/0/access_token/', array(
$this->XMLHTTPRequest('POST', '/developers/application/0/access_token/', array(
'callback' => 'my.callback.com'
), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->assertTrue($this->client->getResponse()->isOk());
@@ -260,10 +239,7 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
$oauthApp = \API_OAuth2_Application::create(\appbox::get_instance(\bootstrap::getCore()), self::$user, 'test app');
$this->client->request('POST', '/developers/application/' . $oauthApp->get_id() . '/access_token/', array(), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->get_id() . '/access_token/');
$this->assertTrue($this->client->getResponse()->isOk());
$content = json_decode($this->client->getResponse()->getContent());
@@ -285,11 +261,8 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testAuthorizeGrantpasswordError()
{
$this->client->request('POST', '/developers/application/0/authorize_grant_password/', array(
$this->XMLHTTPRequest('POST', '/developers/application/0/authorize_grant_password/', array(
'callback' => 'my.callback.com'
), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->assertTrue($this->client->getResponse()->isOk());
@@ -304,11 +277,8 @@ class DevelopersTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
{
$oauthApp = \API_OAuth2_Application::create(\appbox::get_instance(\bootstrap::getCore()), self::$user, 'test app');
$this->client->request('POST', '/developers/application/' . $oauthApp->get_id() . '/authorize_grant_password/', array(
$this->XMLHTTPRequest('POST', '/developers/application/' . $oauthApp->get_id() . '/authorize_grant_password/', array(
'grant' => '1'
), array(), array(
'HTTP_ACCEPT' => 'application/json',
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
$this->assertTrue($this->client->getResponse()->isOk());

View File

@@ -43,7 +43,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->client->request('GET', '/login/', array('postlog' => '1', 'redirect' => 'prod'));
$response = $this->client->getResponse();
$this->assertTrue($response->isRedirect());
$this->assertEquals('/login/?redirect=prod', $response->headers->get('location'));
$this->assertEquals('/login/logout/?redirect=prod', $response->headers->get('location'));
}
/**
@@ -105,7 +105,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testRegisterConfirmMailUserNotFound()
{
$email = \random::generatePassword() . '_email@email.com';
$email = $this->generateEmail();
$token = \random::getUrlToken(\random::TYPE_EMAIL, 0, null, $email);
$this->client->request('GET', '/login/register-confirm/', array('code' => $token));
$response = $this->client->getResponse();
@@ -119,7 +119,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testRegisterConfirmMailUnlocked()
{
$email = \random::generatePassword() . '_email@email.com';
$email = $this->generateEmail();
$token = \random::getUrlToken(\random::TYPE_EMAIL, self::$user->get_id(), null, $email);
self::$user->set_mail_locked(false);
@@ -136,7 +136,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testRegisterConfirmMail()
{
$email = \random::generatePassword() . '_email@email.com';
$email = $this->generateEmail();
$appboxRegister = new \appbox_register($this->app['phraseanet.appbox']);
$token = \random::getUrlToken(\random::TYPE_EMAIL, self::$user->get_id(), null, $email);
@@ -156,7 +156,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
*/
public function testRegisterConfirmMailNoCollAwait()
{
$email = \random::generatePassword() . '_email@email.com';
$email = $this->generateEmail();
$token = \random::getUrlToken(\random::TYPE_EMAIL, self::$user->get_id(), null, $email);
self::$user->set_mail_locked(true);
@@ -290,7 +290,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
));
$this->assertTrue($this->client->getResponse()->isOk());
$this->assertEquals(1, $crawler->filter('.error-msg')->count());
$this->assertEquals(1, $crawler->filter('.alert-error')->count());
}
/**
@@ -305,7 +305,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$response = $this->client->getResponse();
$this->assertTrue($response->isOk());
$this->assertEquals(1, $crawler->filter('.error-msg')->count());
$this->assertEquals(1, $crawler->filter('.alert-error')->count());
}
public function errorMessageProvider()
@@ -357,7 +357,7 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
/**
* @todo change this
*/
if(\login::register_enabled()) {
if ( ! \login::register_enabled()) {
$this->assertTrue($this->client->getResponse()->isRedirect());
} else {
$this->assertTrue($this->client->getResponse()->isOk());
@@ -641,6 +641,81 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$this->assertEquals('/login/?error=user-not-found', $response->headers->get('location'));
}
/**
* @covers \Alchemy\Phrasea\Controller\Root\Login::authenticate
*/
public function testAuthenticate()
{
$this->app['phraseanet.appbox']->get_session()->logout();
$password = \random::generatePassword();
self::$user->set_password($password);
$this->client->request('POST', '/login/authenticate/', array(
'login' => self::$user->get_login(),
'pwd' => $password
));
$this->assertTrue($this->client->getResponse()->isRedirect());
$this->assertTrue($this->app['phraseanet.core']->isAuthenticated());
}
/**
* @covers \Alchemy\Phrasea\Controller\Root\Login::authenticate
*/
public function testBadAuthenticate()
{
$this->app['phraseanet.appbox']->get_session()->logout();
$this->client->request('POST', '/login/authenticate/', array(
'login' => self::$user->get_login(),
'pwd' => 'test'
));
$this->assertTrue($this->client->getResponse()->isRedirect());
$this->assertRegexp('/error=auth/', $this->client->getResponse()->headers->get('location'));
$this->assertFalse($this->app['phraseanet.core']->isAuthenticated());
}
/**
* @covers \Alchemy\Phrasea\Controller\Root\Login::authenticate
*/
public function testMailLockedAuthenticate()
{
$this->app['phraseanet.appbox']->get_session()->logout();
$password = \random::generatePassword();
self::$user->set_mail_locked(true);
$this->client->request('POST', '/login/authenticate/', array(
'login' => self::$user->get_login(),
'pwd' => $password
));
$this->assertTrue($this->client->getResponse()->isRedirect());
$this->assertRegexp('/error=mail-not-confirmed/', $this->client->getResponse()->headers->get('location'));
$this->assertFalse($this->app['phraseanet.core']->isAuthenticated());
self::$user->set_mail_locked(false);
}
/**
* @covers \Alchemy\Phrasea\Controller\Root\Login::authenticate
*/
public function testAuthenticateUnavailable()
{
$this->app['phraseanet.appbox']->get_session()->logout();
$password = \random::generatePassword();
$this->app['phraseanet.core']['Registry']->set('GV_maintenance', true , \registry::TYPE_BOOLEAN);
$this->client->request('POST', '/login/authenticate/', array(
'login' => self::$user->get_login(),
'pwd' => $password
));
$this->app['phraseanet.core']['Registry']->set('GV_maintenance', false, \registry::TYPE_BOOLEAN);
$this->assertTrue($this->client->getResponse()->isRedirect());
$this->assertRegexp('/error=maintenance/', $this->client->getResponse()->headers->get('location'));
$this->assertFalse($this->app['phraseanet.core']->isAuthenticated());
}
/**
* Delete inscription demand made by the current authenticathed user
* @return void
*/
private function deleteRequest()
{
$sql = "DELETE FROM demand WHERE usr_id = :usr_id";
@@ -648,4 +723,13 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$stmt->execute(array(':usr_id' => self::$user->get_id()));
$stmt->closeCursor();
}
/**
* Generate a new valid email adress
* @return string
*/
private function generateEmail()
{
return \random::generatePassword() . '_email@email.com';
}
}

View File

@@ -4,6 +4,8 @@ require_once __DIR__ . "/PhraseanetPHPUnitListener.class.inc";
use Silex\WebTestCase;
use Doctrine\Common\DataFixtures\Loader;
use Symfony\Component\HttpKernel\Client;
use Symfony\Component\DomCrawler\Crawler;
abstract class PhraseanetPHPUnitAbstract extends WebTestCase
{
@@ -485,6 +487,28 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
return;
}
/**
* Calls a URI as XMLHTTP request.
*
* @param string $method The request method
* @param string $uri The URI to fetch
* @param array $parameters The Request parameters
* @param array $httpAccept Contents of the Accept header
*
* @return Crawler
*/
protected function XMLHTTPRequest($method, $uri, array $parameters = array(), $httpAccept = 'application/json')
{
if ( ! $this->client instanceof Client) {
throw new \Exception('Not client seems intitialized');
}
return $this->client->request($method, $uri, $parameters, array(), array(
'HTTP_ACCEPT' => $httpAccept,
'HTTP_X-Requested-With' => 'XMLHttpRequest',
));
}
/**
* Update the sql tables with the current schema
* @return void
@@ -608,6 +632,7 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
foreach ($databox->get_collections() as $collection) {
$base_id = $collection->get_base_id();
$user->ACL()->give_access_to_base(array($base_id));
set_exportorder::set_order_admins(array($user->get_id()), $base_id);

View File

@@ -87,7 +87,7 @@ function login(what)
{
EcrireCookie('last_act',what,null,'/');
}
self.location.replace('/login/index.php?postlog=1');
self.location.replace('/login/?postlog=1');
}
return false;
}