From 2de293efb3e82752f99746862b30be25ebdfd6d3 Mon Sep 17 00:00:00 2001
From: Guy Halse <guy@tenet.ac.za>
Date: Fri, 1 Jul 2016 09:51:45 +0200
Subject: [PATCH] Add an onlyIfEmpty option to core:ScopeAttribute. This makes
 the filter a little more useful for people who want to generate default
 values from another attribute only if none alreay exist.

---
 modules/core/docs/authproc_scopeattribute.md  |  6 +++++
 .../core/lib/Auth/Process/ScopeAttribute.php  | 14 ++++++++++-
 .../lib/Auth/Process/ScopeAttributeTest.php   | 23 +++++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/modules/core/docs/authproc_scopeattribute.md b/modules/core/docs/authproc_scopeattribute.md
index 6930149bb..586158798 100644
--- a/modules/core/docs/authproc_scopeattribute.md
+++ b/modules/core/docs/authproc_scopeattribute.md
@@ -26,6 +26,12 @@ Parameters
 
 :   If the attribute already exists, the new values will be merged into the existing attribute.
 
+`onlyIfEmpty`
+:	Only replace the targetAttribute if it is empty to begin with.
+
+:	If `true`, then the targetAttribute will only be created if it didn't already contain values. Defaults to `false`.
+
+:	This is useful if, for instance, you want to create eduPersonScopedAffiliation from eduPersonAffiliation _only_ if eduPersonScopedAffiliation was not returned by the authenticaton source.
 
 Example
 -------
diff --git a/modules/core/lib/Auth/Process/ScopeAttribute.php b/modules/core/lib/Auth/Process/ScopeAttribute.php
index 9c8c571ac..6c2c03a93 100644
--- a/modules/core/lib/Auth/Process/ScopeAttribute.php
+++ b/modules/core/lib/Auth/Process/ScopeAttribute.php
@@ -30,6 +30,13 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 	 */
 	private $targetAttribute;
 
+	/**
+	 * Only modify targetAttribute if it doesn't already exist.
+	 *
+	 * @var bool
+	 */
+	private $onlyIfEmpty = false;
+
 
 	/**
 	 * Initialize this filter, parse configuration
@@ -46,6 +53,7 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 		$this->scopeAttribute = $config->getString('scopeAttribute');
 		$this->sourceAttribute = $config->getString('sourceAttribute');
 		$this->targetAttribute = $config->getString('targetAttribute');
+		$this->onlyIfEmpty = $config->getBoolean('onlyIfEmpty', false);
 	}
 
 
@@ -72,6 +80,10 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 			$attributes[$this->targetAttribute] = array();
 		}
 
+		if ($this->onlyIfEmpty and count($attributes[$this->targetAttribute]) > 0) {
+			return;
+		}
+
 		foreach ($attributes[$this->scopeAttribute] as $scope) {
 
 			if (strpos($scope, '@') !== FALSE) {
@@ -93,4 +105,4 @@ class sspmod_core_Auth_Process_ScopeAttribute extends SimpleSAML_Auth_Processing
 
 	}
 
-}
\ No newline at end of file
+}
diff --git a/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php b/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
index 31e151636..8b86314cf 100644
--- a/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
+++ b/tests/modules/core/lib/Auth/Process/ScopeAttributeTest.php
@@ -191,4 +191,27 @@ class Test_Core_Auth_Process_ScopeAttribute extends PHPUnit_Framework_TestCase
         $attributes = $result['Attributes'];
         $this->assertEquals($attributes['eduPersonScopedAffiliation'], array('student@example.org'));
     }
+
+	/*
+	 * When the target attribute exists and onlyIfEmpty is set
+	 */
+	public function testOnlyIfEmpty()
+	{
+       $config = array(
+            'scopeAttribute' => 'schacHomeOrganization',
+            'sourceAttribute' => 'eduPersonAffiliation',
+            'targetAttribute' => 'eduPersonScopedAffiliation',
+			'onlyIfEmpty' => true,
+        );
+        $request = array(
+            'Attributes' => array(
+                'schacHomeOrganization' => array('example.org'),
+                'eduPersonAffiliation' => array('student'),
+				'eduPersonScopedAffiliation' => array('staff@example.org', 'member@example.org'),
+            )
+        );
+        $result = self::processFilter($config, $request);
+        $attributes = $result['Attributes'];
+        $this->assertEquals($attributes['eduPersonScopedAffiliation'], array('staff@example.org', 'member@example.org'));
+	}
 }
-- 
GitLab