Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced re-usable authorization system #9028

Conversation

@mickaelandrieu
Copy link
Member

commented May 4, 2018

Questions Answers
Branch? 1.7.4.x
Description? Since 1.7.3 an employee with no rights can access to some migrated pages
Type? bug fix
Category? BO
BC breaks? no
Deprecations? yes, the functions  $authorizationLevel and isDemoEnabled and getDemoMessage in mid term
Fixed ticket? n/a
How to test? Create a user with no rights and access to every migrated page: you should always be redirected to OnBoarding page. In demo mode, some accesses are granted but some actions (create/update/delete something) should also redirect to some URLs.

Related PR: #9025

Note this is a very important security issue, and this patch should be ported to 1.7.3.x branch.

TLDR;

To implement authorizations into Controller actions, rely on AdminSecurity and DemoRestricted annotations:

    /**
     * Do stuff
     * @AdminSecurity("is_granted(['read','update', 'create','delete'], request.get('_legacy_controller')~'_')", message="You do not have permission to update this.")
     * @DemoRestricted("route_to_be_redirected", message="You can't do this when demo mode is enabled.")
     */
    public function fooAction(Request $request)

Important guidelines


This change is Reviewable

@mickaelandrieu mickaelandrieu changed the title Introduced re-usable authorization system [WIP] Introduced re-usable authorization system May 4, 2018

