Browse Source

Merge branch 'feature/BTTF-22' into develop

Vincent GUFFON 4 years ago
parent
commit
92f991d7a6

+ 27 - 0
src/ApiResources/Profile/AccessProfile.php

@@ -5,6 +5,9 @@ namespace App\ApiResources\Profile;
 
 use ApiPlatform\Core\Annotation\ApiProperty;
 use ApiPlatform\Core\Annotation\ApiResource;
+use App\Entity\Access\Access;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
 
 /**
  * Classe resource qui contient les champs disponibles lors d'un appel à my_profile.
@@ -30,9 +33,11 @@ class AccessProfile
     private $givenName;
     private $roles = [];
     private $organization;
+    private $accesses;
 
     public function __construct()
     {
+        $this->accesses = new ArrayCollection();
     }
 
     public function getId(): ?int
@@ -107,4 +112,26 @@ class AccessProfile
         $this->roles = $roles;
         return $this;
     }
+
+    /**
+     * @return Collection|AccessProfile[]
+     */
+    public function getAccesses(): Collection
+    {
+        return $this->accesses;
+    }
+
+    public function addAccess(AccessProfile $accessProfile): self
+    {
+        if (!$this->accesses->contains($accessProfile)) {
+            $this->accesses[] = $accessProfile;
+        }
+        return $this;
+    }
+
+    public function removeAccess(AccessProfile $accessProfile): self
+    {
+        $this->accesses->removeElement($accessProfile);
+        return $this;
+    }
 }

+ 3 - 0
src/Entity/Network/NetworkOrganization.php

@@ -6,6 +6,7 @@ namespace App\Entity\Network;
 use ApiPlatform\Core\Annotation\ApiResource;
 use App\Entity\Organization\Organization;
 use App\Repository\Network\NetworkOrganizationRepository;
+use App\Entity\Traits\ActivityPeriodTrait;
 use Doctrine\ORM\Mapping as ORM;
 
 /**
@@ -15,6 +16,8 @@ use Doctrine\ORM\Mapping as ORM;
  */
 class NetworkOrganization
 {
+    use ActivityPeriodTrait;
+
     /**
      * @ORM\Id
      * @ORM\GeneratedValue

+ 25 - 0
src/Entity/Person/Person.php

@@ -6,6 +6,7 @@ namespace App\Entity\Person;
 use ApiPlatform\Core\Annotation\ApiResource;
 use App\Entity\Core\ContactPoint;
 use App\Repository\Person\PersonRepository;
+use AppBundle\Entity\AccessAndFunction\Access;
 use Doctrine\Common\Collections\ArrayCollection;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\ORM\Mapping as ORM;
@@ -57,6 +58,12 @@ class Person implements UserInterface
      */
     private $contactPoints;
 
+    /**
+     * @ORM\Column(type="integer", nullable=true)
+     * @var int
+     */
+    private $accessFavorite;
+
 
     public function __construct()
     {
@@ -196,4 +203,22 @@ class Person implements UserInterface
 
         return $this;
     }
+
+    /**
+     * @return int
+     */
+    public function getAccessFavorite() : int
+    {
+        return $this->accessFavorite;
+    }
+
+    /**
+     * @param $accessFavorite
+     * @return $this
+     */
+    public function setAccessFavorite($accessFavorite) : self
+    {
+        $this->accessFavorite = $accessFavorite;
+        return $this;
+    }
 }

+ 66 - 0
src/Entity/Traits/ActivityPeriodTrait.php

@@ -0,0 +1,66 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Traits;
+
+use Doctrine\ORM\Mapping as ORM;
+use Symfony\Component\Validator\Constraints as Assert;
+
+trait ActivityPeriodTrait
+{
+    /**
+     * @var \DateTime
+     *
+     * @ORM\Column(type="date", nullable=true)
+     * @Assert\Date
+     */
+    private $startDate;
+
+    /**
+     * @var \DateTime
+     *
+     * @ORM\Column(type="date", nullable=true)
+     * @Assert\Date
+     */
+    private $endDate;
+
+    /**
+     * Gets start date
+     *
+     * @return \DateTime
+     */
+    public function getStartDate(): string {
+        return $this->startDate ? $this->startDate->format('Y-m-d') : '';
+    }
+
+    /**
+     * @param \DateTime|null $startDate
+     * @return $this
+     * @throws \Exception
+     */
+    public function setStartDate(\DateTime $startDate = null): self {
+        if($startDate == null) $startDate = new \DateTime();
+        $this->startDate = $startDate;
+        return $this;
+    }
+
+    /**
+     * Gets end date
+     *
+     * @return \DateTime
+     */
+    public function getEndDate(): string {
+        return $this->endDate ? $this->endDate->format('Y-m-d') : '';
+    }
+
+    /**
+     * Sets end date
+     *
+     * @param \DateTime $endDate
+     * @return $this
+     */
+    public function setEndDate(\DateTime $endDate = null) :self {
+        $this->endDate = $endDate;
+        return $this;
+    }
+}

+ 64 - 0
src/Entity/Traits/ActivityYearTrait.php

@@ -0,0 +1,64 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Entity\Traits;
+
+use Doctrine\ORM\Mapping as ORM;
+
+trait ActivityYearTrait
+{
+    /**
+     * @var int
+     *
+     * @ORM\Column(type="integer", nullable=true)
+     */
+    private $startYear;
+
+    /**
+     * @var int
+     *
+     * @ORM\Column(type="integer", nullable=true)
+     */
+    private $endYear;
+    
+    /**
+     * Gets start year
+     * 
+     * @return int
+     */
+    public function getStartYear(): int {
+        return $this->startYear;
+    }
+    
+    /**
+     * Sets start year
+     * 
+     * @param int $startYear
+     * @return $this
+     */
+    public function setStartYear($startYear = null):self {
+        if($startYear == null) $startYear = date('Y');
+        $this->startYear = $startYear;
+        return $this;
+    }
+
+    /**
+     * Gets end year
+     *
+     * @return int
+     */
+    public function getEndYear():int {
+        return $this->endYear;
+    }
+
+    /**
+     * Sets end year
+     *
+     * @param int $endYear
+     * @return $this
+     */
+    public function setEndYear($endYear):self {
+        $this->endYear = $endYear;
+        return $this;
+    }
+}

+ 18 - 26
src/Repository/Access/AccessRepository.php

@@ -8,7 +8,6 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
 use Doctrine\Persistence\ManagerRegistry;
 use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
 use Symfony\Component\HttpFoundation\RequestStack;
-use Symfony\Component\Security\Core\User\UserInterface;
 
 /**
  * @method Access|null find($id, $lockMode = null, $lockVersion = null)
@@ -17,7 +16,7 @@ use Symfony\Component\Security\Core\User\UserInterface;
  * @method Access[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  * @method null loadUserByIdentifier(string $identifier)
  */
-final class AccessRepository extends ServiceEntityRepository implements UserLoaderInterface
+class AccessRepository extends ServiceEntityRepository implements UserLoaderInterface
 {
     const ACCESS_NAME_HEADER = 'X-AccessId';
 
@@ -52,32 +51,25 @@ final class AccessRepository extends ServiceEntityRepository implements UserLoad
             ->getOneOrNullResult();
     }
 
-    // /**
-    //  * @return Access[] Returns an array of Access objects
-    //  */
-    /*
-    public function findByExampleField($value)
+    /**
+     * @param Access $acces
+     * @return mixed
+     * @throws \Exception
+     */
+    public function findAllValidAccesses(Access $acces)
     {
-        return $this->createQueryBuilder('a')
-            ->andWhere('a.exampleField = :val')
-            ->setParameter('val', $value)
-            ->orderBy('a.id', 'ASC')
-            ->setMaxResults(10)
-            ->getQuery()
-            ->getResult()
-        ;
-    }
-    */
+        $datetime = new \DateTime();
+        $today = $datetime->format('Y-m-d');
 
-    /*
-    public function findOneBySomeField($value): ?Access
-    {
-        return $this->createQueryBuilder('a')
-            ->andWhere('a.exampleField = :val')
-            ->setParameter('val', $value)
+        return $this->createQueryBuilder('access')
+            ->innerJoin('access.organization', 'organization')
+            ->innerJoin('organization.networkOrganizations', 'networkOrganizations')
+            ->where('access.person = :person')
+            ->andWhere('networkOrganizations.startDate <= :today')
+            ->setParameter('person', $acces->getPerson())
+            ->setParameter('today', $today)
             ->getQuery()
-            ->getOneOrNullResult()
-        ;
+            ->getResult()
+      ;
     }
-    */
 }

+ 49 - 5
src/Service/Access/AccessProfileCreator.php

@@ -5,7 +5,10 @@ namespace App\Service\Access;
 
 use App\ApiResources\Profile\AccessProfile;
 use App\Entity\Access\Access;
+use App\Repository\Access\AccessRepository;
 use App\Service\Organization\OrganizationProfileCreator;
+use App\Test\Service\Access\AccessProfileCreatorTest;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
 use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
 
 /**
@@ -16,32 +19,73 @@ class AccessProfileCreator
 {
     private RoleHierarchyInterface $roleHierarchy;
     private OrganizationProfileCreator $organizationProfileCreator;
+    private AccessRepository $accessRepository;
+    private Utils $accessUtils;
 
     public function __construct(
         RoleHierarchyInterface $roleHierarchy,
-        OrganizationProfileCreator $organizationProfileCreator
+        OrganizationProfileCreator $organizationProfileCreator,
+        AccessRepository $accessRepository,
+        Utils $accessUtils
     )
     {
         $this->roleHierarchy = $roleHierarchy;
         $this->organizationProfileCreator = $organizationProfileCreator;
+        $this->accessRepository = $accessRepository;
+        $this->accessUtils = $accessUtils;
     }
 
     /**
-     * Créer une ressource AccessProfile à partir d'une entité Access
+     * On récupère l'accessProfile complet correspondant à l'Access
      * @param Access $access
      * @return AccessProfile
-     * @see AccessProfileCreatorTest::testGetAccessProfile()
+     * @throws \Exception
+     * @see AccessProfileCreatorTest::testGetAccessProfileFailed
      */
     public function getAccessProfile(Access $access): AccessProfile{
+        $validAccesses = $this->accessRepository->findAllValidAccesses($access);
+        if(empty($validAccesses))
+            throw new AuthenticationException('no_valid_access', 401);
+
+        //L'Access en paramètre est celui de la connexion
+        $mainAccessProfile = $this->createAccessProfile($access);
+
+        //On remplit les autres Accesses (multi comptes)
+        $otherAccesses = $this->accessUtils->filterAccesses($validAccesses, $access);
+        foreach ($otherAccesses as $otherAccess){
+            $mainAccessProfile->addAccess($this->createLightAccessProfile($otherAccess));
+        }
+
+        return $mainAccessProfile;
+    }
+
+    /**
+     * Créer une ressource AccessProfile à partir d'une entité Access
+     * @param Access $access
+     * @return AccessProfile
+     * @see AccessProfileCreatorTest::testCreateAccessProfile
+     */
+    public function createAccessProfile(Access $access): AccessProfile{
         $accessProfile = new AccessProfile();
-        $accessProfile
+        return $accessProfile
             ->setId($access->getId())
             ->setIsAdminAccess($access->getAdminAccess())
             ->setName($access->getPerson()->getName())
             ->setGivenName($access->getPerson()->getGivenName())
             ->setRoles($this->roleHierarchy->getReachableRoleNames($access->getRoles()))
             ->setOrganization($this->organizationProfileCreator->getOrganizationProfile($access->getOrganization()));
+    }
 
-        return $accessProfile;
+    /**
+     * Classe permettant de créer et Setter les éléments de base d'une ressource AccessProfile à partir d'une entité Access
+     * @param Access $access
+     * @return AccessProfile
+     * @see AccessProfileCreatorTest::testCreateLightAccessProfile()
+     */
+    public function createLightAccessProfile(Access $access): AccessProfile{
+        $accessProfile = new AccessProfile();
+        return $accessProfile
+            ->setId($access->getId())
+            ->setOrganization($this->organizationProfileCreator->setCommonElements($access->getOrganization()));
     }
 }

+ 32 - 0
src/Service/Access/Utils.php

@@ -0,0 +1,32 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Service\Access;
+
+use App\Entity\Access\Access;
+use App\Test\Service\Access\UtilsTest;
+
+/**
+ * Class Utils : service rassemblant des fonctions d'aides pour les questions se rapportant à l'access
+ * @package App\Service\Resource
+ */
+class Utils
+{
+    public function __construct()
+    {
+    }
+
+    /**
+     * Filtre un tableau d'Access pour ne laisser que les Accesses ne correspondant pas à l'Access passé en second parametre
+     * @param array<Access> $accesses
+     * @param Access $access
+     * @return array
+     * @see UtilsTest::testFilterAccesses()
+     */
+    public function filterAccesses(array $accesses, Access $access): array {
+        return array_filter($accesses, function($a) use($access){
+            /** @var Access $a */
+            return $a->getId() !== $access->getId();
+        });
+    }
+}

+ 1 - 1
src/Service/Organization/OrganizationProfileCreator.php

@@ -56,7 +56,7 @@ class OrganizationProfileCreator
      * @param Organization $organization
      * @return OrganizationProfile
      */
