File: AttributeMap.php

package info (click to toggle)
simplesamlphp 1.16.3-1%2Bdeb10u2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 21,036 kB
  • sloc: php: 73,175; ansic: 875; sh: 83; perl: 82; xml: 52; makefile: 46
file content (142 lines) | stat: -rw-r--r-- 4,459 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php


/**
 * Attribute filter for renaming attributes.
 *
 * @author Olav Morken, UNINETT AS.
 * @package SimpleSAMLphp
 */
class sspmod_core_Auth_Process_AttributeMap extends SimpleSAML_Auth_ProcessingFilter
{

    /**
     * Associative array with the mappings of attribute names.
     */
    private $map = array();

    /**
     * Should attributes be duplicated or renamed.
     */
    private $duplicate = false;


    /**
     * Initialize this filter, parse configuration
     *
     * @param array $config Configuration information about this filter.
     * @param mixed $reserved For future use.
     *
     * @throws Exception If the configuration of the filter is wrong.
     */
    public function __construct($config, $reserved)
    {
        parent::__construct($config, $reserved);

        assert(is_array($config));
        $mapFiles = array();

        foreach ($config as $origName => $newName) {
            if (is_int($origName)) {
                if ($newName === '%duplicate') {
                    $this->duplicate = true;
                } else {
                    // no index given, this is a map file
                    $mapFiles[] = $newName;
                }
                continue;
            }

            if (!is_string($origName)) {
                throw new Exception('Invalid attribute name: '.var_export($origName, true));
            }

            if (!is_string($newName) && !is_array($newName)) {
                throw new Exception('Invalid attribute name: '.var_export($newName, true));
            }

            $this->map[$origName] = $newName;
        }

        // load map files after we determine duplicate or rename
        foreach ($mapFiles as &$file) {
            $this->loadMapFile($file);
        }
    }


    /**
     * Loads and merges in a file with a attribute map.
     *
     * @param string $fileName Name of attribute map file. Expected to be in the attributemap directory in the root
     * of the SimpleSAMLphp installation, or in the root of a module.
     *
     * @throws Exception If the filter could not load the requested attribute map file.
     */
    private function loadMapFile($fileName)
    {
        $config = SimpleSAML_Configuration::getInstance();

        $m = explode(':', $fileName);
        if (count($m) === 2) { // we are asked for a file in a module
            if (!SimpleSAML\Module::isModuleEnabled($m[0])) {
                throw new Exception("Module '$m[0]' is not enabled.");
            }
            $filePath = SimpleSAML\Module::getModuleDir($m[0]).'/attributemap/'.$m[1].'.php';
        } else {
            $filePath = $config->getPathValue('attributenamemapdir', 'attributemap/').$fileName.'.php';
        }

        if (!file_exists($filePath)) {
            throw new Exception('Could not find attribute map file: '.$filePath);
        }

        $attributemap = null;
        include($filePath);
        if (!is_array($attributemap)) {
            throw new Exception('Attribute map file "'.$filePath.'" didn\'t define an attribute map.');
        }

        if ($this->duplicate) {
            $this->map = array_merge_recursive($this->map, $attributemap);
        } else {
            $this->map = array_merge($this->map, $attributemap);
        }
    }


    /**
     * Apply filter to rename attributes.
     *
     * @param array &$request The current request.
     */
    public function process(&$request)
    {
        assert(is_array($request));
        assert(array_key_exists('Attributes', $request));

        $mapped_attributes = array();

        foreach ($request['Attributes'] as $name => $values) {
            if (array_key_exists($name, $this->map)) {
                if (!is_array($this->map[$name])) {
                    if ($this->duplicate) {
                        $mapped_attributes[$name] = $values;
                    }
                    $mapped_attributes[$this->map[$name]] = $values;
                } else {
                    foreach ($this->map[$name] as $to_map) {
                        $mapped_attributes[$to_map] = $values;
                    }
                    if ($this->duplicate && !in_array($name, $this->map[$name], true)) {
                        $mapped_attributes[$name] = $values;
                    }
                }
            } else {
                $mapped_attributes[$name] = $values;
            }
        }

        $request['Attributes'] = $mapped_attributes;
    }
}