Skip to content

Commit

Permalink
Add impersonating user info
Browse files Browse the repository at this point in the history
  • Loading branch information
ronisaha committed Sep 7, 2016
1 parent f47ecb1 commit 1c0a88c
Show file tree
Hide file tree
Showing 12 changed files with 567 additions and 20 deletions.
21 changes: 21 additions & 0 deletions Common/UserAwareComponent.php
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Xiidea\EasyAuditBundle\Traits\ServiceContainerGetterMethods;

class UserAwareComponent implements ContainerAwareInterface
Expand Down Expand Up @@ -51,6 +52,26 @@ public function getUser()
return $user;
}

/**
* @return mixed
*/
protected final function getImpersonatingUser()
{
if (null === $token = $this->getContainer()->get('security.token_storage')->getToken()) {
return null;
}

if ($this->getContainer()->get('security.authorization_checker')->isGranted('ROLE_PREVIOUS_ADMIN')) {
foreach ($token->getRoles() as $role) {
if ($role instanceof SwitchUserRole) {
return $role->getSource()->getUser();
}
}
}

return null;
}

/**
* @return string
*/
Expand Down
18 changes: 18 additions & 0 deletions Entity/BaseAuditLog.php
Expand Up @@ -41,6 +41,8 @@ abstract class BaseAuditLog

protected $user;

protected $impersonatingUser;

/**
* @var String
*/
Expand Down Expand Up @@ -178,4 +180,20 @@ private function getAllowedLevel()

return $oClass->getConstants();
}

/**
* @return mixed
*/
public function getImpersonatingUser()
{
return $this->impersonatingUser;
}

/**
* @param mixed $impersonatingUser
*/
public function setImpersonatingUser($impersonatingUser)
{
$this->impersonatingUser = $impersonatingUser;
}
}
13 changes: 13 additions & 0 deletions Resolver/EventResolverFactory.php
Expand Up @@ -128,6 +128,8 @@ protected function setUser(BaseAuditLog $entity)
}

$entity->setUser($this->getSettablePropertyValue($userProperty, $user));

$this->setImpersonatingUser($entity, $userProperty);
}


Expand Down Expand Up @@ -237,4 +239,15 @@ protected function getSettablePropertyValue($userProperty, $user)
return $this->handleException($e);
}
}

/**
* @param BaseAuditLog $entity
* @param $userProperty
*/
protected function setImpersonatingUser(BaseAuditLog $entity, $userProperty)
{
if (null !== $user = $this->getImpersonatingUser()) {
$entity->setImpersonatingUser($this->getSettablePropertyValue($userProperty, $user));
}
}
}
178 changes: 178 additions & 0 deletions Tests/Common/UserAwareComponentTest.php
@@ -0,0 +1,178 @@
<?php

namespace Xiidea\EasyAuditBundle\Tests\Common;

/*
* This file is part of the XiideaEasyAuditBundle package.
*
* (c) Xiidea <http://www.xiidea.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Xiidea\EasyAuditBundle\Tests\Fixtures\Common\DummyToken;
use Xiidea\EasyAuditBundle\Tests\Fixtures\Common\DummyUserAwareComponent;
use Xiidea\EasyAuditBundle\Tests\Fixtures\ORM\UserEntity;

class UserAwareComponentTest extends \PHPUnit_Framework_TestCase
{
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $container;

/** @var \PHPUnit_Framework_MockObject_MockObject */
private $securityContext;


/** @var DummyUserAwareComponent */
private $userAwareComponent;

public function setUp()
{
$this->container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$this->userAwareComponent = new DummyUserAwareComponent();
$this->userAwareComponent->setContainer($this->container);
}

/**
* @expectedException \LogicException
*/
public function testShouldThrowLogicExceptionWithoutSecurityBundle()
{
$this->container->expects($this->at(0))
->method('has')
->with($this->equalTo('security.token_storage'))
->willReturn(false);

$user = $this->userAwareComponent->getUser();

$this->assertNull($user);
}