-    private function setCommonElements(Organization $organization): OrganizationProfile{
+    public function setCommonElements(Organization $organization): OrganizationProfile{
         $organizationProfile = new OrganizationProfile();
         $organizationProfile
             ->setId($organization->getId())

+ 46 - 13
tests/Service/Access/AccessProfileCreatorTest.php

@@ -6,20 +6,25 @@ use App\ApiResources\Profile\OrganizationProfile;
 use App\Entity\Access\Access;
 use App\Entity\Organization\Organization;
 use App\Entity\Person\Person;
+use App\Repository\Access\AccessRepository;
 use App\Service\Access\AccessProfileCreator;
+use App\Service\Access\Utils;
 use App\Service\Organization\OrganizationProfileCreator;
 use PHPUnit\Framework\TestCase;
+use Symfony\Component\Security\Core\Exception\AuthenticationException;
 use Symfony\Component\Security\Core\Role\RoleHierarchy;
 
 class AccessProfileCreatorTest extends TestCase
 {
     private Access  $access;
-    private Person $person;
+    private $accessProfileCreator;
+    private $accessRepositoryMock;
+    private $accessUtilsMock;
 
     public function setUp():void
     {
-        $this->person = new Person();
-        $this->person
+        $person = new Person();
+        $person
             ->setName('Foo')
             ->setGivenName('Bar')
         ;
@@ -27,29 +32,57 @@ class AccessProfileCreatorTest extends TestCase
         $this->access = new Access();
         $this->access
             ->setAdminAccess(true)
-            ->setPerson($this->person)
+            ->setPerson($person)
             ->setOrganization(new Organization())
         ;
-    }
 
-    /**
-     * @see AccessProfileCreator::getAccessProfile()
-     */
-    public function testGetAccessProfile(){
         $roleHierarchyMock = $this->getMockBuilder(RoleHierarchy::class)->disableOriginalConstructor()->getMock();
         $roleHierarchyMock
             ->method('getReachableRoleNames')
             ->willReturn(["ROLE_A", "ROLE_B"]);
 
-        $organizationProfileCreator = $this->getMockBuilder(OrganizationProfileCreator::class)->disableOriginalConstructor()->getMock();
-        $organizationProfileCreator
+        $organizationProfileCreatorMock = $this->getMockBuilder(OrganizationProfileCreator::class)->disableOriginalConstructor()->getMock();
+        $organizationProfileCreatorMock
             ->method('getOrganizationProfile')
             ->with($this->access->getOrganization())
             ->willReturn(new OrganizationProfile());
 
-        $accessProfileCreator = new AccessProfileCreator($roleHierarchyMock,$organizationProfileCreator);
-        $accessProfile = $accessProfileCreator->getAccessProfile($this->access);
+        $this->accessRepositoryMock = $this->getMockBuilder(AccessRepository::class)->disableOriginalConstructor()->getMock();
+        $this->accessUtilsMock = $this->getMockBuilder(Utils::class)->disableOriginalConstructor()->getMock();
+
+        $this->accessProfileCreator = new AccessProfileCreator(
+            $roleHierarchyMock,
+            $organizationProfileCreatorMock,
+            $this->accessRepositoryMock,
+            $this->accessUtilsMock
+        );
+    }
+
+    /**
+     * @see AccessProfileCreator::getAccessProfile()
+     */
+    public function testGetAccessProfileFailed(){
+        $this->accessRepositoryMock
+            ->method('findAllValidAccesses')
+            ->with($this->access)
+            ->willReturn([]);
+        $this->expectException(AuthenticationException::class);
+        $this->accessProfileCreator->getAccessProfile($this->access);
+    }
+
+    /**
+     * @see AccessProfileCreator::createAccessProfile()
+     */
+    public function testCreateAccessProfile(){
+        $accessProfile = $this->accessProfileCreator->createAccessProfile($this->access);
+        $this->assertInstanceOf(AccessProfile::class, $accessProfile);
+    }
 
+    /**
+     * @see AccessProfileCreator::createLightAccessProfile()
+     */
+    public function testCreateLightAccessProfile(){
+        $accessProfile = $this->accessProfileCreator->createLightAccessProfile($this->access);
         $this->assertInstanceOf(AccessProfile::class, $accessProfile);
     }
 }

+ 40 - 0
tests/Service/Access/UtilsTest.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Test\Service\Access;
+
+use App\Entity\Access\Access;
+use App\Service\Access\Utils;
+use PHPUnit\Framework\TestCase;
+
+class UtilsTest extends TestCase
+{
+
+    public function setUp():void
+    {
+
+    }
+
+    /**
+     * @see Utils::filterAccesses()
+     */
+    public function testFilterAccesses(){
+        $accessMock1 = $this->getMockBuilder(Access::class)->disableOriginalConstructor()->getMock();
+        $accessMock1
+            ->method('getId')
+            ->willReturn(1);
+        $accessesMock[] = $accessMock1;
+        $accessMock2 = $this->getMockBuilder(Access::class)->disableOriginalConstructor()->getMock();
+        $accessMock2
+            ->method('getId')
+            ->willReturn(2);
+        $accessesMock[] = $accessMock2;
+        $accessMock3 = $this->getMockBuilder(Access::class)->disableOriginalConstructor()->getMock();
+        $accessMock3
+            ->method('getId')
+            ->willReturn(3);
+        $accessesMock[] = $accessMock3;
+
+        $utils = new Utils();
+        $this->assertCount(2, $utils->filterAccesses($accessesMock, $accessMock2));
+    }
+}