Skip to content

Commit

Permalink
Merge pull request #803 from PROCERGS/preview-1.19.2
Browse files Browse the repository at this point in the history
v1.19.2
  • Loading branch information
guilhermednt authored Aug 7, 2018
2 parents 370d732 + 5fdea55 commit de6706f
Show file tree
Hide file tree
Showing 15 changed files with 531 additions and 135 deletions.
177 changes: 95 additions & 82 deletions composer.lock

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions src/LoginCidadao/CoreBundle/Entity/Authorization.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ class Authorization
*/
protected $createdAt;

/**
* Authorization constructor.
*/
public function __construct()
{
$this->scope = [];
}

/**
* @return mixed
*/
Expand All @@ -71,10 +79,13 @@ public function getPerson()

/**
* @param PersonInterface|null $person
* @return Authorization
*/
public function setPerson(PersonInterface $person = null)
{
$this->person = $person;

return $this;
}

/**
Expand All @@ -87,10 +98,13 @@ public function getClient()

/**
* @param ClientInterface|null $client
* @return Authorization
*/
public function setClient(ClientInterface $client = null)
{
$this->client = $client;

return $this;
}

/**
Expand All @@ -105,11 +119,14 @@ public function getScope()

/**
* @param array|string $scope
* @return Authorization
*/
public function setScope($scope)
{
$scope = $this->enforcePublicProfileScope(Authorization::enforceArray($scope));
$this->scope = $scope;

return $this;
}

/**
Expand Down
12 changes: 12 additions & 0 deletions src/LoginCidadao/CoreBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,15 @@ services:
public: false
tags:
- { name: twig.extension }

lc.authorization.repository:
class: Doctrine\ORM\EntityRepository
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments:
- LoginCidadao\CoreBundle\Entity\Authorization

lc.authorization.manager:
class: LoginCidadao\CoreBundle\Service\AuthorizationManager
arguments:
- "@doctrine.orm.entity_manager"
- "@lc.authorization.repository"
104 changes: 104 additions & 0 deletions src/LoginCidadao/CoreBundle/Service/AuthorizationManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
/**
* This file is part of the login-cidadao project or it's bundles.
*
* (c) Guilherme Donato <guilhermednt on github>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace LoginCidadao\CoreBundle\Service;

use Doctrine\ORM\EntityManagerInterface;
use LoginCidadao\CoreBundle\Entity\Authorization;
use LoginCidadao\CoreBundle\Entity\AuthorizationRepository;
use LoginCidadao\CoreBundle\Model\PersonInterface;
use LoginCidadao\OAuthBundle\Model\ClientInterface;

class AuthorizationManager
{
/** @var string merge new scope with old one */
public const SCOPE_MERGE = 'merge';

/** @var string replace old scope by new one */
public const SCOPE_REPLACE = 'replace';

/** @var EntityManagerInterface */
private $em;

/** @var AuthorizationRepository */
private $repository;

/**
* AuthorizationManager constructor.
* @param EntityManagerInterface $em
* @param AuthorizationRepository $repository
*/
public function __construct(EntityManagerInterface $em, AuthorizationRepository $repository)
{
$this->em = $em;
$this->repository = $repository;
}

/**
* @param PersonInterface $person
* @param ClientInterface $client
* @return Authorization|null
*/
public function getAuthorization(PersonInterface $person, ClientInterface $client): ?Authorization
{
/** @var Authorization $authorization */
$authorization = $this->repository->findOneBy([
'person' => $person,
'client' => $client,
]);

return $authorization;
}

/**
* @param PersonInterface $person
* @param ClientInterface $client
* @param array $scope
* @param string $scopeStrategy
* @param bool $flush
* @return Authorization
*/
public function enforceAuthorization(
PersonInterface $person,
ClientInterface $client,
array $scope,
string $scopeStrategy,
bool $flush = true
): Authorization {
$authorization = $this->getAuthorization($person, $client);
if (null === $authorization) {
$authorization = (new Authorization())
->setPerson($person)
->setClient($client);
$this->em->persist($authorization);
}

$authorization->setScope(
$this->mergeScope($authorization->getScope(), $scope, $scopeStrategy)
);

if ($flush) {
$this->em->flush();
}

return $authorization;
}

private function mergeScope(array $oldScope, array $newScope, string $strategy)
{
if (self::SCOPE_REPLACE === $strategy) {
return $newScope;
} elseif (self::SCOPE_MERGE === $strategy) {
return array_unique(array_merge($oldScope, $newScope));
} else {
throw new \InvalidArgumentException("Invalid scope merging strategy: '{$strategy}'");
}
}
}
120 changes: 120 additions & 0 deletions src/LoginCidadao/CoreBundle/Tests/Service/AuthorizationManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
/**
* This file is part of the login-cidadao project or it's bundles.
*
* (c) Guilherme Donato <guilhermednt on github>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace LoginCidadao\CoreBundle\Tests\Service;

use Doctrine\ORM\EntityManagerInterface;
use LoginCidadao\CoreBundle\Entity\Authorization;
use LoginCidadao\CoreBundle\Entity\AuthorizationRepository;
use LoginCidadao\CoreBundle\Entity\Person;
use LoginCidadao\CoreBundle\Service\AuthorizationManager;
use LoginCidadao\OAuthBundle\Entity\Client;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class AuthorizationManagerTest extends TestCase
{
public function testGetAuthorization()
{
$person = new Person();
$client = new Client();
$authorization = (new Authorization())
->setPerson($person)
->setClient($client);

/** @var EntityManagerInterface|MockObject $em */
$em = $this->createMock(EntityManagerInterface::class);

