Skip to content

[SecurityBundle] added acl:set command #9990

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

Merged
merged 1 commit into from
Jun 3, 2014
Merged

Conversation

dunglas
Copy link
Member

@dunglas dunglas commented Jan 10, 2014

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets no
License MIT
Doc PR n/a

This new command allows to set ACL directly from the command line. This useful to quickly set up an environment and for debugging / maintenance purpose.

This PR also includes a functional test system for the ACL component. As an example, it is used to test the acl:set command.
The provided entity class is not mandatory (tests will still be green without it) but can be useful to test other ACL related things. I can remove it if necessary.

The instantiation of the MaskBuilder object is done in a separate method to be easily overridable to use a custom one (e.g. the SonataAdmin one).

@@ -70,6 +70,7 @@
"doctrine/data-fixtures": "1.0.*",
"doctrine/dbal": "~2.2",
"doctrine/orm": "~2.2,>=2.2.3",
"doctrine/doctrine-bundle": "~1.2",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A soft dependency could be better.

You can play with class_exist and Command::IsEnable method

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lyrixx doctrine-bundle is only needed to run the tests. It's a require-dev dependency.
Making it a soft dependency is awkward because all functional tests on the ACL system will be skipped by default.
If someone clone the repository, start hacking, run phpunit and make a PR, he can silently broke the ACL system.

It will also require tweaking .travis.yml (to make Travis install doctrine-bundle before running the tests) and update the doc to explain that tests should be run with doctrine-bundle installed.

If it's really annoying to have doctrine-bundle as a development dependency, I prefer registering the DBAL connection directly in the test app's kernel.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know which solution is better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. I did not see it was a dev deps ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're welcome.

@ErichHartmann
Copy link

If any, could you please describe risks or security implications that might result from the ability to set the ACL directly from the command line?

@dunglas
Copy link
Member Author

dunglas commented Jan 16, 2014

@ErichHartmann I think there is no specific security risk or implication for this command. If an attacker get a shell on your server, it's over. Even without this command.

He can access to database's credentials through app/config/parameters.yml, run any SQL query (including an ACL related one) with doctrine:query:sql, run arbitrary PHP code with php -a and do even worse with the shell itself (rm -Rf /).

@dunglas
Copy link
Member Author

dunglas commented Feb 11, 2014

Is this PR ready to be merged? Can I start working on the PR in the doc?

<info>php %command.full_name%</info>

The ACL system must have been initialized with the <info>init:acl</info> command.
EOF
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Help should be expanded to explain the main use cases (probably using the defined options).

@fabpot
Copy link
Member

fabpot commented Mar 3, 2014

@dunglas There is no need to document the command in the docs, but the help message should be expanded instead.

@stof
Copy link
Member

stof commented Mar 4, 2014

the isEnabled method should be overwritten so that the command is available only when the ACL system is enabled. See the router:debug command for an example of usage

