Completed
Push — release-1.x ( c1f7bf...3be149 )
by Boy
09:15 queued 05:00
created

AuditLogProjector::handle()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
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\Projector;
20
21
use Broadway\Domain\DomainMessage;
22
use Broadway\ReadModel\ProjectorInterface;
23
use DateTime as CoreDateTime;
24
use Rhumsaa\Uuid\Uuid;
25
use Surfnet\Stepup\DateTime\DateTime;
26
use Surfnet\Stepup\Identity\Event\AuditableEvent;
27
use Surfnet\Stepup\Identity\Event\IdentityForgottenEvent;
28
use Surfnet\Stepup\Identity\Value\CommonName;
29
use Surfnet\StepupMiddleware\ApiBundle\Exception\RuntimeException;
30
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\AuditLogEntry;
31
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\AuditLogRepository;
32
use Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\IdentityRepository;
33
34
class AuditLogProjector implements ProjectorInterface
35
{
36
    /**
37
     * @var \Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\AuditLogRepository
38
     */
39
    private $auditLogRepository;
40
41
    /**
42
     * @var \Surfnet\StepupMiddleware\ApiBundle\Identity\Repository\IdentityRepository
43
     */
44
    private $identityRepository;
45
46
    public function __construct(
47
        AuditLogRepository $auditLogRepository,
48
        IdentityRepository $identityRepository
49
    ) {
50
        $this->auditLogRepository = $auditLogRepository;
51
        $this->identityRepository = $identityRepository;
52
    }
53
54
    /**
55
     * @param DomainMessage $domainMessage
56
     */
57
    public function handle(DomainMessage $domainMessage)
58
    {
59
        $event = $domainMessage->getPayload();
60
61
        if ($event instanceof IdentityForgottenEvent) {
62
            // Don't insert the IdentityForgottenEvent into the audit log, as we'd remove it immediately afterwards.
63
            $this->applyIdentityForgottenEvent($event);
64
        } elseif ($event instanceof AuditableEvent) {
65
            $this->applyAuditableEvent($event, $domainMessage);
66
        }
67
    }
68
69
    /**
70
     * @param AuditableEvent $event
71
     * @param DomainMessage  $domainMessage
72
     */
73
    private function applyAuditableEvent(AuditableEvent $event, DomainMessage $domainMessage)
74
    {
75
        $auditLogMetadata = $event->getAuditLogMetadata();
76
        $metadata = $domainMessage->getMetadata()->serialize();
77
78
        $entry = new AuditLogEntry();
79
        $entry->id = (string) Uuid::uuid4();
80
81
        if (isset($metadata['actorId'])) {
82
            $actor = $this->identityRepository->find($metadata['actorId']);
83
84
            if (!$actor) {
85
                throw new RuntimeException(sprintf(
86
                    'Cannot create AuditLogEntry, given Actor Identity "%s" does not exist',
87
                    $metadata['actorId']
88
                ));
89
            }
90
91
            $entry->actorId         = $metadata['actorId'];
92
            $entry->actorCommonName = $actor->commonName;
93
        }
94
95
        if (isset($metadata['actorInstitution'])) {
96
            $entry->actorInstitution = $metadata['actorInstitution'];
97
        }
98
99
        $entry->identityId          = (string) $auditLogMetadata->identityId;
100
        $entry->identityInstitution = $auditLogMetadata->identityInstitution;
101
        $entry->event               = get_class($event);
102
        $entry->recordedOn          = new DateTime(new CoreDateTime($domainMessage->getRecordedOn()->toString()));
103
104
        if ($auditLogMetadata->secondFactorId) {
105
            $entry->secondFactorId = (string) $auditLogMetadata->secondFactorId;
106
        }
107
108
        if ($auditLogMetadata->secondFactorType) {
109
            $entry->secondFactorType = (string) $auditLogMetadata->secondFactorType;
110
        }
111
112
        if ($auditLogMetadata->secondFactorIdentifier) {
113
            $entry->secondFactorIdentifier = (string) $auditLogMetadata->secondFactorIdentifier;
114
        }
115
116
        $this->auditLogRepository->save($entry);
117
    }
118
119
    private function applyIdentityForgottenEvent(IdentityForgottenEvent $event)
120
    {
121
        $entriesWhereActor = $this->auditLogRepository->findEntriesWhereIdentityIsActorOnly($event->identityId);
122
        foreach ($entriesWhereActor as $auditLogEntry) {
123
            $auditLogEntry->actorCommonName = CommonName::unknown();
124
        }
125
126
        $this->auditLogRepository->saveAll($entriesWhereActor);
127
        $this->auditLogRepository->removeByIdentityId($event->identityId);
128
    }
129
}
130