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;
}
}
|