->addOption('security-class', 'sc', InputOption::VALUE_OPTIONAL, 'The user security class')
->addOption('security-username', 'su', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The user security username')
->addOption('role', 'r', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'A list of roles')
->addOption('class-scope', 'cs', InputOption::VALUE_OPTIONAL, 'Use class-scope entries', false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be VALUE_NONE IMO

@dunglas
Copy link
Member Author

dunglas commented Mar 4, 2014

@fabpot @stof thanks for the review. I'll be very busy next week but I'll make needed changes when I'll be back.

@dunglas
Copy link
Member Author

dunglas commented Mar 19, 2014

@fabpot @stof Fixed reported issues and added the ability to use / as a namespace delimiter. Added a more precise (but still rude) help message.

fabpot added a commit that referenced this pull request Mar 19, 2014
This PR was submitted for the 2.3-dev branch but it was merged into the 2.3 branch instead (closes #10497).

Discussion
----------

[SecurityBundle] Fixed doc of InitAclCommand

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | no
| License       | MIT
| Doc PR        | n/a

Use {@inheritdoc}. Consistency with #9990 (diff).

Commits
-------

aa49009 [SecurityBundle] Fixed doc of InitAclCommand
)
->addArgument('object-class', InputArgument::REQUIRED, 'The object class name')
->addOption('object-id', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'The object ID')
->addOption('security-class', null, InputOption::VALUE_OPTIONAL, 'The user security class')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VALUE_OPTIONAL means that you don't need to pass a value when using this option, so --security-class is valid; which looks wrong to me. Again, any required value should probably be an argument and not an option.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not required to pass a security class. You must pass at least a security class and a security username OR a role.

This is checked lines 104 to 108.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But when using the --security-class, you must pass a class name, right? If that's the case, you must use VALUE_REQUIRED. VALUE_OPTIONAL means that the value for the option is optional, not the option itself. An option is always optional by definition.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I got it. For required values, how to handle several arrays as arguments?
Object IDs and permissions are required and are arrays.

Should I use an argument for one of them (which) and leave the other as a (required) option?

@dunglas
Copy link
Member Author

dunglas commented Apr 9, 2014

Fixed options types.

protected function execute(InputInterface $input, OutputInterface $output)
{
$objectClassName = strtr($input->getArgument('object-class'), '/', '\\');
$objectIds = $input->getOption('object-id');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the user did not provide a --object-id option? You're going to get null here. That's why I said that all required information must be managed via arguments, not options. To avoid getting too many of them, you can maybe have some conventions like class:id.

@dunglas
Copy link
Member Author

dunglas commented Apr 21, 2014

@fabpot use arguments when required. Simplified and enhanced CLI.

@fabpot
Copy link
Member

fabpot commented Apr 22, 2014

Looks good to me for 2.6. Thanks.

return false;
}

$router = $this->getContainer()->get('security.acl.provider');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird variable name

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed.

@dunglas
Copy link
Member Author

dunglas commented Apr 25, 2014

Renamed weird variable.

@fabpot fabpot added Acl and removed Security labels Apr 28, 2014
@fabpot
Copy link
Member

fabpot commented Jun 3, 2014

Thank you @dunglas.

@fabpot fabpot merged commit a702124 into symfony:master Jun 3, 2014
fabpot added a commit that referenced this pull request Jun 3, 2014
This PR was merged into the 2.6-dev branch.

Discussion
----------

[SecurityBundle] added acl:set command

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | no
| License       | MIT
| Doc PR        | n/a

This new command allows to set ACL directly from the command line. This useful to quickly set up an environment and for debugging / maintenance purpose.

This PR also includes a functional test system for the ACL component. As an example, it is used to test the `acl:set` command.
The provided entity class is not mandatory (tests will still be green without it) but can be useful to test other ACL related things. I can remove it if necessary.

The instantiation of the `MaskBuilder` object is done in a separate method to be easily overridable to use a custom one (e.g. the SonataAdmin one).

Commits
-------

a702124 [SecurityBundle] added acl:set command

To set permissions at the class scope, use the <info>--class-scope</info> option:

<info>php %command.full_name% --class-scope --user=Symfony/Component/Security/Core/User/User:anne OWNER Acme/MyClass:42</info>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dunglas, I'm redacting a "New in Symfony 2.6" blog post about the new acl:set and I wonder if this help message is correct. If you are using the --class-scope, you are granting access to all the objects of the same class, so the trailing object id (42 in this case) should be removed, right?

Original help message:

<info>php %command.full_name% --class-scope --user=Symfony/Component/Security/Core/User/User:anne OWNER Acme/MyClass:42</info>

Proposed help message:

<info>php %command.full_name% --class-scope --user=Symfony/Component/Security/Core/User/User:anne OWNER Acme/MyClass</info>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @javiereguiluz. This help message is correct. It should not be modified. This how the underlying ACL system works (and I agree that this is far from perfect).

The class scope can be set only is you precise an object identity (otherwise an error will be thrown). Technically, it will not grant access to all objects of the same class but only to all objects of this class present in the ACL table.

e.g:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dunglas thanks for your reply. I now understand that everything is correct. However, I find this behavior amazingly counterintuitive. Moreover, in the scopes for access control entries section of the documentation it says:

Class-Scope: These entries apply to all objects with the same class.

This is quite different from what you have said. @wouterj don't you think that the documentation should better explain this strange behavior?

@wouterj
Copy link
Member

wouterj commented Jun 25, 2014

This also should get documented in cookbook/security of the documentation, shouldn't it?

@dunglas dunglas deleted the acl_commands branch December 5, 2015 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants