diff --git a/modules/core/docs/authproc_attributealter.txt b/modules/core/docs/authproc_attributealter.txt new file mode 100644 index 0000000000000000000000000000000000000000..1efae88bb13e5c27809b31a7480bf26d6dfb1fbe --- /dev/null +++ b/modules/core/docs/authproc_attributealter.txt @@ -0,0 +1,85 @@ +`core:AttributeAlter` +========== + +This filter can be used to substitute and replace different parts of the attribute value based on regular expressions. + +Parameters +---------- + +`class` +: This is the name of the filter. + It must be `'core:AttributeAlter'`. + +`subject` +: The attribute in which the search is preformed. + This parameter is REQUIRED and the filter will throw an exception if this parameter is not set. + +`pattern` +: The regular expression used. + This parameter is REQUIRED and the filter will throw an exception if this parameter is not set. + It is not possible to use backreference. + +`replacement` +: The value used to replace the searched value. + This parameter is REQUIRED if `%replace` is not used. + If `%replace` is used and `replacement` is not set, then the matched text is used instead. + +`target` +: The target attribute where the replaced attribute value is put. + This parameter is OPTIONAL. + If this parameter is not set `subject` is used as `target`. + +`%replace` +: Indicate whether the searched part should be replaced or the whole value. + this parameter is OPTIONAL. + +Examples +-------- + +Change the domain on the `mail` attribute (when both the new and old domain is known): + + 10 => array( + 'class' => 'core:AttributeAlter', + 'subject' => 'mail', + 'pattern' => '/olddomain.com/', + 'replacement' => 'newdomain.com', + ), + +Change the domain on the `mail` attribute (when new domain is known): + + 10 => array( + 'class' => 'core:AttributeAlter', + 'subject' => 'mail', + 'pattern' => '/(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/', + 'replacement' => 'newdomain.com', + ), + +Set the eduPersonPrimaryAffiliation based on users distinguishedName: + + 10 => array( + 'class' => 'core:AttributeAlter', + 'subject' => 'dn', + 'pattern' => '/OU=Staff/', + 'replacement' => 'staff', + 'target' => 'eduPersonPrimaryAffiliation', + ), + +Change the eduPersonPrimaryAffiliation: + + 10 => array( + 'class' => 'core:AttributeAlter', + 'subject' => 'eduPersonPrimaryAffiliation', + 'pattern' => '/Student in school/', + 'replacement' => 'student', + '%replace', + ), + +Get the domain of the email and put it in a seperat attribute: + + 10 => array( + 'class' => 'core:AttributeAlter', + 'subject' => 'mail', + 'pattern' => '/(?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$/', + 'target' => 'domain', + '%replace', + ), \ No newline at end of file diff --git a/modules/core/lib/Auth/Process/AttributeAlter.php b/modules/core/lib/Auth/Process/AttributeAlter.php index 601d6c58a7f066b8099724a9d46f34bfa6a4e03b..2cbd528b64390d9c18cc91f2748da77f7463871f 100644 --- a/modules/core/lib/Auth/Process/AttributeAlter.php +++ b/modules/core/lib/Auth/Process/AttributeAlter.php @@ -1,9 +1,8 @@ <?php - /** - * Filter to modify attributes. + * Filter to modify attributes using regular expressions * - * This filter can modify attributes given a regular expression. + * This filter can modify or replace attributes given a regular expression. * * @author Jacob Christiansen, WAYF * @package simpleSAMLphp @@ -17,7 +16,7 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing private $replace = FALSE; /** - * Pattern to besearch for. + * Pattern to be search for. */ private $pattern = ''; @@ -27,10 +26,15 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing private $replacement = ''; /** - * Attribute to search in. + * Attribute to search in */ private $subject = ''; + /** + * Attribute to place result in. + */ + private $target = ''; + /** * Initialize this filter. * @@ -38,11 +42,11 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing * @param mixed $reserved For future use. */ public function __construct($config, $reserved) { - parent::__construct($config, $reserved); - assert('is_array($config)'); - + parent::__construct($config, $reserved); + + // Parse filter configuration foreach($config as $name => $value) { // Is %replace set? if(is_int($name)) { @@ -53,26 +57,34 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing } continue; } + // Unknown flag if(!is_string($name)) { throw new Exception('Unknown flag : ' . var_export($name, TRUE)); } + // Set pattern if($name == 'pattern') { $this->pattern = $value; } + // Set replacement if($name == 'replacement') { $this->replacement = $value; } + // Set subject if($name == 'subject') { $this->subject = $value; } + + // Set target + if($name == 'target') { + $this->target = $value; + } } } - /** * Apply filter to modify attributes. * @@ -84,31 +96,38 @@ class sspmod_core_Auth_Process_AttributeAlter extends SimpleSAML_Auth_Processing assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); - /** - * Get attributes from request - */ + // Get attributes from request $attributes =& $request['Attributes']; + // Check that all required params are set in config if(empty($this->pattern) || empty($this->subject)) { throw new Exception("Not all params set in config."); } - /** - * Check if attributes contains subject attribute - */ - if (array_key_exists($this->subject,$attributes)) { - // Replace is TRUE + if(!$this->replace && empty($this->replacement)) { + throw new Exception("'replacement' must be set if '%replace' is not set"); + } + + // Use subject as taget if target is not set + if(empty($this->target)) { + $this->target = $this->subject; + } + + // Check if attributes contains subject and target attribute + if (array_key_exists($this->subject, $attributes) && array_key_exists($this->target, $attributes)) { if($this->replace == TRUE) { + $matches = array(); // Try to match pattern - if(preg_match($this->pattern, $attributes[$this->subject][0])) { - $attributes[$this->subject] = array($this->replacement); + if(preg_match($this->pattern, $attributes[$this->subject][0], $matches) > 0) { + if(empty($this->replacement)) { + $attributes[$this->target][0] = $matches[0]; + } else { + $attributes[$this->target][0] = $this->replacement; + } } - } else { - // Try to match pattern - $attributes[$this->subject] = preg_replace($this->pattern, $this->replacement, $attributes[$this->subject]); + } else { + $attributes[$this->target] = preg_replace($this->pattern, $this->replacement, $attributes[$this->subject]); } } } -} - -?> +} \ No newline at end of file