Login chamilo using symfony login_check path #2322

pull/2487/head
jmontoyaa 8 years ago
parent ea398cc4c8
commit ec47aaf5ce
  1. 2
      main/inc/global.inc.php
  2. 4
      main/inc/global_error_message.inc.php
  3. 225
      main/inc/lib/chamilo_session.class.php
  4. 4
      main/inc/local.inc.php
  5. 2
      public/legacy.php
  6. 17
      src/CoreBundle/EventListener/LoginSuccessHandler.php
  7. 2
      src/CoreBundle/Framework/PageController.php
  8. 11
      src/CoreBundle/Resources/config/services.yml
  9. 5
      src/CoreBundle/Security/Authorization/Voter/CourseVoter.php
  10. 4
      src/CoreBundle/Security/Authorization/Voter/GroupVoter.php
  11. 5
      src/CoreBundle/Security/Authorization/Voter/ResourceNodeVoter.php
  12. 7
      src/CourseBundle/Resources/config/services.yml

@ -187,7 +187,7 @@ $charset = 'UTF-8';
\Patchwork\Utf8\Bootup::initAll(); \Patchwork\Utf8\Bootup::initAll();
// Start session after the internationalization library has been initialized. // Start session after the internationalization library has been initialized.
ChamiloSession::start($alreadyInstalled); //ChamiloSession::start($alreadyInstalled);
// access_url == 1 is the default chamilo location // access_url == 1 is the default chamilo location
if ($_configuration['access_url'] != 1) { if ($_configuration['access_url'] != 1) {

@ -59,8 +59,8 @@ if (is_int($global_error_code) && $global_error_code > 0) {
$installation_guide_url = $root_rel.'documentation/installation_guide.html'; $installation_guide_url = $root_rel.'documentation/installation_guide.html';
$css_path = 'app/Resources/public/css/'; $css_path = 'app/Resources/public/css/';
$css_web_assets = 'web/assets/'; $css_web_assets = 'public/assets/';
$css_web_path = 'web/css/'; $css_web_path = 'public/css/';
$themePath = $css_path.'themes/'.$theme.'/default.css'; $themePath = $css_path.'themes/'.$theme.'/default.css';
$bootstrap_file = $css_web_assets.'bootstrap/dist/css/bootstrap.min.css'; $bootstrap_file = $css_web_assets.'bootstrap/dist/css/bootstrap.min.css';
$css_base_file = $css_web_path.'base.css'; $css_base_file = $css_web_path.'base.css';

@ -1,144 +1,165 @@
<?php <?php
/* For licensing terms, see /license.txt */
use Symfony\Component\HttpFoundation\Session\Session; use Chamilo\CoreBundle\Framework\Container;
use Symfony\Component\HttpFoundation\Session\Storage\PhpBridgeSessionStorage;
/** /**
* Chamilo session (i.e. the session that maintains the connection open after usr login)
*
* Usage:
*
*
* use ChamiloSession as Session;
*
* Session::read('name');
*
* Or
*
* Chamilo::session()->...
* session()->...
*
* @license see /license.txt
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
*/
/**
* @todo use session symfony component
* @todo replace all $_SESSION calls with this class. * @todo replace all $_SESSION calls with this class.
* @todo remove System\Session class
* ChamiloSession class definition
*/ */
class ChamiloSession extends System\Session class ChamiloSession implements \ArrayAccess
{ {
const NAME = 'ch_sid';
/** /**
* Generate new session instance * @param string $variable
* @return ChamiloSession * @param null $default
* @return mixed|null
*/ */
public static function instance() public static function read($variable, $default = null)
{ {
static $result = null; $session = Container::getSession();
$result = null;
if (isset($session)) {
$result = $session->get($variable);
}
// Check if the value exists in the $_SESSION array
if (empty($result)) { if (empty($result)) {
$result = new ChamiloSession(); if (isset($_SESSION[$variable])) {
return $_SESSION[$variable];
}
return $default;
} else {
return $result;
} }
return $result;
} }
/** /**
* Returns the session lifetime * @param string $variable
* @return int The session lifetime as defined in the config file, in seconds * @param mixed $value
*/ */
public static function session_lifetime() public static function write($variable, $value)
{ {
global $_configuration; //$_SESSION[$variable] = $value;
return $_configuration['session_lifetime']; $session = Container::getSession();
// Writing the session in 2 instances because
$_SESSION[$variable] = $value;
$session->set($variable, $value);
} }
/** /**
* Starts the Chamilo session. * @param string $variable
*/
public static function erase($variable)
{
$variable = (string) $variable;
$session = Container::getSession();
$session->remove($variable);
if (isset($GLOBALS[$variable])) {
unset($GLOBALS[$variable]);
}
if (isset($_SESSION[$variable])) {
unset($_SESSION[$variable]);
}
}
/**
* Returns true if session has variable set up, false otherwise.
* *
* The default lifetime for session is set here. It is not possible to have it * @param string $variable
* as a database setting as it is used before the database connection has been made.
* It is taken from the configuration file, and if it doesn't exist there, it is set
* to 360000 seconds
* *
* @author Olivier Brouckaert * @return bool
* @param string variable - the variable name to save into the session
* @return void
*/ */
public static function start($already_installed = true) public static function has($variable)
{ {
/* return isset($_SESSION[$variable]);
* Prevent Session fixation bug fixes }
* See http://support.chamilo.org/issues/3600
* http://php.net/manual/en/session.configuration.php
* @todo use session_set_cookie_params with some custom admin parameters
*/
//session.cookie_lifetime
//the session ID is only accepted from a cookie
ini_set('session.use_only_cookies', 1);
//HTTPS only if possible
//ini_set('session.cookie_secure', 1);
//session ID in the cookie is only readable by the server
ini_set('session.cookie_httponly', 1);
//Use entropy file
//session.entropy_file
//ini_set('session.entropy_length', 128);
//Do not include the identifier in the URL, and not to read the URL for
// identifiers.
ini_set('session.use_trans_sid', 0);
session_name(self::NAME);
session_start();
$session = self::instance();
if ($already_installed) {
if (!isset($session['checkChamiloURL'])) {
$session['checkChamiloURL'] = api_get_path(WEB_PATH);
} elseif ($session['checkChamiloURL'] != api_get_path(WEB_PATH)) {
self::clear();
}
}
// If the session time has expired, refresh the starttime value, /**
// so we're starting to count down from a later time * Clear
if (self::has('starttime') && $session->is_expired()) { */
self::destroy(); public static function clear()
} else { {
//error_log('Time not expired, extend session for a bit more'); $session = Container::getSession();
self::write('starttime', time()); $session->clear();
}
} }
/** /**
* Session start time: that is the last time the user loaded a page (before this time) * Destroy
* @return int timestamp */
public static function destroy()
{
$session = Container::getSession();
$session->invalidate();
}
/*
* ArrayAccess
*/ */
public function start_time() public function offsetExists($offset)
{ {
return self::read('starttime'); return isset($_SESSION[$offset]);
} }
/** /**
* Session end time: when the session expires. This is made of the last page * It it exists returns the value stored at the specified offset.
* load time + a number of seconds * If offset does not exists returns null. Do not trigger a warning.
* @return int UNIX timestamp (server's timezone) *
* @param string $offset
* @return any
*/
public function offsetGet($offset)
{
return self::read($offset);
}
public function offsetSet($offset, $value)
{
self::write($offset, $value);
}
public function offsetUnset($offset)
{
unset($_SESSION[$offset]);
}
/**
* @param string $name
*/
public function __unset($name)
{
unset($_SESSION[$name]);
}
/**
* @param string $name
* @return bool
*/ */
public function end_time() public function __isset($name)
{ {
$start_time = $this->start_time(); return self::has($name);
$lifetime = self::session_lifetime();
return $start_time + $lifetime;
} }
/** /**
* Returns whether the session is expired * It it exists returns the value stored at the specified offset.
* @return bool True if the session is expired, false if it is still valid * If offset does not exists returns null. Do not trigger a warning.
*
* @param string $name
*
* @return mixed
*
*/
public function __get($name)
{
return self::read($name);
}
/**
*
* @param string $name
* @param mixed $value
*/ */
public function is_expired() public function __set($name, $value)
{ {
return $this->end_time() < time(); self::write($name, $value);
} }
} }

@ -136,8 +136,8 @@ if (isset($_SESSION['conditional_login']['uid']) && $_SESSION['conditional_login
} }
// parameters passed via GET // parameters passed via GET
$logout = isset($_GET["logout"]) ? $_GET["logout"] : ''; $logout = isset($_GET['logout']) ? $_GET['logout'] : '';
$gidReq = isset($_GET["gidReq"]) ? intval($_GET["gidReq"]) : ''; $gidReq = isset($_GET['gidReq']) ? (int) $_GET['gidReq'] : '';
// Keep a trace of the course and session from which we are getting out, to // Keep a trace of the course and session from which we are getting out, to
// enable proper course logout tracking in courseLogout() // enable proper course logout tracking in courseLogout()

@ -1,7 +1,7 @@
<?php <?php
/* For licensing terms, see /license.txt */ /* For licensing terms, see /license.txt */
define('USERNAME_MAX_LENGTH', 40); //define('USERNAME_MAX_LENGTH', 40);
require_once __DIR__.'/../main/inc/lib/api.lib.php'; require_once __DIR__.'/../main/inc/lib/api.lib.php';
require_once __DIR__.'/../main/inc/lib/array.lib.php'; require_once __DIR__.'/../main/inc/lib/array.lib.php';

@ -7,7 +7,7 @@ use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerI
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router; use ChamiloSession as Session;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Chamilo\UserBundle\Entity\User; use Chamilo\UserBundle\Entity\User;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker; use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
@ -76,10 +76,12 @@ class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
if ($this->checker->isGranted('ROLE_STUDENT') && !empty($pageAfterLogin)) { if ($this->checker->isGranted('ROLE_STUDENT') && !empty($pageAfterLogin)) {
switch ($pageAfterLogin) { switch ($pageAfterLogin) {
case 'index.php': case 'index.php':
$url = $this->router->generate('home'); //$url = $this->router->generate('home');
$url = $this->router->generate('home').'/../index.php';
break; break;
case 'user_portal.php': case 'user_portal.php':
$url = $this->router->generate('userportal'); //$url = $this->router->generate('userportal');
$url = $this->router->generate('home').'/../user_portal.php';
break; break;
case 'main/auth/courses.php': case 'main/auth/courses.php':
$url = api_get_path(WEB_PUBLIC_PATH).$pageAfterLogin; $url = api_get_path(WEB_PUBLIC_PATH).$pageAfterLogin;
@ -87,11 +89,15 @@ class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
} }
} }
$url = $this->router->generate('userportal'); Session::write('_uid', $user->getId());
Session::write('_user', $userInfo);
Session::write('is_platformAdmin', (bool) \UserManager::is_admin($userId));
Session::write('is_allowedCreateCourse', (bool) ($userInfo['status'] == 1));
//$url = $this->router->generate('userportal');
// Redirecting to a course or a session. // Redirecting to a course or a session.
if (api_get_setting('course.go_to_course_after_login') == 'true') { if (api_get_setting('course.go_to_course_after_login') == 'true') {
// Get the courses list // Get the courses list
$personal_course_list = \UserManager::get_personal_session_course_list($userId); $personal_course_list = \UserManager::get_personal_session_course_list($userId);
@ -109,7 +115,6 @@ class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
} }
$count_of_sessions = count($my_session_list); $count_of_sessions = count($my_session_list);
if ($count_of_sessions == 1 && $count_of_courses_no_sessions == 0) { if ($count_of_sessions == 1 && $count_of_courses_no_sessions == 0) {
$key = array_keys($personal_course_list); $key = array_keys($personal_course_list);
$course_info = $personal_course_list[$key[0]]['course_info']; $course_info = $personal_course_list[$key[0]]['course_info'];

@ -691,7 +691,7 @@ class PageController
$loadDirs = api_get_setting('document.show_documents_preview') == 'true' ? true : false; $loadDirs = api_get_setting('document.show_documents_preview') == 'true' ? true : false;
$start = ($page - 1) * $this->maxPerPage; $start = ($page - 1) * $this->maxPerPage;
return ;
$nbResults = CourseManager::displayCourses( $nbResults = CourseManager::displayCourses(
$user_id, $user_id,
$filter, $filter,

@ -48,7 +48,10 @@ services:
# Session voter checks if a user has permissions to do actions in a session # Session voter checks if a user has permissions to do actions in a session
chamilo_core.security.authorization.voter.session_voter: chamilo_core.security.authorization.voter.session_voter:
class: Chamilo\CoreBundle\Security\Authorization\Voter\SessionVoter class: Chamilo\CoreBundle\Security\Authorization\Voter\SessionVoter
arguments: ['@doctrine.orm.entity_manager', '@chamilo_core.entity.manager.course_manager', '@service_container'] arguments:
- '@doctrine.orm.entity_manager'
- '@chamilo_core.entity.manager.course_manager'
- '@service_container'
public: false public: false
tags: tags:
- {name: security.voter} - {name: security.voter}
@ -136,6 +139,12 @@ services:
- {name: kernel.event_listener, event: kernel.request, method: onKernelRequest} - {name: kernel.event_listener, event: kernel.request, method: onKernelRequest}
- {name: kernel.event_listener, event: kernel.controller, method: onKernelController, priority: 9} - {name: kernel.event_listener, event: kernel.controller, method: onKernelController, priority: 9}
# chamilo_core.listener.legacy_login_listener:
# class: Chamilo\CoreBundle\EventListener\LegacyLoginListener
# arguments: ["@service_container", '@security.token_storage']
# tags:
# - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
# Locale listener # Locale listener
chamilo_core.listener.locale: chamilo_core.listener.locale:
class: Chamilo\CoreBundle\EventListener\LocaleListener class: Chamilo\CoreBundle\EventListener\LocaleListener

@ -9,14 +9,15 @@ use Chamilo\UserBundle\Entity\User;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter as AbstractVoter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
/** /**
* Class CourseVoter * Class CourseVoter
* @package Chamilo\CoreBundle\Security\Authorization\Voter * @package Chamilo\CoreBundle\Security\Authorization\Voter
*/ */
class CourseVoter extends AbstractVoter class CourseVoter extends Voter
{ {
const VIEW = 'VIEW'; const VIEW = 'VIEW';
const EDIT = 'EDIT'; const EDIT = 'EDIT';

@ -12,14 +12,14 @@ use Chamilo\UserBundle\Entity\User;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter as AbstractVoter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
/** /**
* Class GroupVoter * Class GroupVoter
* @package Chamilo\CoreBundle\Security\Authorization\Voter * @package Chamilo\CoreBundle\Security\Authorization\Voter
*/ */
class GroupVoter extends AbstractVoter class GroupVoter extends Voter
{ {
const VIEW = 'VIEW'; const VIEW = 'VIEW';
const EDIT = 'EDIT'; const EDIT = 'EDIT';

@ -13,7 +13,6 @@ use Doctrine\Common\Collections\ArrayCollection;
use Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap; use Sonata\AdminBundle\Security\Acl\Permission\AdminPermissionMap;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity; use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
//use Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Zend\Permissions\Acl\Acl; use Zend\Permissions\Acl\Acl;
@ -21,7 +20,7 @@ use Zend\Permissions\Acl\Role\GenericRole as Role;
//use Zend\Permissions\Acl\Resource\GenericResource as Resource; //use Zend\Permissions\Acl\Resource\GenericResource as Resource;
use Symfony\Component\Security\Acl\Permission\MaskBuilder; use Symfony\Component\Security\Acl\Permission\MaskBuilder;
use Symfony\Component\Security\Core\Authorization\Voter\Voter as AbstractVoter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
//use Sonata\AdminBundle\Security\Acl\Permission\MaskBuilder; //use Sonata\AdminBundle\Security\Acl\Permission\MaskBuilder;
@ -29,7 +28,7 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter as AbstractVoter;
* Class ResourceNodeVoter * Class ResourceNodeVoter
* @package Chamilo\CoreBundle\Security\Authorization\Voter * @package Chamilo\CoreBundle\Security\Authorization\Voter
*/ */
class ResourceNodeVoter extends AbstractVoter class ResourceNodeVoter extends Voter
{ {
private $container; private $container;

@ -16,11 +16,12 @@ services:
# Event Listeners # Event Listeners
chamilo_course.listener.course: chamilo_course.listener.course:
class: Chamilo\CourseBundle\EventListener\CourseListener class: Chamilo\CourseBundle\EventListener\CourseListener
arguments: ['@service_container'] calls:
- [setContainer, ['@service_container']]
tags: tags:
- {name: kernel.event_listener, event: kernel.request, method: onKernelRequest} - {name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 200}
- {name: kernel.event_listener, event: kernel.response, method: onKernelResponse} - {name: kernel.event_listener, event: kernel.response, method: onKernelResponse}
- {name: kernel.event_listener, event: kernel.controller, method: onKernelController, priority: 10} - {name: kernel.event_listener, event: kernel.controller, method: onKernelController}
# Sets the user access in a course listener # Sets the user access in a course listener
chamilo_course.listener.course_access: chamilo_course.listener.course_access:

Loading…
Cancel
Save