@@ -61,7 +61,7 @@ public function loadUserByUsername($username)
if (isset($this->legacyContext->employee) && $this->legacyContext->employee->email == $username) {
$employee = new Employee($this->legacyContext->employee);
$employee->setRoles(
Access::getRoles($this->legacyContext->employee->id_profile)
array_merge(['ROLE_EMPLOYEE'], Access::getRoles($this->legacyContext->employee->id_profile))

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

we need to add - at least - a minimal role or the User Provider will throw an exception!

This is not the case if you create a new profile and set no authorization at all: really uncommon, but still, this shouldn't throw a PHP exception 👍

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Maybe use const for roles? (Don't know it is for others)

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

others are values in bdd, I can add a constant in EmployeeProvider.

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

fixed 👍

@mickaelandrieu mickaelandrieu force-pushed the mickaelandrieu:bogoss/reusable-authorization-system branch 2 times, most recently from 9628843 to 8fe74ee May 4, 2018

$security = $event->getRequest()->get('_security');
if (empty($security) || !$security[0] instanceof BetterSecurity) {

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Hum, what happens if there is more than one element in security array?

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

I don't know, and looking at security, I don't even know why I retrieve an array here :/

*/
private function throwNotificationMessage(BetterSecurity $betterSecurity)
{
$this->session->getFlashBag()->add('error', $this->translator->trans($betterSecurity->getMessage(), [], $betterSecurity->getDomain()));

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Line too long:

$this->session->getFlashBag()->add(
    'error',
    $this->translator->trans(
        $betterSecurity->getMessage(),
        [],
        $betterSecurity->getDomain()
    )
);

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

coding style etc... I'll launch php-cs-fixer on this file.

*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
if (!$event->isMasterRequest()) {

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Maybe combine both conditions?

@mickaelandrieu mickaelandrieu force-pushed the mickaelandrieu:bogoss/reusable-authorization-system branch from 8fe74ee to 9419ffc May 4, 2018

$security = $event->getRequest()->get('_security');
if (empty($security) || !$security[0] instanceof AdminSecurity) {

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Hum, what happens if there is more than one element in security array?

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

anyway, fixed 👍

*/
private function throwNotificationMessage( AdminSecurity $adminSecurity)
{
$this->session->getFlashBag()->add('error', $this->translator->trans($adminSecurity->getMessage(), [], $adminSecurity->getDomain()));

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Line too long:

$this->session->getFlashBag()->add(
    'error',
    $this->translator->trans(
        $betterSecurity->getMessage(),
        [],
        $betterSecurity->getDomain()
    )
);

@mickaelandrieu mickaelandrieu force-pushed the mickaelandrieu:bogoss/reusable-authorization-system branch 3 times, most recently from 60f01ce to 7f5faac May 4, 2018

$this->throwNotificationMessage($securityConfiguration);
$url = $this->computeUrl($securityConfiguration);
$event->setResponse(new RedirectResponse($url));

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 4, 2018

Contributor

Break if response is set, no need to continue the foreach.

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

return is even better, thanks :)

@mickaelandrieu mickaelandrieu force-pushed the mickaelandrieu:bogoss/reusable-authorization-system branch from 7f5faac to 3b7a465 May 4, 2018

@mickaelandrieu mickaelandrieu changed the title [WIP] Introduced re-usable authorization system Introduced re-usable authorization system May 4, 2018

@mickaelandrieu mickaelandrieu force-pushed the mickaelandrieu:bogoss/reusable-authorization-system branch 3 times, most recently from 1e7f32b to 459b8f3 May 4, 2018

@@ -41,13 +42,12 @@ class AdministrationController extends FrameworkBundleAdminController
const CONTROLLER_NAME = 'AdminAdminPreferences';
/**
* Show administration page
*
* Show administration page*

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

remove the extra "*"

@@ -0,0 +1,36 @@
<?php

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 4, 2018

Author Member

useless, you can remove it

@mickaelandrieu

This comment has been minimized.

Copy link
Member Author

commented May 7, 2018

ping @eternoendless don't miss this one before 1.7.4 this is a security breach fix

@mickaelandrieu

This comment has been minimized.

Copy link
Member Author

commented May 23, 2018

The question is, why do you concatenate an underscore at the end of the string?

This is how works the current authorization system :/

See https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Controller/Admin/FrameworkBundleAdminController.php#L218 and https://github.com/PrestaShop/PrestaShop/blob/develop/src/PrestaShopBundle/Security/Voter/PageVoter.php#L87

We could improve that, but not here, in a future PR: what I want here is rely on the current system because it works and not introduce regression.

@eternoendless

This comment has been minimized.

Copy link
Member

commented May 23, 2018

We could improve that, but not here, in a future PR.

I agree. I didn't know about the trailing underscore thing, that's why I asked... it's really weird.

@eternoendless

This comment has been minimized.

Copy link
Member

commented May 23, 2018

:lgtm:


Review status: all files reviewed at latest revision, all discussions resolved, all commit checks successful.


Comments from Reviewable

@eternoendless

This comment has been minimized.

Copy link
Member

commented May 23, 2018

Don't forget to write the docs!

@mickaelandrieu

This comment has been minimized.

Copy link
Member Author

commented May 23, 2018

Don't forget to write the docs!

First in my todo list once it's merged 👍

@mickaelandrieu

This comment has been minimized.

Copy link
Member Author

commented May 24, 2018

=> Docs <=

$tokenAnnotation = DemoRestricted::class;
$classAnnotation = $this->annotationReader->getClassAnnotation(
new \ReflectionClass(ClassUtils::getClass($controllerObject)), $tokenAnnotation

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 24, 2018

Contributor

Can you use namespace please

*/
private function getAnnotation($controllerObject, $methodName)
{
$tokenAnnotation = DemoRestricted::class;

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 24, 2018

Contributor

No need to use this variable DemoRestricted::class is a const.

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 24, 2018

Author Member

It's not the reason I'm using a variable, it's to explain what is expected here :)

}

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 24, 2018

Contributor

Double line break.

This comment has been minimized.

Copy link
@mickaelandrieu

mickaelandrieu May 24, 2018

Author Member

fixed

$event->setController(function () use ($url){
return new RedirectResponse($url);
});

This comment has been minimized.

Copy link
@PierreRambaud

PierreRambaud May 24, 2018

Contributor

Useless line break.

@mickaelandrieu

This comment has been minimized.

Copy link
Member Author

commented May 24, 2018

please @PierreRambaud, put the approval again 👍

cs

@mickaelandrieu mickaelandrieu force-pushed the mickaelandrieu:bogoss/reusable-authorization-system branch from 7ef8c17 to 095e81e May 24, 2018

@PierreRambaud

This comment has been minimized.

Copy link
Contributor

commented May 24, 2018

Sir YES Sir 👍

@mickaelandrieu mickaelandrieu merged commit fdc7350 into PrestaShop:1.7.4.x May 24, 2018

2 of 3 checks passed

code-review/reviewable 3 files, 4 discussions left (eternoendless, PierreRambaud, Quetzacoalt91)
Details
Codacy/PR Quality Review Up to standards. A positive pull request.
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@mickaelandrieu

This comment has been minimized.

Copy link
Member Author

commented May 24, 2018

and ... shipped in 1.7.4.0 :)

Don't forget this pull request @eternoendless, very very very important one ^^

@mickaelandrieu mickaelandrieu deleted the mickaelandrieu:bogoss/reusable-authorization-system branch May 24, 2018

@mickaelandrieu mickaelandrieu referenced this pull request Jun 26, 2018
26 of 40 tasks complete
@mickaelandrieu mickaelandrieu referenced this pull request Sep 5, 2018
27 of 40 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.