Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
SecuritySettingsRepository
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
6 / 6
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findAll
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 persist
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 createSetting
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 isMultilineValueKey
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 extractPersistenceValue
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2020 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\tao\model\security\DataAccess\Repository;
24
25use oat\tao\model\security\Business\Contract\SecuritySettingsRepositoryInterface;
26use oat\tao\model\security\Business\Domain\Setting;
27use oat\tao\model\security\Business\Domain\SettingsCollection;
28use oat\tao\model\service\InjectionAwareService;
29use oat\tao\model\settings\SettingsStorageInterface;
30
31class SecuritySettingsRepository extends InjectionAwareService implements SecuritySettingsRepositoryInterface
32{
33    public const CONTENT_SECURITY_POLICY           = 'cspHeader';
34    public const CONTENT_SECURITY_POLICY_WHITELIST = 'cspHeaderList';
35    public const STRICT_TRANSPORT_SECURITY         = 'tlsHeader';
36
37    private const SETTING_KEYS = [
38        self::CONTENT_SECURITY_POLICY,
39        self::CONTENT_SECURITY_POLICY_WHITELIST,
40        self::STRICT_TRANSPORT_SECURITY,
41    ];
42
43    private const MULTILINE_VALUE_KEYS = [
44        self::CONTENT_SECURITY_POLICY_WHITELIST,
45    ];
46
47    /** @var SettingsStorageInterface */
48    private $storage;
49
50    /** @noinspection MagicMethodsValidityInspection */
51    /** @noinspection PhpMissingParentConstructorInspection */
52    public function __construct(SettingsStorageInterface $storage)
53    {
54        $this->storage = $storage;
55    }
56
57    /**
58     * @inheritDoc
59     */
60    public function findAll(): SettingsCollection
61    {
62        return new SettingsCollection(
63            ...array_map(
64                [$this, 'createSetting'],
65                self::SETTING_KEYS
66            )
67        );
68    }
69
70    /**
71     * @inheritDoc
72     */
73    public function persist(SettingsCollection $settings): void
74    {
75        foreach ($settings as $setting) {
76            $this->storage->set(
77                $setting->getKey(),
78                $this->extractPersistenceValue($setting)
79            );
80        }
81    }
82
83    private function createSetting(string $key): Setting
84    {
85        $rawValue = $this->storage->get($key) ?: '';
86
87        if ($rawValue && $this->isMultilineValueKey($key)) {
88            $rawValue = implode("\n", json_decode($rawValue, true) ?? []);
89        }
90
91        return new Setting($key, $rawValue);
92    }
93
94    private function isMultilineValueKey(string $key): bool
95    {
96        return in_array($key, self::MULTILINE_VALUE_KEYS, true);
97    }
98
99    private function extractPersistenceValue(Setting $setting): string
100    {
101        if (!$this->isMultilineValueKey($setting->getKey())) {
102            return $setting->getValue();
103        }
104
105        return json_encode(
106            array_filter(
107                array_map('trim', explode("\n", $setting->getValue()))
108            )
109        );
110    }
111}