ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Cardinality.php
Go to the documentation of this file.
1<?php
2
3use SimpleSAML\Utils\HTTPAdapter;
4
12{
14 private $cardinality = array();
15
17 private $ignoreEntities = array();
18
20 private $http;
21
30 public function __construct($config, $reserved, HTTPAdapter $http = null)
31 {
32 parent::__construct($config, $reserved);
33 assert(is_array($config));
34
35 $this->http = $http ?: new HTTPAdapter();
36
37 foreach ($config as $attribute => $rules) {
38 if ($attribute === '%ignoreEntities') {
39 $this->ignoreEntities = $config['%ignoreEntities'];
40 continue;
41 }
42
43 if (!is_string($attribute)) {
44 throw new SimpleSAML_Error_Exception('Invalid attribute name: '.var_export($attribute, true));
45 }
46 $this->cardinality[$attribute] = array('warn' => false);
47
48 /* allow either positional or name-based parameters */
49 if (isset($rules[0])) {
50 $this->cardinality[$attribute]['min'] = $rules[0];
51 } elseif (isset($rules['min'])) {
52 $this->cardinality[$attribute]['min'] = $rules['min'];
53 }
54 if (isset($rules[1])) {
55 $this->cardinality[$attribute]['max'] = $rules[1];
56 } elseif (isset($rules['max'])) {
57 $this->cardinality[$attribute]['max'] = $rules['max'];
58 }
59 if (array_key_exists('warn', $rules)) {
60 $this->cardinality[$attribute]['warn'] = (bool) $rules['warn'];
61 }
62
63 /* sanity check the rules */
64 if (!array_key_exists('min', $this->cardinality[$attribute])) {
65 $this->cardinality[$attribute]['min'] = 0;
66 } elseif (!is_int($this->cardinality[$attribute]['min']) ||
67 $this->cardinality[$attribute]['min'] < 0
68 ) {
69 throw new SimpleSAML_Error_Exception('Minimum cardinality must be a positive integer: '.
70 var_export($attribute, true));
71 }
72 if (array_key_exists('max', $this->cardinality[$attribute]) &&
73 !is_int($this->cardinality[$attribute]['max'])
74 ) {
75 throw new SimpleSAML_Error_Exception('Maximum cardinality must be a positive integer: '.
76 var_export($attribute, true));
77 }
78 if (array_key_exists('min', $this->cardinality[$attribute]) &&
79 array_key_exists('max', $this->cardinality[$attribute]) &&
80 $this->cardinality[$attribute]['min'] > $this->cardinality[$attribute]['max']
81 ) {
82 throw new SimpleSAML_Error_Exception('Minimum cardinality must be less than maximium: '.
83 var_export($attribute, true));
84 }
85
86 /* generate a display expression */
87 $this->cardinality[$attribute]['_expr'] = sprintf('%d ≤ n', $this->cardinality[$attribute]['min']);
88 if (array_key_exists('max', $this->cardinality[$attribute])) {
89 $this->cardinality[$attribute]['_expr'] .= sprintf(' ≤ %d', $this->cardinality[$attribute]['max']);
90 }
91 }
92 }
93
99 public function process(&$request)
100 {
101 assert(is_array($request));
102 assert(array_key_exists("Attributes", $request));
103
104 $entityid = false;
105 if (array_key_exists('Source', $request) && array_key_exists('entityid', $request['Source'])) {
106 $entityid = $request['Source']['entityid'];
107 }
108 if (in_array($entityid, $this->ignoreEntities, true)) {
109 SimpleSAML\Logger::debug('Cardinality: Ignoring assertions from '.$entityid);
110 return;
111 }
112
113 foreach ($request['Attributes'] as $k => $v) {
114
115 if (!array_key_exists($k, $this->cardinality)) {
116 continue;
117 }
118 if (!is_array($v)) {
119 $v = array($v);
120 }
121
122 /* minimum cardinality */
123 if (count($v) < $this->cardinality[$k]['min']) {
124 if ($this->cardinality[$k]['warn']) {
126 'Cardinality: attribute %s from %s does not meet minimum cardinality of %d (%d)',
127 $k, $entityid, $this->cardinality[$k]['min'], count($v)
128 ));
129 } else {
130 $request['core:cardinality:errorAttributes'][$k] = array(count($v), $this->cardinality[$k]['_expr']);
131 }
132 continue;
133 }
134
135 /* maximum cardinality */
136 if (array_key_exists('max', $this->cardinality[$k]) && count($v) > $this->cardinality[$k]['max']) {
137 if ($this->cardinality[$k]['warn']) {
139 'Cardinality: attribute %s from %s does not meet maximum cardinality of %d (%d)',
140 $k, $entityid, $this->cardinality[$k]['max'], count($v)
141 ));
142 } else {
143 $request['core:cardinality:errorAttributes'][$k] = array(count($v), $this->cardinality[$k]['_expr']);
144 }
145 continue;
146 }
147 }
148
149 /* check for missing attributes with a minimum cardinality */
150 foreach ($this->cardinality as $k => $v) {
151 if (!$this->cardinality[$k]['min'] || array_key_exists($k, $request['Attributes'])) {
152 continue;
153 }
154 if ($this->cardinality[$k]['warn']) {
156 'Cardinality: attribute %s from %s is missing',
157 $k, $entityid
158 ));
159 } else {
160 $request['core:cardinality:errorAttributes'][$k] = array(0, $this->cardinality[$k]['_expr']);
161 }
162 }
163
164 /* abort if we found a problematic attribute */
165 if (array_key_exists('core:cardinality:errorAttributes', $request)) {
166 $id = SimpleSAML_Auth_State::saveState($request, 'core:cardinality');
167 $url = SimpleSAML\Module::getModuleURL('core/cardinality_error.php');
168 $this->http->redirectTrustedURL($url, array('StateId' => $id));
169 return;
170 }
171 }
172}
foreach($paths as $path) $request
Definition: asyncclient.php:32
An exception for terminatinating execution or to throw for unit testing.
static warning($string)
Definition: Logger.php:177
static debug($string)
Definition: Logger.php:211
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
Definition: Module.php:220
static saveState(&$state, $stage, $rawId=false)
Save the state.
Definition: State.php:194
__construct($config, $reserved, HTTPAdapter $http=null)
Initialize this filter, parse configuration.
Definition: Cardinality.php:30
process(&$request)
Process this filter.
Definition: Cardinality.php:99
if(!array_key_exists('StateId', $_REQUEST)) $id
$config
Definition: bootstrap.php:15
static http()
Fetches the global http state from ILIAS.
$url