Passed
Push — master ( c4afc2...9cde23 )
by Pieter van der
27:49 queued 12:42
created

ActivationFlowService::process()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 36
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 26
nc 6
nop 1
dl 0
loc 36
rs 9.504
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright 2022 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\StepupSelfService\SelfServiceBundle\Service;
20
21
use Psr\Log\LoggerInterface;
22
use Surfnet\StepupSelfService\SelfServiceBundle\Value\ActivationFlowPreference;
23
use Surfnet\StepupSelfService\SelfServiceBundle\Value\ActivationFlowPreferenceInterface;
24
use Surfnet\StepupSelfService\SelfServiceBundle\Value\ActivationFlowPreferenceNotExpressed;
25
use Symfony\Component\HttpFoundation\Session\SessionInterface;
26
use function sprintf;
27
28
class ActivationFlowService
29
{
30
    private const ACTIVATION_FLOW_PREFERENCE_SESSION_NAME = 'self_service_activation_flow_preference';
31
    /**
32
     * @var string
33
     */
34
    private $fieldName;
35
36
    /**
37
     * @var array
38
     */
39
    private $options;
40
41
    /**
42
     * @var SessionInterface
43
     */
44
    private $session;
45
46
    /**
47
     * @var LoggerInterface
48
     */
49
    private $logger;
50
51
    /**
52
     * Handle preferred activation flow logic
53
     *
54
     * 1. On the / path, the preferred activation flow can be set using the configured
55
     *    query string field. This field can have an option indicating the preferred flow.
56
     *    This is stored in session.
57
     * 2. If this preference was set, the list of available options is limited to just that
58
     *    option.
59
     * 3. The option can be reset by the Identity, removing it from session.
60
     *
61
     * Note that:
62
     * - fieldName and options are configured in the SelfServiceExtension
63
     */
64
    public function __construct(SessionInterface $session, LoggerInterface $logger, string $fieldName, array $options)
65
    {
66
        $this->session = $session;
67
        $this->logger = $logger;
68
        $this->fieldName = $fieldName;
69
        $this->options = $options;
70
    }
71
72
73
    public function process(string $uri): void
74
    {
75
        $this->logger->info(sprintf('Analysing uri "%s" for activation flow query parameter', $uri));
76
        $parts = parse_url($uri);
77
        $parameters = [];
78
        if (array_key_exists('query', $parts)) {
79
            $this->logger->debug('Found a query string in the uri');
80
            parse_str($parts['query'], $parameters);
81
        }
82
        // Is the configured field name in the querystring?
83
        if (!array_key_exists($this->fieldName, $parameters)) {
84
            $this->logger->notice(
85
                sprintf(
86
                    'The configured query string field name "%s" was not found in the uri "%s"',
87
                    $this->fieldName,
88
                    $uri
89
                )
90
            );
91
            return;
92
        }
93
        $option = $parameters[$this->fieldName];
94
        if (!in_array($option, $this->options)) {
95
            $this->logger->notice(
96
                sprintf(
97
                    'Field "%s" contained an invalid option "%s", must be one of: %s',
98
                    $this->fieldName,
99
                    $option,
100
                    implode(', ', $this->options)
101
                )
102
            );
103
            return;
104
        }
105
        $this->logger->info('Storing the preference in session');
106
        $this->session->set(
107
            self::ACTIVATION_FLOW_PREFERENCE_SESSION_NAME,
108
            new ActivationFlowPreference($option)
109
        );
110
    }
111
112
    public function hasActivationFlowPreference(): bool
113
    {
114
        return $this->session->has(self::ACTIVATION_FLOW_PREFERENCE_SESSION_NAME);
115
    }
116
117
    public function getPreference(): ActivationFlowPreferenceInterface
118
    {
119
        if (!$this->hasActivationFlowPreference()) {
120
            return new ActivationFlowPreferenceNotExpressed();
121
        }
122
        return $this->session->get(self::ACTIVATION_FLOW_PREFERENCE_SESSION_NAME);
123
    }
124
}
125