/** @var AuthorizationRepository|MockObject $repo */
$repo = $this->createMock(AuthorizationRepository::class);
$repo->expects($this->once())->method('findOneBy')
->with(['person' => $person, 'client' => $client])
->willReturn($authorization);

$manager = new AuthorizationManager($em, $repo);
$this->assertSame($authorization, $manager->getAuthorization($person, $client));
}

public function testEnforceNewAuthorization()
{
$person = new Person();
$client = new Client();
$scope = ['new'];
$strategy = AuthorizationManager::SCOPE_REPLACE;

/** @var EntityManagerInterface|MockObject $em */
$em = $this->createMock(EntityManagerInterface::class);
$em->expects($this->once())->method('flush');
$em->expects($this->once())->method('persist')->with($this->isInstanceOf(Authorization::class));

/** @var AuthorizationRepository|MockObject $repo */
$repo = $this->createMock(AuthorizationRepository::class);

$manager = new AuthorizationManager($em, $repo);
$authorization = $manager->enforceAuthorization($person, $client, $scope, $strategy);

$this->assertInstanceOf(Authorization::class, $authorization);
$this->assertContains('new', $authorization->getScope());
}

public function testEnforceExistingAuthorization()
{
$person = new Person();
$client = new Client();
$scope = ['new'];
$strategy = AuthorizationManager::SCOPE_MERGE;

$existingAuthorization = (new Authorization())
->setPerson($person)
->setClient($client)
->setScope(['old']);

/** @var EntityManagerInterface|MockObject $em */
$em = $this->createMock(EntityManagerInterface::class);
$em->expects($this->once())->method('flush');
$em->expects($this->never())->method('persist')->with($this->isInstanceOf(Authorization::class));

/** @var AuthorizationRepository|MockObject $repo */
$repo = $this->createMock(AuthorizationRepository::class);
$repo->expects($this->once())->method('findOneBy')
->with(['person' => $person, 'client' => $client])
->willReturn($existingAuthorization);

$manager = new AuthorizationManager($em, $repo);
$authorization = $manager->enforceAuthorization($person, $client, $scope, $strategy);

$this->assertInstanceOf(Authorization::class, $authorization);
$this->assertContains('new', $authorization->getScope());
$this->assertContains('old', $authorization->getScope());
}

public function testMergeFailsWithInvalidStrategy()
{
$this->expectException(\InvalidArgumentException::class);

$person = new Person();
$client = new Client();
$scope = ['new'];
$strategy = 'invalid';

/** @var EntityManagerInterface|MockObject $em */
$em = $this->createMock(EntityManagerInterface::class);
$em->expects($this->never())->method('flush');

/** @var AuthorizationRepository|MockObject $repo */
$repo = $this->createMock(AuthorizationRepository::class);

$manager = new AuthorizationManager($em, $repo);
$authorization = $manager->enforceAuthorization($person, $client, $scope, $strategy);

$this->assertInstanceOf(Authorization::class, $authorization);
$this->assertContains('new', $authorization->getScope());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use LoginCidadao\APIBundle\Controller\BaseController;
use LoginCidadao\CoreBundle\Entity\Authorization;
use LoginCidadao\CoreBundle\Entity\AuthorizationRepository;
use LoginCidadao\CoreBundle\Service\AuthorizationManager;
use LoginCidadao\OAuthBundle\Model\ClientInterface;
use LoginCidadao\RemoteClaimsBundle\Model\ClaimProviderInterface;
use LoginCidadao\RemoteClaimsBundle\Model\RemoteClaimAuthorizationInterface;
Expand Down Expand Up @@ -54,20 +55,22 @@ public function validateRemoteClaimAction(Request $request)
$person = $remoteClaimAuthorization->getPerson();
$client = $remoteClaimAuthorization->getClient();

/** @var AuthorizationRepository $authorizationRepo */
$authorizationRepo = $this->getDoctrine()->getRepository('LoginCidadaoCoreBundle:Authorization');
/** @var AuthorizationManager $authorizationManager */
$authorizationManager = $this->get('lc.authorization.manager');

/** @var Authorization $authorization */
$authorization = $authorizationRepo->findOneBy([
'client' => $provider,
'person' => $person,
]);
/** @var Authorization|null $authorization */
$authorization = $authorizationManager->getAuthorization($person, $provider);

if ($authorization instanceof Authorization) {
throw $this->createNotFoundException("Authorization not found");
}

/** @var SerializerInterface $serializer */
$serializer = $this->get('jms_serializer');
$personSerializationContext = $this->getJMSSerializationContext($authorization->getScope());
$serializedPerson = $serializer->serialize($person, $format, $personSerializationContext);
$serializedClient = $serializer->serialize($client, $format, $this->getJMSSerializationContext(['remote_claim']));
$serializedClient = $serializer->serialize($client, $format,
$this->getJMSSerializationContext(['remote_claim']));

$response = [
'claim_name' => (string)$remoteClaimAuthorization->getClaimName(),
Expand Down
13 changes: 13 additions & 0 deletions src/LoginCidadao/RemoteClaimsBundle/Entity/RemoteClaim.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ class RemoteClaim implements RemoteClaimInterface
*/
private $provider;

/**
* RemoteClaim constructor.
*/
public function __construct()
{
$this->providerEssentialScope = [];
$this->providerRecommendedScope = [];
}

/**
* @return mixed
*/
Expand Down Expand Up @@ -246,6 +255,10 @@ private function enforceScopeArray($scope)
return $scope;
}

if (trim($scope) === '') {
return [];
}

return explode(' ', $scope);
}
}
Loading

0 comments on commit de6706f

Please sign in to comment.