MetaRefresh   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Importance

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

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
F runRefresh() 0 111 16
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
     * @param \SimpleSAML\Configuration              $config The configuration to use by the module.
26
     * @param \SimpleSAML\Configuration              $modconfig The module-specific configuration to use by the module.
27
     */
28
    public function __construct(Configuration $config, Configuration $modconfig)
29
    {
30
        $this->config = $config;
31
        $this->modconfig = $modconfig;
32
    }
33
34
    /**
35
     * @param string|null $crontag Only refresh sets which allow this crontag
36
     */
37
    public function runRefresh(?string $crontag = null): void
38
    {
39
        $sets = $this->modconfig->getArray('sets');
40
        /** @var string $datadir */
41
        $datadir = $this->config->getPathValue('datadir', 'data/');
42
        $stateFile = $datadir . 'metarefresh-state.php';
43
44
        foreach ($sets as $setkey => $set) {
45
            $set = Configuration::loadFromArray($set);
46
47
            // Only process sets where cron matches the current cron tag
48
            $cronTags = $set->getArray('cron');
49
            if ($crontag !== null && !in_array($crontag, $cronTags, true)) {
50
                Logger::debug('[metarefresh]: Skipping set [' . $setkey . '], not allowed for cron tag ' . $crontag);
51
                continue;
52
            }
53
54
            Logger::info('[metarefresh]: Executing set [' . $setkey . ']');
55
56
            $expireAfter = $set->getOptionalInteger('expireAfter', null);
57
            if ($expireAfter !== null) {
58
                $expire = time() + $expireAfter;
59
            } else {
60
                $expire = null;
61
            }
62
63
            $outputDir = $set->getString('outputDir');
64
            $outputDir = $this->config->resolvePath($outputDir);
65
            if ($outputDir === null) {
66
                throw new Exception("Invalid outputDir specified.");
67
            }
68
69
            $outputFormat = $set->getOptionalValueValidate('outputFormat', ['flatfile', 'serialize', 'pdo'], 'flatfile');
70
71
            $oldMetadataSrc = MetaDataStorageSource::getSource([
72
                'type' => $outputFormat,
73
                'directory' => $outputDir,
74
            ]);
75
76
            $metaloader = new MetaLoader($expire, $stateFile, $oldMetadataSrc);
77
78
            // Get global blacklist, whitelist, attributewhitelist and caching info
79
            $blacklist = $this->modconfig->getOptionalArray('blacklist', []);
80
            $whitelist = $this->modconfig->getOptionalArray('whitelist', []);
81
            $attributewhitelist = $this->modconfig->getOptionalArray('attributewhitelist', []);
82
            $conditionalGET = $this->modconfig->getOptionalBoolean('conditionalGET', false);
83
84
            // get global type filters
85
            $available_types = [
86
                'saml20-idp-remote',
87
                'saml20-sp-remote',
88
                'attributeauthority-remote',
89
            ];
90
            $set_types = $set->getOptionalArray('types', $available_types);
91
92
            foreach ($set->getArray('sources') as $source) {
93
                // filter metadata by type of entity
94
                if (isset($source['types'])) {
95
                    $metaloader->setTypes($source['types']);
96
                } else {
97
                    $metaloader->setTypes($set_types);
98
                }
99
100
                // Merge global and src specific blacklists
101
                if (isset($source['blacklist'])) {
102
                    $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

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