public function testShouldReturnNullUserIfUserNotLoggedIn()
{
$this->initiateContainerWithSecurityContextCheck();

$user = $this->userAwareComponent->getUser();

$this->assertNull($user);
}

public function testShouldReturnUserObjectOnLoggedInState()
{
$this->initiateContainerWithSecurityContextCheck();

$this->securityContext->expects($this->any())
->method('getToken')
->willReturn(new DummyToken(new UserEntity(1, 'admin')));

$user = $this->userAwareComponent->getUser();

$this->assertNotNull($user);
$this->assertEquals('admin', $user->getUsername());
$this->assertEquals(1, $user->getId());
}

public function testShouldReturnNullIfAuthenticatedAnonymously()
{
$this->initiateContainerWithSecurityContextCheck();

$this->securityContext->expects($this->any())
->method('getToken')
->willReturn(new DummyToken(""));

$user = $this->userAwareComponent->getUser();

$this->assertNull($user);
}

public function testShouldReturnNullImpersonatingUserWhenSecurityTokenNotExists() {

$this->initiateContainerWithOutSecurityContextCheck();

$this->securityContext->expects($this->any())
->method('getToken')
->willReturn(null);

$user = $this->userAwareComponent->getImpersonatingUserForTest();

$this->assertNull($user);
}

public function testShouldReturnNullImpersonatingUserIfUserDoNotHavePreviousAdminRole() {
$this->initiateContainerWithOutSecurityContextCheck();
$this->mockSecurityAuthChecker(1);

$this->securityContext->expects($this->any())
->method('getToken')
->willReturn(new DummyToken(new UserEntity(1, 'a')));

$user = $this->userAwareComponent->getImpersonatingUserForTest();

$this->assertNull($user);
}

public function testShouldReturnImpersonatingUserIfUserHavePreviousAdminRole() {
$this->initiateContainerWithOutSecurityContextCheck();
$this->mockSecurityAuthChecker(1, true);

$userToken = new DummyToken(new UserEntity(1, 'admin'));

$this->securityContext->expects($this->any())
->method('getToken')
->willReturn(new DummyToken(new UserEntity(1, 'a', array(new SwitchUserRole('', $userToken)))));

$user = $this->userAwareComponent->getImpersonatingUserForTest();

$this->assertNotNull($user);
$this->assertEquals('admin', $user->getUsername());
$this->assertEquals(1, $user->getId());
}

private function mockSecurityAuthChecker($callIndex, $isGranted = false) {
$authChecker = $this->getMock('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface');

$this->container->expects($this->at($callIndex))
->method('get')
->with($this->equalTo('security.authorization_checker'))
->willReturn($authChecker);

$authChecker->expects($this->once())
->method('isGranted')
->with('ROLE_PREVIOUS_ADMIN')
->willReturn($isGranted);
}


protected function initiateContainerWithSecurityContextCheck($callIndex = 0)
{
$this->securityContext = $this
->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage')
->disableOriginalConstructor()
->getMock();

$this->container->expects($this->at($callIndex))
->method('has')
->with($this->equalTo('security.token_storage'))
->willReturn(true);

$this->container->expects($this->at($callIndex + 1))
->method('get')
->with($this->equalTo('security.token_storage'))
->willReturn($this->securityContext);
}

protected function initiateContainerWithOutSecurityContextCheck($callIndex = 0)
{
$this->securityContext = $this
->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage')
->disableOriginalConstructor()
->getMock();

$this->container->expects($this->at($callIndex))
->method('get')
->with($this->equalTo('security.token_storage'))
->willReturn($this->securityContext);
}
}
Expand Up @@ -11,7 +11,6 @@

namespace Xiidea\EasyAuditBundle\Tests\DependencyInjection\Compiler;


use Symfony\Component\DependencyInjection\Reference;
use Xiidea\EasyAuditBundle\DependencyInjection\Compiler\LoggerFactoryPass;

Expand Down

0 comments on commit 1c0a88c

Please sign in to comment.