|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* * ********************************************************************************* |
|
4
|
|
|
* (c) 2011-15 GÉANT on behalf of the GN3, GN3plus and GN4 consortia |
|
5
|
|
|
* License: see the LICENSE file in the root directory |
|
6
|
|
|
* ********************************************************************************* */ |
|
7
|
|
|
?> |
|
8
|
|
|
<?php |
|
9
|
|
|
|
|
10
|
|
|
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . "/config/_config.php"); |
|
11
|
|
|
|
|
12
|
|
|
require_once("Options.php"); |
|
13
|
|
|
|
|
14
|
|
|
require_once("input_validation.inc.php"); |
|
15
|
|
|
|
|
16
|
|
|
function postProcessValidAttribtues($options, &$good, &$bad) { |
|
17
|
|
|
foreach ($options as $index => $iterate_option) { |
|
18
|
|
|
foreach ($iterate_option as $name => $value) { |
|
19
|
|
|
switch ($name) { |
|
20
|
|
View Code Duplication |
case "eap:ca_url": // eap:ca_url becomes eap:ca_file by downloading the file |
|
|
|
|
|
|
21
|
|
|
if (empty($value)) { |
|
22
|
|
|
break; |
|
23
|
|
|
} |
|
24
|
|
|
$content = downloadFile($value); |
|
25
|
|
|
unset($options[$index]); |
|
26
|
|
|
if (check_upload_sanity("eap:ca_file", $content)) { |
|
27
|
|
|
$content = base64_encode($content); |
|
28
|
|
|
$options[] = ["eap:ca_file" => $content]; |
|
29
|
|
|
$good[] = $name; |
|
30
|
|
|
} else { |
|
31
|
|
|
$bad[] = $name; |
|
32
|
|
|
} |
|
33
|
|
|
break; |
|
34
|
|
|
case "eap:ca_file": // CA files get split (PEM files can contain more than one CA cert) |
|
35
|
|
|
// the data being processed here is always "good": |
|
36
|
|
|
// if it was eap:ca_file initially then its sanity was checked in step 1; |
|
37
|
|
|
// if it was eap:ca_url then it was checked after we downloaded it |
|
38
|
|
|
if (empty($value) || preg_match('/^ROWID-/', $value)) { |
|
39
|
|
|
break; |
|
40
|
|
|
} |
|
41
|
|
|
$content = base64_decode($value); |
|
42
|
|
|
unset($options[$index]); |
|
43
|
|
|
$ca_files = X509::splitCertificate($content); |
|
|
|
|
|
|
44
|
|
|
foreach ($ca_files as $ca_file) { |
|
45
|
|
|
$options[] = ["eap:ca_file" => base64_encode(X509::pem2der($ca_file))]; |
|
46
|
|
|
} |
|
47
|
|
|
$good[] = $name; |
|
48
|
|
|
break; |
|
49
|
|
View Code Duplication |
case "general:logo_url": // logo URLs become logo files by downloading the file |
|
|
|
|
|
|
50
|
|
|
if (empty($value)) { |
|
51
|
|
|
break; |
|
52
|
|
|
} |
|
53
|
|
|
$bindata = downloadFile($value); |
|
54
|
|
|
unset($options[$index]); |
|
55
|
|
|
if (check_upload_sanity("general:logo_file", $bindata)) { |
|
56
|
|
|
$good[] = $name; |
|
57
|
|
|
$options[] = ["general:logo_file" => base64_encode($bindata)]; |
|
58
|
|
|
} else { |
|
59
|
|
|
$bad[] = $name; |
|
60
|
|
|
} |
|
61
|
|
|
break; |
|
62
|
|
|
default: |
|
63
|
|
|
$good[] = $name; // all other options were checked and are sane in step 1 already |
|
64
|
|
|
break; |
|
65
|
|
|
} |
|
66
|
|
|
} |
|
67
|
|
|
} |
|
68
|
|
|
return $options; |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
function postProcessCoordinates($options, &$good) { |
|
72
|
|
|
if (!empty($_POST['geo_long']) && !empty($_POST['geo_lat'])) { |
|
73
|
|
|
|
|
74
|
|
|
$lat = valid_coordinate($_POST['geo_lat']); |
|
75
|
|
|
$lon = valid_coordinate($_POST['geo_long']); |
|
76
|
|
|
|
|
77
|
|
|
$options[] = ["general:geo_coordinates" => serialize(["lon" => $lon, "lat" => $lat])]; |
|
78
|
|
|
$good[] = ("general:geo_coordinates"); |
|
79
|
|
|
} |
|
80
|
|
|
return $options; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
function displaySummaryInUI($good, $bad, $multilangAttribsWithC) { |
|
84
|
|
|
$retval = ""; |
|
85
|
|
|
// don't do your own table - only the <tr>s here |
|
86
|
|
|
// list all attributes that were set correctly |
|
87
|
|
|
$listGood = array_count_values($good); |
|
88
|
|
|
foreach ($listGood as $name => $count) { |
|
89
|
|
|
/// number of times attribute is present, and its name |
|
90
|
|
|
/// Example: "5x Support E-Mail" |
|
91
|
|
|
$retval .= UI_okay(sprintf(_("%dx %s"), $count, display_name($name))); |
|
92
|
|
|
} |
|
93
|
|
|
// list all atributes that had errors |
|
94
|
|
|
$listBad = array_count_values($bad); |
|
95
|
|
|
foreach ($listBad as $name => $count) { |
|
96
|
|
|
$retval .= UI_error(sprintf(_("%dx %s"), $count, display_name($name))); |
|
97
|
|
|
} |
|
98
|
|
|
// list multilang without default |
|
99
|
|
|
foreach ($multilangAttribsWithC as $attrib_name => $isitsetornot) { |
|
100
|
|
|
if ($isitsetornot == FALSE) { |
|
101
|
|
|
$retval .= UI_warning(sprintf(_("You did not set a 'default language' value for %s. This means we can only display this string for installers which are <strong>exactly</strong> in the language you configured. For the sake of all other languages, you may want to edit the profile again and populate the 'default/other' language field."), display_name($attrib_name))); |
|
102
|
|
|
} |
|
103
|
|
|
} |
|
104
|
|
|
return $retval; |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
function processSubmittedFields($object, $pendingattributes, $eaptype = 0, $device = 0, $silent = 0) { |
|
108
|
|
|
|
|
109
|
|
|
// construct new array with all non-empty options for later feeding into DB |
|
110
|
|
|
|
|
111
|
|
|
$optionsStep1 = []; |
|
112
|
|
|
$good = []; |
|
113
|
|
|
$bad = []; |
|
114
|
|
|
|
|
115
|
|
|
$killlist = $pendingattributes; |
|
116
|
|
|
|
|
117
|
|
|
$iterator = []; |
|
118
|
|
|
|
|
119
|
|
|
$optioninfoObject = Options::instance(); |
|
120
|
|
|
// Step 1a: parse the arrays for text-based input |
|
121
|
|
|
|
|
122
|
|
|
if (isset($_POST)) { |
|
123
|
|
|
if (isset($_POST['option'])) { |
|
124
|
|
|
foreach ($_POST['option'] as $optId => $optname) { |
|
125
|
|
|
$iterator[$optId] = $optname; |
|
126
|
|
|
} |
|
127
|
|
|
} |
|
128
|
|
|
if (isset($_POST['value'])) { |
|
129
|
|
|
foreach ($_POST['value'] as $optId => $optvalue) { |
|
130
|
|
|
$iterator[$optId] = $optvalue; |
|
131
|
|
|
} |
|
132
|
|
|
} |
|
133
|
|
|
} |
|
134
|
|
|
if (isset($_FILES) && isset($_FILES['value']) && isset($_FILES['value']['tmp_name'])) { |
|
135
|
|
|
foreach ($_FILES['value']['tmp_name'] as $opt_id => $optfileref) { |
|
136
|
|
|
$iterator[$opt_id] = $optfileref; |
|
137
|
|
|
} |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
// following is a helper array to keep track of multilang options that were set in a specific language |
|
141
|
|
|
// but are not accompanied by a "default" language setting |
|
142
|
|
|
// if the array isn't empty by the end of processing, we need to warn the admin that this attribute |
|
143
|
|
|
// is "invisible" in certain languages |
|
144
|
|
|
// attrib_name -> boolean |
|
145
|
|
|
|
|
146
|
|
|
$multilangAttribsWithC = []; |
|
147
|
|
|
|
|
148
|
|
|
foreach ($iterator as $objId => $objValueRaw) { |
|
149
|
|
|
// pick those without dash - they indicate a new value |
|
150
|
|
|
if (preg_match('/^S[0123456789]*$/', $objId)) { |
|
151
|
|
|
$objValue = preg_replace('/#.*$/', '', $objValueRaw); |
|
152
|
|
|
$optioninfo = $optioninfoObject->optionType($objValue); |
|
153
|
|
|
$lang = ""; |
|
154
|
|
|
if ($optioninfo["flag"] == "ML") { |
|
155
|
|
|
if (isset($iterator["$objId-lang"])) { |
|
156
|
|
|
$lang = $iterator["$objId-lang"]; |
|
157
|
|
|
if ($lang == "") { // user forgot to select a language |
|
158
|
|
|
$lang = "C"; |
|
159
|
|
|
} |
|
160
|
|
|
} else { |
|
161
|
|
|
$bad[] = $objValue; |
|
162
|
|
|
continue; |
|
163
|
|
|
} |
|
164
|
|
|
// did we get a C language? set corresponding value to TRUE |
|
165
|
|
|
if ($lang == "C") { |
|
166
|
|
|
$multilangAttribsWithC[$objValue] = TRUE; |
|
167
|
|
|
} else { // did we get a C earlier - fine, don't touch the array. Otherwise, set FALSE |
|
168
|
|
|
if (!isset($multilangAttribsWithC[$objValue]) || $multilangAttribsWithC[$objValue] != TRUE) { |
|
169
|
|
|
$multilangAttribsWithC[$objValue] = FALSE; |
|
170
|
|
|
} |
|
171
|
|
|
} |
|
172
|
|
|
} |
|
173
|
|
|
$content = ""; |
|
|
|
|
|
|
174
|
|
|
switch ($optioninfo["type"]) { |
|
175
|
|
|
case "string": |
|
176
|
|
|
if (!empty($iterator["$objId-0"])) { |
|
177
|
|
|
if ($objValue == "media:consortium_OI") { |
|
178
|
|
|
$content = valid_consortium_oi($iterator["$objId-0"]); |
|
179
|
|
|
if ($content === FALSE) { |
|
180
|
|
|
$bad[] = $objValue; |
|
181
|
|
|
continue 2; |
|
182
|
|
|
} |
|
183
|
|
|
} elseif ($objValue == "media:remove_SSID") { |
|
184
|
|
|
$content = valid_string_db($iterator["$objId-0"]); |
|
185
|
|
|
if ($content == "eduroam") { |
|
186
|
|
|
$bad[] = $objValue; |
|
187
|
|
|
continue 2; |
|
188
|
|
|
} |
|
189
|
|
|
} else { |
|
190
|
|
|
$content = valid_string_db($iterator["$objId-0"]); |
|
191
|
|
|
} |
|
192
|
|
|
break; |
|
193
|
|
|
} |
|
194
|
|
|
continue 2; |
|
195
|
|
|
case "text": |
|
196
|
|
View Code Duplication |
if (!empty($iterator["$objId-1"])) { |
|
|
|
|
|
|
197
|
|
|
$content = valid_string_db($iterator["$objId-1"], 1); |
|
198
|
|
|
break; |
|
199
|
|
|
} |
|
200
|
|
|
continue 2; |
|
201
|
|
|
case "coordinates": |
|
202
|
|
View Code Duplication |
if (!empty($iterator["$objId-1"])) { |
|
|
|
|
|
|
203
|
|
|
$content = valid_coord_serialized($iterator["$objId-1"]); |
|
204
|
|
|
break; |
|
205
|
|
|
} |
|
206
|
|
|
continue 2; |
|
207
|
|
|
case "file": |
|
208
|
|
|
// echo "In file processing ...<br/>"; |
|
209
|
|
|
if (!empty($iterator["$objId-1"])) { // was already in, by ROWID reference, extract |
|
210
|
|
|
// ROWID means it's a multi-line string (simple strings are inline in the form; so allow whitespace) |
|
211
|
|
|
$content = valid_string_db(urldecode($iterator["$objId-1"]), 1); |
|
212
|
|
|
break; |
|
213
|
|
|
} else if (isset($iterator["$objId-2"]) && ($iterator["$objId-2"] != "")) { // let's do the download |
|
214
|
|
|
// echo "Trying to download file:///".$a["$obj_id-2"]."<br/>"; |
|
215
|
|
|
$content = downloadFile("file:///" . $iterator["$objId-2"]); |
|
216
|
|
|
if (!check_upload_sanity($objValue, $content)) { |
|
217
|
|
|
$bad[] = $objValue; |
|
218
|
|
|
continue 2; |
|
219
|
|
|
} |
|
220
|
|
|
$content = base64_encode($content); |
|
221
|
|
|
break; |
|
222
|
|
|
} |
|
223
|
|
|
continue 2; |
|
224
|
|
|
|
|
225
|
|
|
case "boolean": |
|
226
|
|
View Code Duplication |
if (!empty($iterator["$objId-3"])) { |
|
|
|
|
|
|
227
|
|
|
$content = valid_boolean($iterator["$objId-3"]); |
|
228
|
|
|
break; |
|
229
|
|
|
} |
|
230
|
|
|
continue 2; |
|
231
|
|
|
case "integer": |
|
232
|
|
View Code Duplication |
if (!empty($iterator["$objId-4"])) { |
|
|
|
|
|
|
233
|
|
|
$content = valid_integer($iterator["$objId-4"]); |
|
234
|
|
|
break; |
|
235
|
|
|
} |
|
236
|
|
|
continue 2; |
|
237
|
|
|
default: |
|
238
|
|
|
throw new Exception("Internal Error: Unknown option type " . $objValue . "!"); |
|
239
|
|
|
} |
|
240
|
|
|
if ($lang != "" && preg_match("/^ROWID-.*-([0-9]+)/", $content) == 0) { // new value, encode as language array |
|
241
|
|
|
// add the new option with lang |
|
242
|
|
|
$optionsStep1[] = ["$objValue" => serialize(["lang" => $lang, "content" => $content])]; |
|
243
|
|
|
} else { // just store it (could be a literal value or a ROWID reference) |
|
244
|
|
|
$optionsStep1[] = ["$objValue" => $content]; |
|
245
|
|
|
} |
|
246
|
|
|
} |
|
247
|
|
|
} |
|
248
|
|
|
|
|
249
|
|
|
// Step 2: now we have clean input data. Some attributes need special care: |
|
250
|
|
|
// URL-based attributes need to be downloaded to get their actual content |
|
251
|
|
|
// CA files may need to be split (PEM can contain multiple CAs |
|
252
|
|
|
|
|
253
|
|
|
$optionsStep2 = postProcessValidAttributes($optionsStep1, $good, $bad); |
|
254
|
|
|
|
|
255
|
|
|
|
|
256
|
|
|
// Step 3: coordinates do not follow the usual POST array as they are two values forming one attribute |
|
257
|
|
|
|
|
258
|
|
|
$options = postProcessCoordinates($optionsStep2, $good); |
|
259
|
|
|
|
|
260
|
|
|
// finally, some attributes are in the DB and were only called by reference |
|
261
|
|
|
// keep those which are still referenced, throw the rest away |
|
262
|
|
|
|
|
263
|
|
|
foreach ($options as $iterate_option) { |
|
264
|
|
|
foreach ($iterate_option as $name => $value) { |
|
265
|
|
|
$optiontype = $optioninfoObject->optionType($name); |
|
266
|
|
|
if ($optiontype["type"] == "file" && preg_match("/^ROWID-.*-([0-9]+)/", $value, $retval)) { |
|
267
|
|
|
unset($killlist[$retval[1]]); |
|
268
|
|
|
continue; |
|
269
|
|
|
} |
|
270
|
|
|
if ($object instanceof IdP || $object instanceof User || $object instanceof Federation) { |
|
271
|
|
|
$object->addAttribute($name, $value); |
|
272
|
|
|
} elseif ($object instanceof Profile) { |
|
|
|
|
|
|
273
|
|
|
if ($device !== 0) { |
|
274
|
|
|
$object->addAttributeDeviceSpecific($name, $value, $device); |
|
275
|
|
|
} elseif ($eaptype != 0) { |
|
276
|
|
|
$object->addAttributeEAPSpecific($name, $value, $eaptype); |
|
277
|
|
|
} else { |
|
278
|
|
|
$object->addAttribute($name, $value); |
|
279
|
|
|
} |
|
280
|
|
|
} |
|
281
|
|
|
} |
|
282
|
|
|
} |
|
283
|
|
|
|
|
284
|
|
|
if ($silent == 0) { |
|
285
|
|
|
echo displaySummaryInUI($good, $bad, $multilangAttribsWithC); |
|
|
|
|
|
|
286
|
|
|
} |
|
287
|
|
|
return $killlist; |
|
288
|
|
|
} |
|
289
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.