Passed
Push — master ( f27ac9...8a19bb )
by
unknown
02:06
created

AttributeExtractor::extractUserAndAttributes()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
c 1
b 0
f 0
nc 8
nop 2
dl 0
loc 34
rs 8.6666
1
<?php
2
3
namespace SimpleSAML\Module\casserver\Cas;
4
5
use SimpleSAML\Configuration;
6
use SimpleSAML\Module;
7
8
/**
9
 * Extract the user and any mapped attributes from the AuthSource attributes
10
 */
11
class AttributeExtractor
12
{
13
    /**
14
     * Determine the user and any CAS attributes based on the attributes from the
15
     * authsource and the CAS configuration.
16
     *
17
     * The result is an array
18
     * [
19
     *   'user' => 'user_value',
20
     *   'attributes' => [
21
     *    // any attributes
22
     * ]
23
     *
24
     * If no CAS attributes are configured then the attributes array is empty
25
     * @param array $attributes
26
     * @param \SimpleSAML\Configuration $casconfig
27
     * @return array
28
     */
29
    public function extractUserAndAttributes(array $attributes, Configuration $casconfig)
30
    {
31
        if ($casconfig->hasValue('authproc')) {
32
            $attributes = $this->invokeAuthProc($attributes, $casconfig);
33
        }
34
35
        $casUsernameAttribute = $casconfig->getValue('attrname', 'eduPersonPrincipalName');
36
37
        $userName = $attributes[$casUsernameAttribute][0];
38
        if (empty($userName)) {
39
            throw new \Exception("No cas user defined for attribute $casUsernameAttribute");
40
        }
41
42
        if ($casconfig->getValue('attributes', true)) {
43
            $attributesToTransfer = $casconfig->getValue('attributes_to_transfer', []);
44
45
            if (sizeof($attributesToTransfer) > 0) {
46
                $casAttributes = [];
47
48
                foreach ($attributesToTransfer as $key) {
49
                    if (array_key_exists($key, $attributes)) {
50
                        $casAttributes[$key] = $attributes[$key];
51
                    }
52
                }
53
            } else {
54
                $casAttributes = $attributes;
55
            }
56
        } else {
57
            $casAttributes = [];
58
        }
59
60
        return [
61
            'user' => $userName,
62
            'attributes' => $casAttributes
63
        ];
64
    }
65
66
67
    /**
68
     * Process any authproc filters defined in the configuration. The Authproc filters must only
69
     * rely on 'Attributes' being available and not on additional SAML state.
70
     * @see \SimpleSAML_Auth_ProcessingChain::parseFilter() For the original, SAML side implementation
71
     * @param array $attributes The current attributes
72
     * @param \SimpleSAML\Configuration $casconfig The cas configuration
73
     * @return array The attributes post processing.
74
     */
75
    private function invokeAuthProc(array $attributes, Configuration $casconfig)
76
    {
77
        $filters = $casconfig->getArray('authproc', []);
78
79
        $state = [
80
            'Attributes' => $attributes
81
        ];
82
        foreach ($filters as $config) {
83
            $className = Module::resolveClass(
84
                $config['class'],
85
                'Auth\Process',
86
                \SimpleSAML\Auth\ProcessingFilter::class
87
            );
88
            // Unset 'class' to prevent the filter from interpreting it as an option
89
            unset($config['class']);
90
            /** @psalm-suppress InvalidStringClass */
91
            $filter = new $className($config, null);
92
            $filter->process($state);
93
        }
94
95
        return $state['Attributes'];
96
    }
97
}
98