-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security][SecurityBundle] Dump role hierarchy as mermaid chart #61034
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
base: 7.4
Are you sure you want to change the base?
Conversation
src/Symfony/Bundle/SecurityBundle/Command/SecurityRoleHierarchyDumpCommand.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/SecurityBundle/Command/SecurityRoleHierarchyDumpCommand.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/SecurityBundle/Tests/Command/SecurityRoleHierarchyDumpCommandTest.php
Outdated
Show resolved
Hide resolved
]; | ||
|
||
public function __construct( | ||
private readonly string $direction = self::DIRECTION_TOP_TO_BOTTOM, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving $direction
argument to dump
method would allow to dump multiple times the same role hierarchy in different directions without the need to instanciate multiple dumpers. WDYT?
Nice one 👍🏻 |
src/Symfony/Bundle/SecurityBundle/Command/SecurityRoleHierarchyDumpCommand.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/SecurityBundle/Tests/Command/SecurityRoleHierarchyDumpCommandTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/SecurityBundle/Tests/Command/SecurityRoleHierarchyDumpCommandTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/SecurityBundle/Tests/Command/SecurityRoleHierarchyDumpCommandTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/SecurityBundle/Tests/Command/SecurityRoleHierarchyDumpCommandTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Core/Tests/Dumper/MermaidDumperTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Core/Tests/Dumper/MermaidDumperTest.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Security/Core/Tests/Dumper/MermaidDumperTest.php
Outdated
Show resolved
Hide resolved
Yes, I had also this in mind for a second PR, once this one gets merged.
Great idea ! I'll keep it in mind :) |
$this | ||
->setDefinition([ | ||
new InputOption('direction', 'd', InputOption::VALUE_REQUIRED, 'The direction of the flowchart ['.implode('|', MermaidDumper::VALID_DIRECTIONS).']', MermaidDumper::DIRECTION_TOP_TO_BOTTOM), | ||
new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'The output format', 'mermaid'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The command implementation being strongly tight to mermaid at the moment, I suggest not to add this format option until we consider supporting another format.
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Security\Core\Dumper; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this dumper really "core" inside this component ?
namespace feels weird
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the role hierarchy belongs to symfony/security-core
, so it makes sense to put the dumper there as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i was seeing this class tooling more like a "debug or dev" class, that is what I wanted to comment (perhaps poorly ^^)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, it's the only "debug" class of security component for now, and it is quite tied to roles and role hierarchy. IMO, it can stay here for now.
class SecurityRoleHierarchyDumpCommand extends Command | ||
{ | ||
public function __construct( | ||
private readonly ?RoleHierarchyInterface $roleHierarchy = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how can it be null via service declaration service()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We remove the role hierarchy service if you don't configure any hierarchy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we then better remove this command as well ? useless to register a command if its to dump nothing
{ | ||
$this | ||
->setDefinition([ | ||
new InputOption('direction', 'd', InputOption::VALUE_REQUIRED, 'The direction of the flowchart ['.implode('|', MermaidDumper::VALID_DIRECTIONS).']', MermaidDumper::DIRECTION_TOP_TO_BOTTOM), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add support for completion by providing the valid choices
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the completion method in the command okay for this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, I missed that you implemented this method. For static values, it is better to configure the completion values in the definition (and let symfony/console
provide them) as it is simpler and also visible directly when looking at the definition that completion is supported.
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
if (null === $this->roleHierarchy) { | ||
$output->writeln('<comment>No role hierarchy is configured.</comment>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be written to STDERR as it is about human-readable message. this is especially important for that command which will generally send the output to a file.
When using the SymfonyStyle
class, you have a method to access easily the error output, and you can also use the usual symfony style for command output.
$format = $input->getOption('format'); | ||
|
||
if ('mermaid' !== $format) { | ||
$output->writeln('<error>Only "mermaid" format is currently supported.</error>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should also be written to STDERR.
} | ||
|
||
if (!in_array($direction, MermaidDumper::VALID_DIRECTIONS, true)) { | ||
$output->writeln('<error>Invalid direction. Available options: '.implode(', ', MermaidDumper::VALID_DIRECTIONS).'</error>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should also be written to STDERR.
public const DIRECTION_TOP_DOWN = 'TD'; | ||
public const DIRECTION_BOTTOM_TO_TOP = 'BT'; | ||
public const DIRECTION_RIGHT_TO_LEFT = 'RL'; | ||
public const DIRECTION_LEFT_TO_RIGHT = 'LR'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
those look like a perfect use case for a backed enum instead of using string constants in that class (and then redoing lots of manual validation)
{ | ||
$reflection = new \ReflectionClass($roleHierarchy); | ||
|
||
if ($reflection->hasProperty('hierarchy')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the RoleHierarchyInterface is not a child of RoleHierarchy, it could have a hierarchy
property that has a totally unrelated type.
And if the RoleHierarchyInterface is a child of RoleHierarchy, this check will return false
as the property is private: https://3v4l.org/jtqTG#vnull
You should check $roleHierarchy instanceof RoleHierarchy
and then create the ReflectionClass for RoleHierarchy::class
From a developer POV, Roles and the SecurityBundle are so convenient, specially role hierarchy in the config. But as a web app grows, the number of roles also grows and with role inheritance, it can be painful to clearly see which role implies another which implies another which implies another (and its possible consequences).
I'm proposing a new command in the security bundle to generate a Mermaid flowchart, easing the understanding of the roles and its hierarchy. An example of the graph generated from the role hierarchy in the doc :
For now, only the mermaid format is suggested (the only format I know) but as the worfklow dump command, we could implement graphviz and plantuml format later.