Completed
Push — master ( 93bf3b...7b62ab )
by Michiel
06:06 queued 03:58
created

RaCandidateRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupMiddleware\ApiBundle\Identity\Repository;
20
21
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
22
use Doctrine\Common\Persistence\ManagerRegistry;
23
use Doctrine\ORM\Query\Expr\Join;
24
use Surfnet\StepupMiddleware\ApiBundle\Authorization\Filter\InstitutionAuthorizationRepositoryFilter;
25
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Entity\InstitutionAuthorization;
26
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\Identity;
27
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaCandidate;
28
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaListing;
29
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\VettedSecondFactor;
30
use Surfnet\StepupMiddleware\ApiBundle\Identity\Query\RaCandidateQuery;
31
32
/**
33
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
34
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
35
 */
36
class RaCandidateRepository extends ServiceEntityRepository
37
{
38
    /**
39
     * @var InstitutionAuthorizationRepositoryFilter
40
     */
41
    private $authorizationRepositoryFilter;
42
43
    public function __construct(ManagerRegistry $registry, InstitutionAuthorizationRepositoryFilter $authorizationRepositoryFilter)
44
    {
45
        parent::__construct($registry, RaCandidate::class);
46
        $this->authorizationRepositoryFilter = $authorizationRepositoryFilter;
47
    }
48
49
    /**
50
     * @param RaCandidateQuery $query
51
     * @return \Doctrine\ORM\Query
52
     */
53
    public function createSearchQuery(RaCandidateQuery $query)
54
    {
55
        $queryBuilder = $this->getBaseQuery();
56
57
        // Modify query to filter on authorization:
58
        // For the RA candidates we want the identities that we could make RA. Because we then need to look at the
59
        // select_raa's we have to look at the institution of the candidate because that's the institution we could
60
        // select RA's from. Hence the 'rac.institution'.
61
        $this->authorizationRepositoryFilter->filter(
62
            $queryBuilder,
63
            $query->authorizationContext,
64
            'i.institution',
65
            'iac'
66
        );
67
68
        if ($query->institution) {
69
            $queryBuilder
70
                ->andWhere('i.institution = :institution')
71
                ->setParameter('institution', $query->institution);
72
        }
73
74
        if ($query->commonName) {
75
            $queryBuilder
76
                ->andWhere('i.commonName LIKE :commonName')
77
                ->setParameter('commonName', sprintf('%%%s%%', $query->commonName));
78
        }
79
80
        if ($query->email) {
81
            $queryBuilder
82
                ->andWhere('i.email LIKE :email')
83
                ->setParameter('email', sprintf('%%%s%%', $query->email));
84
        }
85
86
        if (!empty($query->secondFactorTypes)) {
87
            $queryBuilder
88
                ->andWhere('vsf.type IN (:secondFactorTypes)')
89
                ->setParameter('secondFactorTypes', $query->secondFactorTypes);
90
        }
91
92
        if (!empty($query->raInstitution)) {
93
            $queryBuilder
94
                ->andWhere('a.raInstitution = :raInstitution')
95
                ->setParameter('raInstitution', $query->raInstitution);
96
        }
97
98
        $queryBuilder->groupBy('i.id');
99
100
        return $queryBuilder->getQuery();
101
    }
102
103
    /**
104
     * @param RaCandidateQuery $query
105
     * @return \Doctrine\ORM\Query
106
     */
107
    public function createOptionsQuery(RaCandidateQuery $query)
108
    {
109
        $queryBuilder = $this->getEntityManager()->createQueryBuilder()
110
            ->select('a.institution')
111
            ->from(InstitutionAuthorization::class, 'a')
112
            ->where("a.institutionRole = 'select_raa'");
113
114
        // Modify query to filter on authorization:
115
        // For the RA candidates we want the identities that we could make RA. Because we then need to look at the
116
        // select_raa's we have to look at the institution of the candidate because that's the institution we could
117
        // select RA's from. Hence the 'rac.institution'.
118
        $this->authorizationRepositoryFilter->filter(
119
            $queryBuilder,
120
            $query->authorizationContext,
121
            'a.institution',
122
            'iac'
123
        );
124
125
        return $queryBuilder->getQuery();
126
    }
127
128
    /**
129
     * @return array|null
130
     */
131
    public function findOneByIdentityId(string $identityId)
132
    {
133
        // Finds a single identity by its identity id. Returns the identity as an array
134
        $queryBuilder = $this->getBaseQuery()
135
            ->andWhere('i.id = :identityId')
136
            ->setParameter('identityId', $identityId)
137
            ->groupBy('i.id')
138
            ->orderBy('a.institution');
139
140
        return $queryBuilder->getQuery()->getOneOrNullResult();
141
    }
142
143
    /**
144
     * @return \Doctrine\ORM\QueryBuilder
145
     */
146
    private function getBaseQuery()
147
    {
148
        // Base query to get all allowed ra candidates
149
        $queryBuilder = $this->getEntityManager()->createQueryBuilder()
150
            ->select('i.id as identity_id, i.institution, i.commonName as common_name, i.email, i.nameId AS name_id, a.institution AS ra_institution')
151
            ->from(VettedSecondFactor::class, 'vsf')
152
            ->innerJoin(Identity::class, 'i', Join::WITH, "vsf.identityId = i.id")
153
            ->innerJoin(
154
                InstitutionAuthorization::class,
155
                'a',
156
                Join::WITH,
157
                "a.institutionRole = 'select_raa' AND a.institutionRelation = i.institution"
158
            );
159
160
        // Filter out candidates who are already ra
161
        // Todo: filter out SRAA's ?
162
        $subQuery = $this->getEntityManager()->createQueryBuilder()
163
            ->select('l')
164
            ->from(RaListing::class, "l")
165
            ->where("l.identityId = i.id AND l.raInstitution = a.institution");
166
167
        $queryBuilder->andWhere($queryBuilder->expr()->not($queryBuilder->expr()->exists($subQuery->getDQL())));
168
169
        return $queryBuilder;
170
    }
171
}
172