File: GenerateGroups.php

package info (click to toggle)
simplesamlphp 1.13.1-2%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 11,304 kB
  • sloc: php: 65,124; xml: 629; python: 376; sh: 193; perl: 185; makefile: 43
file content (144 lines) | stat: -rw-r--r-- 3,572 bytes parent folder | download | duplicates (2)
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
<?php

/**
 * Filter to generate a groups attribute based on many of the attributes of the user.
 *
 * @author Olav Morken, UNINETT AS.
 * @package simpleSAMLphp
 */
class sspmod_core_Auth_Process_GenerateGroups extends SimpleSAML_Auth_ProcessingFilter {


	/**
	 * The attributes we should generate groups from.
	 */
	private $generateGroupsFrom;


	/**
	 * Initialize this filter.
	 *
	 * @param array $config  Configuration information about this filter.
	 * @param mixed $reserved  For future use.
	 */
	public function __construct($config, $reserved) {
		parent::__construct($config, $reserved);

		assert('is_array($config)');

		if (count($config) === 0) {
			/* Use default groups. */
			$this->generateGroupsFrom = array(
				'eduPersonAffiliation',
				'eduPersonOrgUnitDN',
				'eduPersonEntitlement',
			);

		} else {
			/* Validate configuration. */
			foreach ($config as $attributeName) {
				if (!is_string($attributeName)) {
					throw new Exception('Invalid attribute name for core:GenerateGroups filter: ' .
						var_export($attributeName, TRUE));
				}
			}

			$this->generateGroupsFrom = $config;
		}
	}


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

		$groups = array();
		$attributes =& $request['Attributes'];

		$realm = self::getRealm($attributes);
		if ($realm !== NULL) {
			$groups[] = 'realm-' . $realm;
		}


		foreach ($this->generateGroupsFrom as $name) {
			if (!array_key_exists($name, $attributes)) {
				SimpleSAML_Logger::debug('GenerateGroups - attribute \'' . $name . '\' not found.');
				/* Attribute not present. */
				continue;
			}

			foreach ($attributes[$name] as $value) {
				$value = self::escapeIllegalChars($value);
				$groups[] = $name . '-' . $value;
				if ($realm !== NULL) {
					$groups[] = $name . '-' . $realm . '-' . $value;
				}
			}
		}

		if (count($groups) > 0) {
			$attributes['groups'] = $groups;
		}
	}


	/**
	 * Determine which realm the user belongs to.
	 *
	 * This function will attempt to determine the realm a user belongs to based on the
	 * eduPersonPrincipalName attribute if it is present. If it isn't, or if it doesn't contain
	 * a realm, NULL will be returned.
	 *
	 * @param array $attributes  The attributes of the user.
	 * @return string|NULL  The realm of the user, or NULL if we are unable to determine the realm.
	 */
	private static function getRealm($attributes) {
		assert('is_array($attributes)');

		if (!array_key_exists('eduPersonPrincipalName', $attributes)) {
			return NULL;
		}
		$eppn = $attributes['eduPersonPrincipalName'];

		if (count($eppn) < 1) {
			return NULL;
		}
		$eppn = $eppn[0];

		$realm = explode('@', $eppn, 2);
		if (count($realm) < 2) {
			return NULL;
		}
		$realm = $realm[1];

		return self::escapeIllegalChars($realm);
	}


	/**
	 * Escape special characters in a string.
	 *
	 * This function is similar to urlencode, but encodes many more characters.
	 * This function takes any characters not in [a-zA-Z0-9_@=.] and encodes them with as
	 * %<hex version>. For example, it will encode '+' as '%2b' and '%' as '%25'.
	 *
	 * @param string $string  The string which should be escaped.
	 * @return string  The escaped string.
	 */
	private static function escapeIllegalChars($string) {
		assert('is_string($string)');

		return preg_replace_callback('/([^a-zA-Z0-9_@=.])/',
			function ($m) { return sprintf("%%%02x", ord($m[1])); },
			$string);
	}

}

?>