MetaRefresh   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 73
dl 0
loc 138
rs 10
c 3
b 0
f 0
wmc 17

2 Methods

Rating   Name   Duplication   Size   Complexity  
F runRefresh() 0 111 16
A __construct() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\metarefresh;
6
7
use Exception;
8
use SimpleSAML\Configuration;
9
use SimpleSAML\Logger;
10
use SimpleSAML\Metadata\MetaDataStorageSource;
11
12
class MetaRefresh
13
{
14
    /**
15
     * @var \SimpleSAML\Configuration
16
     */
17
    private Configuration $config;
18
19
    /**
20
     * @var \SimpleSAML\Configuration
21
     */
22
    private Configuration $modconfig;
23
24
25
    /**
26
     * @param \SimpleSAML\Configuration $config The configuration to use by the module.
27
     * @param \SimpleSAML\Configuration $modconfig The module-specific configuration to use by the module.
28
     */
29
    public function __construct(Configuration $config, Configuration $modconfig)
30
    {
31
        $this->config = $config;
32
        $this->modconfig = $modconfig;
33
    }
34
35
36
    /**
37
     * @param string|null $crontag Only refresh sets which allow this crontag
38
     */
39
    public function runRefresh(?string $crontag = null): void
40
    {
41
        $sets = $this->modconfig->getArray('sets');
42
        /** @var string $datadir */
43
        $datadir = $this->config->getPathValue('datadir', 'data/');
44
        $stateFile = $datadir . 'metarefresh-state.php';
45
46
        foreach ($sets as $setkey => $set) {
47
            $set = Configuration::loadFromArray($set);
48
49
            // Only process sets where cron matches the current cron tag
50
            $cronTags = $set->getArray('cron');
51
            if ($crontag !== null && !in_array($crontag, $cronTags, true)) {
52
                Logger::debug('[metarefresh]: Skipping set [' . $setkey . '], not allowed for cron tag ' . $crontag);
53
                continue;
54
            }
55
56
            Logger::info('[metarefresh]: Executing set [' . $setkey . ']');
57
58
            $expireAfter = $set->getOptionalInteger('expireAfter', null);
59
            if ($expireAfter !== null) {
60
                $expire = time() + $expireAfter;
61
            } else {
62
                $expire = null;
63
            }
64
65
            $outputDir = $set->getString('outputDir');
66
            $outputDir = $this->config->resolvePath($outputDir);
67
            if ($outputDir === null) {
68
                throw new Exception("Invalid outputDir specified.");
69
            }
70
71
            $outputFormat = $set->getOptionalValueValidate('outputFormat', ['flatfile', 'serialize', 'pdo'], 'flatfile');
72
73
            $oldMetadataSrc = MetaDataStorageSource::getSource([
74
                'type' => $outputFormat,
75
                'directory' => $outputDir,
76
            ]);
77
78
            $metaloader = new MetaLoader($expire, $stateFile, $oldMetadataSrc);
79
80
            // Get global blacklist, whitelist, attributewhitelist and caching info
81
            $blacklist = $this->modconfig->getOptionalArray('blacklist', []);
82
            $whitelist = $this->modconfig->getOptionalArray('whitelist', []);
83
            $attributewhitelist = $this->modconfig->getOptionalArray('attributewhitelist', []);
84
            $conditionalGET = $this->modconfig->getOptionalBoolean('conditionalGET', false);
85
86
            // get global type filters
87
            $available_types = [
88
                'saml20-idp-remote',
89
                'saml20-sp-remote',
90
                'attributeauthority-remote',
91
            ];
92
            $set_types = $set->getOptionalArray('types', $available_types);
93
94
            foreach ($set->getArray('sources') as $source) {
95
                // filter metadata by type of entity
96
                if (isset($source['types'])) {
97
                    $metaloader->setTypes($source['types']);
98
                } else {
99
                    $metaloader->setTypes($set_types);
100
                }
101
102
                // Merge global and src specific blacklists
103
                if (isset($source['blacklist'])) {
104
                    $source['blacklist'] = array_unique(array_merge($source['blacklist'], $blacklist));
0 ignored issues
show
Bug introduced by
It seems like $blacklist can also be of type null; however, parameter $arrays of array_merge() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
                    $source['blacklist'] = array_unique(array_merge($source['blacklist'], /** @scrutinizer ignore-type */ $blacklist));
Loading history...
105
                } else {
106
                    $source['blacklist'] = $blacklist;
107
                }
108
109
                // Merge global and src specific whitelists
110
                if (isset($source['whitelist'])) {
111
                    $source['whitelist'] = array_unique(array_merge($source['whitelist'], $whitelist));
112
                } else {
113
                    $source['whitelist'] = $whitelist;
114
                }
115
116
                # Merge global and src specific attributewhitelists: cannot use array_unique for multi-dim.
117
                if (isset($source['attributewhitelist'])) {
118
                    $source['attributewhitelist'] = array_merge($source['attributewhitelist'], $attributewhitelist);
119
                } else {
120
                    $source['attributewhitelist'] = $attributewhitelist;
121
                }
122
123
                // Let src specific conditionalGET override global one
124
                if (!isset($source['conditionalGET'])) {
125
                    $source['conditionalGET'] = $conditionalGET;
126
                }
127
128
                Logger::debug('[metarefresh]: In set [' . $setkey . '] loading source [' . $source['src'] . ']');
129
                $metaloader->loadSource($source);
130
            }
131
132
            // Write state information back to disk
133
            $metaloader->writeState();
134
135
            switch ($outputFormat) {
136
                case 'flatfile':
137
                    $metaloader->writeMetadataFiles($outputDir);
138
                    break;
139
                case 'serialize':
140
                    $metaloader->writeMetadataSerialize($outputDir);
141
                    break;
142
                case 'pdo':
143
                    $metaloader->writeMetadataPdo($this->config);
144
                    break;
145
            }
146
147
            if ($set->hasValue('arp')) {
148
                $arpconfig = Configuration::loadFromArray($set->getValue('arp'));
149
                $metaloader->writeARPfile($arpconfig);
150
            }
151
        }
152
    }
153
}
154