Skip to content

Commit

Permalink
Merge pull request DATA-DOG#59 from stefanogironella/blame-impersonator
Browse files Browse the repository at this point in the history
Blame impersonator
  • Loading branch information
l3pp4rd authored Jul 31, 2019
2 parents 06b8618 + 800143c commit d930195
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ Sometimes, it is also possible, that you want to create audit log entries only f

You can specify either audited or unaudited entities. If both are specified, only audited entities would be taken into account.

### Impersonation

Sometimes, you might also want to blame the `impersonator` user instead of the `impersonated` one. You can archive this by adding the `blame_impersonator` configuration key in your `config.yml`, for example:

data_dog_audit:
blame_impersonator: true
The default behavior is to blame the logged-in user, so it will ignore the `impersonator` when not explicitly declared.

## Screenshots

All paginated audit log:
Expand Down
7 changes: 7 additions & 0 deletions src/DataDog/AuditBundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ public function getConfigTreeBuilder()
->end()
;

$rootNode
->children()
->booleanNode('blame_impersonator')
->defaultFalse()
->end()
;

return $treeBuilder;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@ public function load(array $configs, ContainerBuilder $container)
} else if (isset($config['unaudited_entities'])) {
$auditSubscriber->addMethodCall('addUnauditedEntities', array($config['unaudited_entities']));
}

if (isset($config['blame_impersonator'])) {
$auditSubscriber->addMethodCall('setBlameImpersonator', array($config['blame_impersonator']));
}
}
}
30 changes: 30 additions & 0 deletions src/DataDog/AuditBundle/EventSubscriber/AuditSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use DataDog\AuditBundle\Entity\Association;

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Logging\LoggerChain;
Expand Down Expand Up @@ -34,6 +36,8 @@ class AuditSubscriber implements EventSubscriber
protected $auditedEntities = [];
protected $unauditedEntities = [];

protected $blameImpersonator = false;

protected $inserted = []; // [$source, $changeset]
protected $updated = []; // [$source, $changeset]
protected $removed = []; // [$source, $id]
Expand Down Expand Up @@ -78,6 +82,12 @@ public function addUnauditedEntities(array $unauditedEntities)
}
}

public function setBlameImpersonator($blameImpersonator)
{
// blame impersonator user instead of logged user (where applicable)
$this->blameImpersonator = $blameImpersonator;
}

public function getUnauditedEntities()
{
return array_keys($this->unauditedEntities);
Expand Down Expand Up @@ -457,12 +467,32 @@ protected function blame(EntityManager $em)
return $this->assoc($em, $this->blameUser);
}
$token = $this->securityTokenStorage->getToken();
$impersonatorUser = $this->getImpersonatorUserFromSecurityToken($token);
if ($impersonatorUser instanceof UserInterface) {
return $this->assoc($em, $impersonatorUser);
}
if ($token && $token->getUser() instanceof UserInterface && \method_exists($token->getUser(), 'getId')) {
return $this->assoc($em, $token->getUser());
}
return null;
}

private function getImpersonatorUserFromSecurityToken($token)
{
if (false === $this->blameImpersonator) {
return null;
}
if(!$token instanceof TokenInterface) {
return null;
}
foreach ($token->getRoles() as $role) {
if ($role instanceof SwitchUserRole) {
return $role->getSource()->getUser();
}
}
return null;
}

public function getSubscribedEvents()
{
return [Events::onFlush];
Expand Down

0 comments on commit d930195

Please sign in to comment.