N°919 Portal: Make portal denial based on user profiles work again

This commit is contained in:
Molkobain
2019-08-12 16:15:09 +02:00
parent b096472ccf
commit ca92316e7d
3 changed files with 68 additions and 50 deletions

View File

@@ -22,13 +22,12 @@
namespace Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration;
use Combodo\iTop\DesignElement;
use iPortalUIExtension;
use Symfony\Component\DependencyInjection\Container;
use Exception;
use utils;
use UserRights;
use MetaModel;
use DOMFormatException;
use Exception;
use iPortalUIExtension;
use MetaModel;
use Symfony\Component\DependencyInjection\Container;
use utils;
/**
* Class Basic
@@ -55,8 +54,6 @@ class Basic extends AbstractConfiguration
$aPortalConf = $this->ParseGlobalProperties($aPortalConf);
// - Rectifying portal logo url
$aPortalConf = $this->AppendLogoUri($aPortalConf);
// - User allowed portals
$aPortalConf['portals'] = UserRights::GetAllowedPortals();
// - class list
$aPortalConf['ui_extensions'] = $this->GetUiExtensions($oContainer);
@@ -99,7 +96,6 @@ class Basic extends AbstractConfiguration
'opening_mode' => null,
),
),
'portals' => array(),
'forms' => array(),
'ui_extensions' => array(
'css_files' => array(),
@@ -148,7 +144,7 @@ class Basic extends AbstractConfiguration
$aPortalConf = $this->ParseAttachments($aPortalConf, $oPropertyNode);
break;
case 'allowed_portals':
$aPortalConf = $this->ParseAllowedPortals($aPortalConf, $oPropertyNode);
$aPortalConf = $this->ParseAllowedPortalsOptions($aPortalConf, $oPropertyNode);
break;
}
}
@@ -247,7 +243,7 @@ class Basic extends AbstractConfiguration
*
* @return array
*/
private function ParseAllowedPortals(array $aPortalConf, DesignElement $oPropertyNode)
private function ParseAllowedPortalsOptions(array $aPortalConf, DesignElement $oPropertyNode)
{
/** @var \MFElement $oSubNode */
foreach ($oPropertyNode->GetNodes('*') as $oSubNode)

View File

@@ -21,14 +21,16 @@
namespace Combodo\iTop\Portal\EventListener;
use Dict;
use Exception;
use LoginWebPage;
use ModuleDesign;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Dict;
use LoginWebPage;
use Symfony\Component\HttpKernel\Exception\HttpException;
use UserRights;
use ModuleDesign;
/**
* Class UserProvider
@@ -38,9 +40,9 @@ use ModuleDesign;
*/
class UserProvider implements ContainerAwareInterface
{
/** @var \ModuleDesign $oModuleDesign */
private $oModuleDesign;
/** @var string $sPortalId */
/** @var \ModuleDesign $oModuleDesign */
private $oModuleDesign;
/** @var string $sPortalId */
private $sPortalId;
/** @var \Symfony\Component\DependencyInjection\ContainerInterface $container */
private $oContainer;
@@ -51,42 +53,62 @@ class UserProvider implements ContainerAwareInterface
* @param \ModuleDesign $oModuleDesign
* @param string $sPortalId
*/
public function __construct(ModuleDesign $oModuleDesign, $sPortalId)
{
$this->oModuleDesign = $oModuleDesign;
$this->sPortalId = $sPortalId;
}
public function __construct(ModuleDesign $oModuleDesign, $sPortalId)
{
$this->oModuleDesign = $oModuleDesign;
$this->sPortalId = $sPortalId;
}
/**
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $oGetResponseEvent
*
* @throws \Exception
*/
public function onKernelRequest(GetResponseEvent $oGetResponseEvent)
{
// User pre-checks
// Note: At this point the Exception handler is not registered, so we can't use $oApp::abort() method, hence the die().
// - Checking user rights and prompt if needed (401 HTTP code returned if XHR request)
$iExitMethod = ($oGetResponseEvent->getRequest()->isXmlHttpRequest()) ? LoginWebPage::EXIT_RETURN : LoginWebPage::EXIT_PROMPT;
$iLogonRes = LoginWebPage::DoLoginEx($this->sPortalId, false, $iExitMethod);
if( ($iExitMethod === LoginWebPage::EXIT_RETURN) && ($iLogonRes != 0) )
{
die(Dict::S('Portal:ErrorUserLoggedOut'));
}
// - User must be associated with a Contact
if (UserRights::GetContactId() == 0)
{
die(Dict::S('Portal:ErrorNoContactForThisUser'));
}
public function onKernelRequest(GetResponseEvent $oGetResponseEvent)
{
// User pre-checks
// Note: At this point the Exception handler is not registered, so we can't use $oApp::abort() method, hence the die().
// - Checking user rights and prompt if needed (401 HTTP code returned if XHR request)
$iExitMethod = ($oGetResponseEvent->getRequest()->isXmlHttpRequest()) ? LoginWebPage::EXIT_RETURN : LoginWebPage::EXIT_PROMPT;
$iLogonRes = LoginWebPage::DoLoginEx($this->sPortalId, false, $iExitMethod);
if( ($iExitMethod === LoginWebPage::EXIT_RETURN) && ($iLogonRes != 0) )
{
die(Dict::S('Portal:ErrorUserLoggedOut'));
}
// - User must be associated with a Contact
if (UserRights::GetContactId() == 0)
{
die(Dict::S('Portal:ErrorNoContactForThisUser'));
}
// User
$oUser = UserRights::GetUserObject();
if ($oUser === null)
{
throw new Exception('Could not load connected user.');
}
$this->oContainer->set('combodo.current_user', $oUser);
}
// User
$oUser = UserRights::GetUserObject();
if ($oUser === null)
{
throw new Exception('Could not load connected user.');
}
$this->oContainer->set('combodo.current_user', $oUser);
// Allowed portals
$aAllowedPortals = UserRights::GetAllowedPortals();
// Checking that user is allowed this portal
$bAllowed = false;
foreach ($aAllowedPortals as $aAllowedPortal)
{
if ($aAllowedPortal['id'] === $this->sPortalId)
{
$bAllowed = true;
break;
}
}
if (!$bAllowed)
{
throw new HttpException(Response::HTTP_NOT_FOUND);
}
/** @noinspection PhpParamsInspection It's an array and it's gonna stay that way */
$this->oContainer->set('combodo.current_user.allowed_portals', $aAllowedPortals);
}
/**
* Sets the container.

View File

@@ -217,14 +217,14 @@
{% if bUserConnected %}
<li role="separator" class="divider"></li>
<li><a href="{{ app.url_generator.generate('p_user_profile_brick') }}"><span class="brick_icon fas fa-user fa-2x fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil'|dict_s }}</a></li>
{% for aPortal in app['combodo.portal.instance.conf'].portals %}
{% for aPortal in app['combodo.current_user.allowed_portals'] %}
{% if aPortal.id != app['combodo.portal.instance.conf'].properties.id %}
{% set sIconClass = (aPortal.id == 'backoffice') ? 'far fa-list-alt' : 'fas fa-external-link-alt' %}
<li><a href="{{ aPortal.url }}" target="_blank"><span class="brick_icon {{ sIconClass }} fa-2x fa-fw"></span>{{ aPortal.label|dict_s }}</a></li>
{% endif %}
{% endfor %}
{# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
{% if app['combodo.portal.instance.conf'].portals|length > 1 %}
{% if app['combodo.current_user.allowed_portals']|length > 1 %}
<li role="separator" class="divider"></li>
{% endif %}
<li><a href="{{ app['combodo.absolute_url'] }}pages/logoff.php"><span class="brick_icon fas fa-sign-out-alt fa-2x fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}</a></li>
@@ -256,14 +256,14 @@
</a>
<ul class="dropdown-menu user_options" aria-labelledby="user_options">
<li><a href="{{ app.url_generator.generate('p_user_profile_brick') }}"><span class="brick_icon fas fa-user fa-lg fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:MyProfil'|dict_s }}</a></li>
{% for aPortal in app['combodo.portal.instance.conf'].portals %}
{% for aPortal in app['combodo.current_user.allowed_portals'] %}
{% if aPortal.id != app['combodo.portal.instance.conf'].properties.id %}
{% set sGlyphiconClass = (aPortal.id == 'backoffice') ? 'far fa-list-alt' : 'fas fa-external-link-alt' %}
<li><a href="{{ aPortal.url }}" {% if app['combodo.portal.instance.conf'].properties.allowed_portals.opening_mode == 'tab' %}target="_blank"{% endif %} title="{{ aPortal.label|dict_s }}"><span class="brick_icon {{ sGlyphiconClass }} fa-lg fa-fw"></span>{{ aPortal.label|dict_s }}</a></li>
{% endif %}
{% endfor %}
{# We display the separator only if the user has more then 1 portal. Meaning default portal + console or several portal at least #}
{% if app['combodo.portal.instance.conf'].portals|length > 1 %}
{% if app['combodo.current_user.allowed_portals']|length > 1 %}
<li role="separator" class="divider"></li>
{% endif %}
<li><a href="{{ app['combodo.absolute_url'] }}pages/logoff.php"><span class="brick_icon fas fa-sign-out-alt fa-lg fa-fw"></span>{{ 'Brick:Portal:UserProfile:Navigation:Dropdown:Logout'|dict_s }}</a></li>