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 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\core\Auth\Process;
use SimpleSAML\Configuration;
use SimpleSAML\Module;
/**
* Attribute filter for renaming attributes.
*
* @author Olav Morken, UNINETT AS.
* @package SimpleSAMLphp
*/
class AttributeMap extends \SimpleSAML\Auth\ProcessingFilter
{
/**
* Associative array with the mappings of attribute names.
* @var array
*/
private $map = [];
/**
* Should attributes be duplicated or renamed.
* @var bool
*/
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 = [];
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.
* @return void
*/
private function loadMapFile(string $fileName): void
{
$config = Configuration::getInstance();
$m = explode(':', $fileName);
if (count($m) === 2) {
// we are asked for a file in a module
if (!Module::isModuleEnabled($m[0])) {
throw new \Exception("Module '$m[0]' is not enabled.");
}
$filePath = Module::getModuleDir($m[0]) . '/attributemap/' . $m[1] . '.php';
} else {
$attributenamemapdir = $config->getPathValue('attributenamemapdir', 'attributemap/') ?: 'attributemap/';
$filePath = $attributenamemapdir . $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.
* @return void
*/
public function process(&$request)
{
assert(is_array($request));
assert(array_key_exists('Attributes', $request));
$mapped_attributes = [];
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 {
if (array_key_exists($name, $mapped_attributes)) {
continue;
}
$mapped_attributes[$name] = $values;
}
}
$request['Attributes'] = $mapped_attributes;
}
}
|