Completed
Push — feature/use-ra-candidate-view ( 70df3f...fdc88b )
by
unknown
02:07
created

RaCandidateRepository::getBaseQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
cc 1
nc 1
nop 0
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\ORM\EntityManager;
22
use Doctrine\ORM\EntityRepository;
23
use Doctrine\ORM\Mapping;
24
use Doctrine\ORM\Query\Expr\Join;
25
use Surfnet\StepupMiddleware\ApiBundle\Authorization\Filter\InstitutionAuthorizationRepositoryFilter;
26
use Surfnet\StepupMiddleware\ApiBundle\Authorization\Value\InstitutionAuthorizationContextInterface;
27
use Surfnet\StepupMiddleware\ApiBundle\Configuration\Entity\InstitutionAuthorization;
28
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\Identity;
29
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaCandidate;
30
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaListing;
31
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\VettedSecondFactor;
32
use Surfnet\StepupMiddleware\ApiBundle\Identity\Query\RaCandidateQuery;
33
34
/**
35
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
36
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
37
 */
38
class RaCandidateRepository extends EntityRepository
39
{
40
    /**
41
     * @var InstitutionAuthorizationRepositoryFilter
42
     */
43
    private $authorizationRepositoryFilter;
44
45
    public function __construct(
46
        EntityManager $em,
47
        Mapping\ClassMetadata $class,
48
        InstitutionAuthorizationRepositoryFilter $authorizationRepositoryFilter
49
    ) {
50
        parent::__construct($em, $class);
51
        $this->authorizationRepositoryFilter = $authorizationRepositoryFilter;
52
    }
53
54
    /**
55
     * @param RaCandidateQuery $query
56
     * @return \Doctrine\ORM\Query
57
     */
58
    public function createSearchQuery(RaCandidateQuery $query)
59
    {
60
        $queryBuilder = $this->getBaseQuery();
61
62
        // Modify query to filter on authorization:
63
        // For the RA candidates we want the identities that we could make RA. Because we then need to look at the
64
        // select_raa's we have to look at the institution of the candidate because that's the institution we could
65
        // select RA's from. Hence the 'rac.institution'.
66
        $this->authorizationRepositoryFilter->filter(
67
            $queryBuilder,
68
            $query->authorizationContext,
69
            'i.institution',
70
            'iac'
71
        );
72
73
        if ($query->institution) {
74
            $queryBuilder
75
                ->andWhere('i.institution = :institution')
76
                ->setParameter('institution', $query->institution);
77
        }
78
79
        if ($query->commonName) {
80
            $queryBuilder
81
                ->andWhere('i.commonName LIKE :commonName')
82
                ->setParameter('commonName', sprintf('%%%s%%', $query->commonName));
83
        }
84
85
        if ($query->email) {
86
            $queryBuilder
87
                ->andWhere('i.email LIKE :email')
88
                ->setParameter('email', sprintf('%%%s%%', $query->email));
89
        }
90
91
        if (!empty($query->secondFactorTypes)) {
92
            $queryBuilder
93
                ->andWhere('vsf.type IN (:secondFactorTypes)')
94
                ->setParameter('secondFactorTypes', $query->secondFactorTypes);
95
        }
96
97
        if (!empty($query->raInstitution)) {
98
            $queryBuilder
99
                ->andWhere('a.raInstitution = :raInstitution')
100
                ->setParameter('raInstitution', $query->raInstitution);
101
        }
102
103
        $queryBuilder->groupBy('i.id');
104
105
        return $queryBuilder->getQuery();
106
    }
107
108
    /**
109
     * @param RaCandidateQuery $query
110
     * @return \Doctrine\ORM\Query
111
     */
112
    public function createOptionsQuery(RaCandidateQuery $query)
113
    {
114
        $queryBuilder = $this->getEntityManager()->createQueryBuilder()
115
            ->select('a.institution')
116
            ->from(InstitutionAuthorization::class, 'a')
117
            ->where("a.institutionRole = 'select_raa'");
118
119
        // Modify query to filter on authorization:
120
        // For the RA candidates we want the identities that we could make RA. Because we then need to look at the
121
        // select_raa's we have to look at the institution of the candidate because that's the institution we could
122
        // select RA's from. Hence the 'rac.institution'.
123
        $this->authorizationRepositoryFilter->filter(
124
            $queryBuilder,
125
            $query->authorizationContext,
126
            'a.institution',
127
            'iac'
128
        );
129
130
        return $queryBuilder->getQuery();
131
    }
132
133
    /**
134
     * @param string $identityId
135
     * @param InstitutionAuthorizationContextInterface $authorizationContext
136
     * @return RaCandidate[]
137
     */
138
    public function findAllRaasByIdentityId($identityId, InstitutionAuthorizationContextInterface $authorizationContext)
139
    {
140
        $queryBuilder = $this->getBaseQuery()
141
            ->andWhere('i.id = :identityId')
142
            ->setParameter('identityId', $identityId)
143
            ->orderBy('a.institution');
144
145
        // Modify query to filter on authorization:
146
        // For the RA candidates we want the identities that we could make RA. Because we then need to look at the
147
        // select_raa's we have to look at the institution of the candidate because that's the institution we could
148
        // select RA's from. Hence the 'rac.institution'.
149
        $this->authorizationRepositoryFilter->filter(
150
            $queryBuilder,
151
            $authorizationContext,
152
            'i.institution',
153
            'iac'
154
        );
155
156
        return $queryBuilder->getQuery()->getResult();
157
    }
158
159
    /**
160
     * @return \Doctrine\ORM\QueryBuilder
161
     */
162
    private function getBaseQuery()
163
    {
164
        // Base query to get all allowed ra candidates
165
        $queryBuilder = $this->getEntityManager()->createQueryBuilder()
166
            ->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')
167
            ->from(VettedSecondFactor::class, 'vsf')
168
            ->innerJoin(Identity::class, 'i', Join::WITH, "vsf.identityId = i.id")
169
            ->innerJoin(
170
                InstitutionAuthorization::class,
171
                'a',
172
                Join::WITH,
173
                "a.institutionRole = 'select_raa' AND a.institutionRelation = i.institution"
174
            );
175
176
        // Filter out candidates who are already ra
177
        // Todo: filter out SRAA's ?
178
        $subQuery = $this->getEntityManager()->createQueryBuilder()
179
            ->select('l')
180
            ->from(RaListing::class, "l")
181
            ->where("l.identityId = i.id AND l.raInstitution = a.institution");
182
183
        $queryBuilder->andWhere($queryBuilder->expr()->not($queryBuilder->expr()->exists($subQuery->getDQL())));
184
185
        return $queryBuilder;
186
    }
187
}
188