1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace CILogon\Service; |
4
|
|
|
|
5
|
|
|
use CILogon\Service\Util; |
6
|
|
|
use tubalmartin\CssMin\Minifier as CSSmin; |
7
|
|
|
use PEAR; |
8
|
|
|
use DB; |
9
|
|
|
use Config; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Skin |
13
|
|
|
* |
14
|
|
|
* This class reads in CSS and configuration options |
15
|
|
|
* for a 'skin'. The skin is set by passing the |
16
|
|
|
* '?skin=...' (or '?cilogon_skin=...') query parameter. |
17
|
|
|
* If found, the assoicated config XML and CSS are read |
18
|
|
|
* in from either the filesystem (under the /skin/NAME |
19
|
|
|
* directory) or the database. It also sets a PHP |
20
|
|
|
* session variable so that the skin name is remembered |
21
|
|
|
* across page loads. If no skin name is found, then the |
22
|
|
|
* default /skin/config.xml file is read in. |
23
|
|
|
* |
24
|
|
|
* Note that this class uses the SimpleXML class to parse |
25
|
|
|
* the config XML. This stores the XML in a special |
26
|
|
|
* SimpleXMLElement object, which is NOT an array. But |
27
|
|
|
* you can iterate over elements in the structure. See |
28
|
|
|
* the PHP SimpleXML online manual 'Basic Usage' for |
29
|
|
|
* more information. |
30
|
|
|
* |
31
|
|
|
* This class provides a getConfigOption() method to |
32
|
|
|
* access XML (sub)blocks to get at a config value. |
33
|
|
|
* It is important to rememeber that the values returned |
34
|
|
|
* by the getConfigOption() method must be typecast to |
35
|
|
|
* native datatypes in order to be used effectively. |
36
|
|
|
* |
37
|
|
|
* An example configuration file (with all available options) is at |
38
|
|
|
* /var/www/html/skin/config-example.xml |
39
|
|
|
* |
40
|
|
|
* Example usage: |
41
|
|
|
* require_once 'Skin.php'; |
42
|
|
|
* $skin = new Skin(); |
43
|
|
|
* // While outputting the <head> HTML block... |
44
|
|
|
* $skin->printSkinCSS(); |
45
|
|
|
* // Get the value of a configuration option |
46
|
|
|
* $idpwhitelist = $skin->getConfigOption('idpwhitelist'); |
47
|
|
|
* // Now, process entries in the $idpwhitelist |
48
|
|
|
* if ((!is_null($idpwhitelist)) && (!empty($idpwhitelist->idp))) { |
49
|
|
|
* foreach ($idpwhitelist->idp as $entityID) { |
50
|
|
|
* echo '<p>' , (string)$entityID , "<\p>\n"; |
51
|
|
|
* } |
52
|
|
|
* } |
53
|
|
|
* // Check to see if <hideportalinfo> is set |
54
|
|
|
* $hideportalinfo = false; |
55
|
|
|
* $hpi=$skin->getConfigOption('portallistaction','hideportalinfo'); |
56
|
|
|
* if ((!is_null($hpi)) && ((int)$hpi > 0)) { |
57
|
|
|
* $hideportalinfo = true; |
58
|
|
|
* } |
59
|
|
|
*/ |
60
|
|
|
class Skin |
61
|
|
|
{ |
62
|
|
|
/** |
63
|
|
|
* @var string $skinname The name of the skin |
64
|
|
|
*/ |
65
|
|
|
protected $skinname; |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @var \SimpleXMLElement $configxml A SimpleXMLElement object for the |
69
|
|
|
* config.xml file |
70
|
|
|
*/ |
71
|
|
|
protected $configxml; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* @var string $css The un-minified CSS for the skin |
75
|
|
|
*/ |
76
|
|
|
protected $css; |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @var array $forcearray An array of (URI,skinname) pairs for forcing |
80
|
|
|
* skin application |
81
|
|
|
*/ |
82
|
|
|
protected $forcearray; |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* __construct |
86
|
|
|
* |
87
|
|
|
* Default constructor. Calls init() to do the actual work. |
88
|
|
|
* |
89
|
|
|
* @return Skin A new Skin object. |
90
|
|
|
*/ |
91
|
|
|
public function __construct() |
92
|
|
|
{ |
93
|
|
|
$this->init(); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* init |
98
|
|
|
* |
99
|
|
|
* This function does the work of (re)initializing the skin object. |
100
|
|
|
* It finds the name of the skin (if any) and reads in the skin's |
101
|
|
|
* config XML file (if found). Call this function to reset the |
102
|
|
|
* skin in case of possible forced skin due to IdP or portal |
103
|
|
|
* callbackURL. |
104
|
|
|
* |
105
|
|
|
* @param bool $reset True to reset the 'cilogon_skin' PHP session var |
106
|
|
|
* to blank so that readSkinConfig doesn't check for it. |
107
|
|
|
* Defaults to 'false'. |
108
|
|
|
*/ |
109
|
|
|
public function init($reset = false) |
110
|
|
|
{ |
111
|
|
|
if ($reset) { |
112
|
|
|
Util::unsetSessionVar('cilogon_skin'); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
$this->skinname = ''; |
116
|
|
|
$this->configxml = null; |
117
|
|
|
$this->css = ''; |
118
|
|
|
$this->forcearray = FORCE_SKIN_ARRAY; |
|
|
|
|
119
|
|
|
$this->readSkinConfig(); |
120
|
|
|
$this->setMyProxyInfo(); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* readSkinConfig |
125
|
|
|
* |
126
|
|
|
* This function checks for the name of the skin in several places: |
127
|
|
|
* (1) The FORCE_SKIN_ARRAY for a matching IdP entityID or portal |
128
|
|
|
* callbackURL, (2) in a URL parameter (can be '?skin=', |
129
|
|
|
* '?cilogon_skin=', '?vo='), (3) cilogon_vo form input variable |
130
|
|
|
* (POST for ECP case), or (4) 'cilogon_skin' PHP session |
131
|
|
|
* variable. If it finds the skin name in any of these, it then |
132
|
|
|
* checks to see if such a named skin exists, either on the filesystem |
133
|
|
|
* or in the database. If found, the class variable $skinname AND the |
134
|
|
|
* 'cilogon_skin' PHP session variable (for use on future page |
135
|
|
|
* loads by the user) are set. It then reads in the config XML and the |
136
|
|
|
* CSS and stores them in the class variables $configxml and $css. |
137
|
|
|
* If no skin name is found, read in the default /skin/config.xml file. |
138
|
|
|
* |
139
|
|
|
* Side Effect: Sets the 'cilogon_skin' session variable if needed. |
140
|
|
|
*/ |
141
|
|
|
protected function readSkinConfig() |
142
|
|
|
{ |
143
|
|
|
$skinvar = ''; |
144
|
|
|
|
145
|
|
|
// Check for matching IdP, callbackURI (OAuth1), |
146
|
|
|
// redirect_uri (OAuth2), or client_id (OAuth2) |
147
|
|
|
// in the FORCE_SKIN_ARRAY. |
148
|
|
|
$uristocheck = array( |
149
|
|
|
Util::getGetVar('redirect_uri'), |
150
|
|
|
Util::getGetVar('client_id'), |
151
|
|
|
Util::getSessionVar('callbackuri'), |
152
|
|
|
Util::getSessionVar('idp') |
153
|
|
|
); |
154
|
|
|
|
155
|
|
|
foreach ($uristocheck as $value) { |
156
|
|
|
if (strlen($value) > 0) { |
157
|
|
|
$skin = $this->getForceSkin($value); |
158
|
|
|
if (strlen($skin) > 0) { |
159
|
|
|
$skinvar = $skin; |
160
|
|
|
break; |
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
// If no force skin found, check GET and POST parameters, as well as |
166
|
|
|
// previously set cilogon_skin PHP session variable. |
167
|
|
|
if (strlen($skinvar) == 0) { |
168
|
|
|
// First, look for '?skin=...' |
169
|
|
|
$skinvar = Util::getGetVar('skin'); |
170
|
|
|
} |
171
|
|
|
if (strlen($skinvar) == 0) { |
172
|
|
|
// Next, look for '?cilogon_skin=...' |
173
|
|
|
$skinvar = Util::getGetVar('cilogon_skin'); |
174
|
|
|
} |
175
|
|
|
if (strlen($skinvar) == 0) { |
176
|
|
|
// Next, look for '?vo=...' |
177
|
|
|
$skinvar = Util::getGetVar('vo'); |
178
|
|
|
} |
179
|
|
|
if (strlen($skinvar) == 0) { |
180
|
|
|
// Next, check 'cilogon_vo' form input variable |
181
|
|
|
$skinvar = Util::getPostVar('cilogon_vo'); |
182
|
|
|
} |
183
|
|
|
if (strlen($skinvar) == 0) { |
184
|
|
|
// Finally, check 'cilogon_skin' PHP session variable |
185
|
|
|
$skinvar = Util::getSessionVar('cilogon_skin'); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
// If we found $skinvar, attempt to read the skin config/css from |
189
|
|
|
// either the filesystem or the database, or failing that, read the |
190
|
|
|
// default /skin/config.xml file. |
191
|
|
|
if (strlen($skinvar) > 0) { |
192
|
|
|
$skinvar = strtolower($skinvar); // All skin dirs are lowercase |
193
|
|
|
$this->readSkinFromFile($skinvar) || |
194
|
|
|
$this->readSkinFromDatabase($skinvar) || |
195
|
|
|
$this->readDefaultSkin(); |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* readSkinFromFile |
201
|
|
|
* |
202
|
|
|
* This function reads in the skin config XML and CSS from the |
203
|
|
|
* filesystem into the class variables $configxml and $css. |
204
|
|
|
* |
205
|
|
|
* @param string $skinvar The name of the skin as found by |
206
|
|
|
* readSkinConfig(). |
207
|
|
|
* @return bool True if at least one of config.xml or skin.css could |
208
|
|
|
* be found (and read in) for the skin (i.e., the skin |
209
|
|
|
* directory exists and isn't empty). False otherwise. |
210
|
|
|
*/ |
211
|
|
|
protected function readSkinFromFile($skinvar) |
212
|
|
|
{ |
213
|
|
|
$readin = false; // Make sure we read in either XML or CSS (or both) |
214
|
|
|
|
215
|
|
|
$skindir = Util::getServerVar('DOCUMENT_ROOT') . "/skin/$skinvar"; |
216
|
|
|
if (is_dir($skindir)) { |
217
|
|
|
// Read in the config XML |
218
|
|
|
$skinconf = $skindir . '/config.xml'; |
219
|
|
|
if (is_readable($skinconf)) { |
220
|
|
|
if (($xml = @simplexml_load_file($skinconf)) !== false) { |
221
|
|
|
$this->configxml = $xml; |
222
|
|
|
$readin = true; |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
//Read in the CSS |
226
|
|
|
$skincss = $skindir . '/skin.css'; |
227
|
|
|
if (is_readable($skincss)) { |
228
|
|
|
if (($css = file_get_contents($skincss)) !== false) { |
229
|
|
|
$this->css = $css; |
230
|
|
|
$readin = true; |
231
|
|
|
} |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
if ($readin) { |
236
|
|
|
$this->skinname = $skinvar; |
237
|
|
|
Util::setSessionVar('cilogon_skin', $skinvar); |
238
|
|
|
} else { |
239
|
|
|
Util::unsetSessionVar('cilogon_skin'); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
return $readin; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* readSkinFromDatabase |
247
|
|
|
* |
248
|
|
|
* This function reads in the skin config XML and CSS from the |
249
|
|
|
* database into the class variables $configxml and $css. |
250
|
|
|
* |
251
|
|
|
* @param string $skinvar The name of the skin as found by |
252
|
|
|
* readSkinConfig(). |
253
|
|
|
* @return bool True if at least one of config XML or CSS could |
254
|
|
|
* be read from the database for the skin. False otherwise. |
255
|
|
|
*/ |
256
|
|
|
protected function readSkinFromDatabase($skinvar) |
257
|
|
|
{ |
258
|
|
|
$readin = false; // Make sure we read in either XML or CSS (or both) |
259
|
|
|
|
260
|
|
|
if (strlen($skinvar) > 0) { |
261
|
|
|
$dsn = array( |
262
|
|
|
'phptype' => 'mysqli', |
263
|
|
|
'username' => MYSQLI_USERNAME, |
|
|
|
|
264
|
|
|
'password' => MYSQLI_PASSWORD, |
|
|
|
|
265
|
|
|
'database' => 'ciloa2', |
266
|
|
|
'hostspec' => 'localhost' |
267
|
|
|
); |
268
|
|
|
|
269
|
|
|
$opts = array( |
270
|
|
|
'persistent' => true, |
271
|
|
|
'portability' => DB_PORTABILITY_ALL |
272
|
|
|
); |
273
|
|
|
|
274
|
|
|
$db = DB::connect($dsn, $opts); |
275
|
|
|
if (!PEAR::isError($db)) { |
276
|
|
|
$data = $db->getRow( |
277
|
|
|
'SELECT * from skins WHERE name = ?', |
278
|
|
|
array($skinvar), |
279
|
|
|
DB_FETCHMODE_ASSOC |
280
|
|
|
); |
281
|
|
|
if ((!DB::isError($data)) && (!empty($data))) { |
282
|
|
|
// Read in the config XML |
283
|
|
|
if ( |
284
|
|
|
(strlen(@$data['config']) > 0) && |
285
|
|
|
(($xml = @simple_xml_load_string($data['config'])) !== false) |
|
|
|
|
286
|
|
|
) { |
287
|
|
|
$this->configxml = $xml; |
288
|
|
|
$readin = true; |
289
|
|
|
} |
290
|
|
|
//Read in the CSS |
291
|
|
|
if (strlen(@$data['css']) > 0) { |
292
|
|
|
$this->css = $data['css']; |
293
|
|
|
$readin = true; |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
$db->disconnect(); |
297
|
|
|
} |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
if ($readin) { |
301
|
|
|
$this->skinname = $skinvar; |
302
|
|
|
Util::setSessionVar('cilogon_skin', $skinvar); |
303
|
|
|
} else { |
304
|
|
|
Util::unsetSessionVar('cilogon_skin'); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
return $readin; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* readDefaultSkin |
312
|
|
|
* |
313
|
|
|
* If we don't read a skin from the filesystem or the database, then |
314
|
|
|
* read in the default "/skin/config.xml" file. |
315
|
|
|
* |
316
|
|
|
* @return bool True if the default config.xml file was read in. |
317
|
|
|
* False otherwise. |
318
|
|
|
*/ |
319
|
|
|
protected function readDefaultSkin() |
320
|
|
|
{ |
321
|
|
|
$readin = false; |
322
|
|
|
|
323
|
|
|
$this->skinname = ''; |
324
|
|
|
$this->css = ''; |
325
|
|
|
Util::unsetSessionVar('cilogon_skin'); |
326
|
|
|
|
327
|
|
|
$skinconf = Util::getServerVar('DOCUMENT_ROOT') . '/skin/config.xml'; |
328
|
|
|
if (is_readable($skinconf)) { |
329
|
|
|
if (($xml = @simplexml_load_file($skinconf)) !== false) { |
330
|
|
|
$this->configxml = $xml; |
331
|
|
|
$readin = true; |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
return $readin; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* getConfigOption |
340
|
|
|
* |
341
|
|
|
* This method returns a SimpleXMLElement block corresponding to |
342
|
|
|
* the passed in arguments. For example, to get the blacklist of |
343
|
|
|
* idps, call $idps = getConfigOption('idpblacklist') and then |
344
|
|
|
* iterate over $idps with foreach($idps as $idp) { ... }. To get |
345
|
|
|
* a single subblock value such as the initial lifetime number for |
346
|
|
|
* the PKCS12 download option, call $life = |
347
|
|
|
* (int)getConfigOption('pkcs12','initiallifetime','number'). Note |
348
|
|
|
* that you should explicitly cast the values to int, string, |
349
|
|
|
* float, etc., when you use them. |
350
|
|
|
* |
351
|
|
|
* @param mixed $args Variable number of parameters corresponding to XML |
352
|
|
|
* blocks (and possible sub-blocks). |
353
|
|
|
* @return \SimpleXMLElement|null A SimpleXMLElement corresponding to the |
354
|
|
|
* passed-in XML option, or 'null' if no such option exists. |
355
|
|
|
*/ |
356
|
|
|
public function getConfigOption(...$args) |
357
|
|
|
{ |
358
|
|
|
$retval = null; |
359
|
|
|
$numargs = count($args); |
360
|
|
|
if ($numargs > 0) { |
361
|
|
|
$retval = $this->configxml; |
362
|
|
|
} |
363
|
|
|
for ($i = 0; $i < $numargs; $i++) { |
364
|
|
|
$argval = $args[$i]; |
365
|
|
|
if (empty($retval->$argval)) { |
366
|
|
|
$retval = null; |
367
|
|
|
break; |
368
|
|
|
} else { |
369
|
|
|
$retval = $retval->$argval; |
370
|
|
|
} |
371
|
|
|
} |
372
|
|
|
return $retval; |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* printSkinCSS |
377
|
|
|
* |
378
|
|
|
* Call this function in the HTML <head> block to print out the |
379
|
|
|
* <style> tag for the internal CSS of the skin. The CSS is minified |
380
|
|
|
* to remove whitespace. Note that you should call readSkinConfig |
381
|
|
|
* to set the contents of $css. |
382
|
|
|
*/ |
383
|
|
|
public function printSkinCSS() |
384
|
|
|
{ |
385
|
|
|
if (strlen($this->css) > 0) { |
386
|
|
|
$cssmin = new CSSmin(); |
387
|
|
|
$cssmin->removeImportantComments(); |
388
|
|
|
$cssmin->setLineBreakPosition(255); |
389
|
|
|
$outputcss = $cssmin->run($this->css); |
390
|
|
|
echo "<style>$outputcss</style>"; |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* hasIdpWhitelist |
396
|
|
|
* |
397
|
|
|
* This function checks for the presence of a <idpwhitelist> block |
398
|
|
|
* in the skin's config file. There must be at least one <idp> |
399
|
|
|
* in the <idpwhitelist>. |
400
|
|
|
* |
401
|
|
|
* @return bool True if skin has a non-empty <idpwhitelist>. |
402
|
|
|
*/ |
403
|
|
|
public function hasIdpWhitelist() |
404
|
|
|
{ |
405
|
|
|
$retval = false; // Assume no <idpwhitelist> configured |
406
|
|
|
$idpwhitelist = $this->getConfigOption('idpwhitelist'); |
407
|
|
|
if ((!is_null($idpwhitelist)) && (!empty($idpwhitelist->idp))) { |
408
|
|
|
$retval = true; |
409
|
|
|
} |
410
|
|
|
return $retval; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* hasIdpBlacklist |
415
|
|
|
* |
416
|
|
|
* This function checks for the presence of a <idpblacklist> block |
417
|
|
|
* in the skin's config file. There must be at least one <idp> |
418
|
|
|
* in the <idpblacklist>. |
419
|
|
|
* |
420
|
|
|
* @return bool True if skin has a non-empty <idpblacklist>. |
421
|
|
|
*/ |
422
|
|
|
public function hasIdpBlacklist() |
423
|
|
|
{ |
424
|
|
|
$retval = false; // Assume no <idpblacklist> configured |
425
|
|
|
$idpblacklist = $this->getConfigOption('idpblacklist'); |
426
|
|
|
if ((!is_null($idpblacklist)) && (!empty($idpblacklist->idp))) { |
427
|
|
|
$retval = true; |
428
|
|
|
} |
429
|
|
|
return $retval; |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
/** |
433
|
|
|
* idpWhitelisted |
434
|
|
|
* |
435
|
|
|
* This method checks to see if a given entityId of an IdP |
436
|
|
|
* is whitelisted. 'Whitelisted' in this case means either (a) the |
437
|
|
|
* entityId is in the skin's <idpwhitelist> list or (b) the skin |
438
|
|
|
* doesn't have a <idpwhitelist> at all. In the second case, all |
439
|
|
|
* IdPs are by default 'whitelisted'. If you want to find if an |
440
|
|
|
* IdP should be listed in the WAYF, use 'idpAvailable' which |
441
|
|
|
* checks the whitelist AND the blacklist. |
442
|
|
|
* |
443
|
|
|
* @param string $entityId The entityId of an IdP to check for |
444
|
|
|
* whitelisting. |
445
|
|
|
* @return bool True if the given IdP entityId is in the skin's |
446
|
|
|
* whitelist (or if the skin doesn't have a whitelist). |
447
|
|
|
*/ |
448
|
|
|
public function idpWhitelisted($entityId) |
449
|
|
|
{ |
450
|
|
|
$retval = true; // Assume the entityId is 'whitelisted' |
451
|
|
|
if ($this->hasIdpWhitelist()) { |
452
|
|
|
$idpwhitelist = $this->getConfigOption('idpwhitelist'); |
453
|
|
|
$found = false; |
454
|
|
|
foreach ($idpwhitelist->idp as $whiteidp) { |
455
|
|
|
if ($entityId == ((string)$whiteidp)) { |
456
|
|
|
$found = true; |
457
|
|
|
break; |
458
|
|
|
} |
459
|
|
|
} |
460
|
|
|
if (!$found) { |
461
|
|
|
$retval = false; |
462
|
|
|
} |
463
|
|
|
} |
464
|
|
|
return $retval; |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
/** |
468
|
|
|
* idpBlacklisted |
469
|
|
|
* |
470
|
|
|
* This method checks to see if a given entityId of an IdP |
471
|
|
|
* appears in the skin's <idpblacklist>. |
472
|
|
|
* |
473
|
|
|
* @param string $entityId The entityId of an IdP to check for |
474
|
|
|
* blacklisting. |
475
|
|
|
* @return bool True if the given IdP entityId is in the skin's |
476
|
|
|
* blacklist. |
477
|
|
|
*/ |
478
|
|
|
public function idpBlacklisted($entityId) |
479
|
|
|
{ |
480
|
|
|
$retval = false; // Assume entityId is NOT in the idpblacklist |
481
|
|
|
if ($this->hasIdpBlacklist()) { |
482
|
|
|
$idpblacklist = $this->getConfigOption('idpblacklist'); |
483
|
|
|
foreach ($idpblacklist->idp as $blackidp) { |
484
|
|
|
if ($entityId == ((string)$blackidp)) { |
485
|
|
|
$retval = true; |
486
|
|
|
break; |
487
|
|
|
} |
488
|
|
|
} |
489
|
|
|
} |
490
|
|
|
return $retval; |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
/** |
494
|
|
|
* idpAvailable |
495
|
|
|
* |
496
|
|
|
* This method combines idpWhitelisted and idpBlacklisted to return |
497
|
|
|
* a 'yes/no' for if a given IdP should be made available for |
498
|
|
|
* selection in the WAYF. It first checks to see if the IdP is |
499
|
|
|
* whitelisted. If not, it returns false. Otherwise, it then |
500
|
|
|
* checks if the IdP is blacklisted. If not, it returns true. |
501
|
|
|
* |
502
|
|
|
* @param string $entityId The entityId of an IdP to check to see if it |
503
|
|
|
* should be available in the WAYF. |
504
|
|
|
* @return bool True if the given IdP entityId is available to be |
505
|
|
|
* selected in the WAYF. |
506
|
|
|
*/ |
507
|
|
|
public function idpAvailable($entityId) |
508
|
|
|
{ |
509
|
|
|
$retval = false; // Assume IdP is not available in the WAYF |
510
|
|
|
if ( |
511
|
|
|
($this->idpWhitelisted($entityId)) && |
512
|
|
|
(!$this->idpBlacklisted($entityId)) |
513
|
|
|
) { |
514
|
|
|
$retval = true; |
515
|
|
|
} |
516
|
|
|
return $retval; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
/** |
520
|
|
|
* setMyProxyInfo |
521
|
|
|
* |
522
|
|
|
* This method sets the 'myproxyinfo' PHP session variable. The |
523
|
|
|
* variable has the form 'info:key1=value1,key2=value2,...' and is |
524
|
|
|
* passed to the 'myproxy-logon' command as part of the username |
525
|
|
|
* when fetching a credential. The MyProxy server will do extra |
526
|
|
|
* processing based on the content of this 'info:...' tag. If the |
527
|
|
|
* skinname is not empty, that is added to the info tag. Also, |
528
|
|
|
* the apache REMOTE_ADDR is added. For other key=value pairs that |
529
|
|
|
* get added, see the code below. |
530
|
|
|
*/ |
531
|
|
|
public function setMyProxyInfo() |
532
|
|
|
{ |
533
|
|
|
$infostr = ''; |
534
|
|
|
|
535
|
|
|
// Add the skinname if available |
536
|
|
|
if (strlen($this->skinname) > 0) { |
537
|
|
|
$infostr .= 'cilogon_skin=' . $this->skinname; |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
// Add the REMOTE_ADDR |
541
|
|
|
$remoteaddr = Util::getServerVar('REMOTE_ADDR'); |
542
|
|
|
if (strlen($remoteaddr) > 0) { |
543
|
|
|
$infostr .= (strlen($infostr) > 0 ? ',' : '') . |
544
|
|
|
"remote_addr=$remoteaddr"; |
545
|
|
|
} |
546
|
|
|
|
547
|
|
|
// Add eppn, eptid, open_id, and oidc if available |
548
|
|
|
// Note that these values are lowercase after an update to make |
549
|
|
|
// them the same as those used by the dbService. BUT, MyProxy |
550
|
|
|
// expects the old versions. So this array maps the new lowercase |
551
|
|
|
// versions back into the old ones. |
552
|
|
|
$mpid = array( |
553
|
|
|
'eppn' => 'ePPN', |
554
|
|
|
'eptid' => 'ePTID', |
555
|
|
|
'open_id' => 'openidID', |
556
|
|
|
'oidc' => 'oidcID' |
557
|
|
|
); |
558
|
|
|
foreach (array('eppn','eptid','open_id','oidc') as $id) { |
559
|
|
|
$sessvar = Util::getSessionVar($id); |
560
|
|
|
if (strlen($sessvar) > 0) { |
561
|
|
|
$infostr .= (strlen($infostr) > 0 ? ',' : '') . |
562
|
|
|
$mpid[$id] . "=" . $sessvar; |
563
|
|
|
} |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
// Finally, set the 'myproxyinfo' PHP session variable |
567
|
|
|
if (strlen($infostr) > 0) { |
568
|
|
|
Util::setSessionVar('myproxyinfo', 'info:' . $infostr); |
569
|
|
|
} else { |
570
|
|
|
Util::unsetSessionVar('myproxyinfo'); |
571
|
|
|
} |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
/** |
575
|
|
|
* hasPortalList |
576
|
|
|
* |
577
|
|
|
* This function checks for the presence of a <portallist> block in |
578
|
|
|
* the skin's config file. There must be at least one <portal> in |
579
|
|
|
* the <portallist>. |
580
|
|
|
* |
581
|
|
|
* @return bool True if skin has a non-empty <portallist>. |
582
|
|
|
*/ |
583
|
|
|
public function hasPortalList() |
584
|
|
|
{ |
585
|
|
|
$retval = false; // Assume no <portallist> configured |
586
|
|
|
$portallist = $this->getConfigOption('portallist'); |
587
|
|
|
if ((!is_null($portallist)) && (!empty($portallist->portal))) { |
588
|
|
|
$retval = true; |
589
|
|
|
} |
590
|
|
|
return $retval; |
591
|
|
|
} |
592
|
|
|
|
593
|
|
|
/** |
594
|
|
|
* inPortalList |
595
|
|
|
* |
596
|
|
|
* This function takes in a 'callback' URL of a portal passed to |
597
|
|
|
* the CILogon Delegate service. It then looks through the list |
598
|
|
|
* of <portal> patterns in the skin's <portallist>. If the |
599
|
|
|
* callback URL matches any of these patterns, true is returned. |
600
|
|
|
* This is used to hide the 'Site Name / Site URL / Service URL' |
601
|
|
|
* box on the delegation WAYF page, for example. |
602
|
|
|
* |
603
|
|
|
* @param string $portalurl A 'callback' URL of a portal accessing the |
604
|
|
|
* delegate service. |
605
|
|
|
* @return bool True if the callback URL matches one of the patterns |
606
|
|
|
* in the skin's <portallist>. False otherwise. |
607
|
|
|
*/ |
608
|
|
|
public function inPortalList($portalurl) |
609
|
|
|
{ |
610
|
|
|
$retval = false; // Assume the portalurl not a listed <portal> |
611
|
|
|
if ($this->hasPortalList()) { |
612
|
|
|
$portallist = $this->getConfigOption('portallist'); |
613
|
|
|
foreach ($portallist->portal as $portalmatch) { |
614
|
|
|
if (preg_match(((string)$portalmatch), $portalurl)) { |
615
|
|
|
$retval = true; |
616
|
|
|
break; |
617
|
|
|
} |
618
|
|
|
} |
619
|
|
|
} |
620
|
|
|
return $retval; |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/** |
624
|
|
|
* getForceSkin |
625
|
|
|
* |
626
|
|
|
* The FORCE_SKIN_ARRAY contains 'uripattern'=>'skinname' pairs |
627
|
|
|
* corresponding to IdP entityIDs, portal callbackurls, or client_ids |
628
|
|
|
* that should have a particular skin force-applied. This function |
629
|
|
|
* looks in the FORCE_SKIN_ARRAY for a pattern-matched URI and returns |
630
|
|
|
* the corresponding skin name if found. If not found, empty |
631
|
|
|
* string is returned. |
632
|
|
|
* |
633
|
|
|
* @param string $uri A URI to search for in the FORCE_SKIN_ARRAY. |
634
|
|
|
* @return string The skin name for the URI, or empty string if not |
635
|
|
|
* found. |
636
|
|
|
*/ |
637
|
|
|
protected function getForceSkin($uri) |
638
|
|
|
{ |
639
|
|
|
$retval = ''; // Assume uri is not in FORCE_SKIN_ARRAY |
640
|
|
|
|
641
|
|
|
foreach ($this->forcearray as $key => $value) { |
642
|
|
|
if (preg_match($key, $uri)) { |
643
|
|
|
$retval = $value; |
644
|
|
|
break; |
645
|
|
|
} |
646
|
|
|
} |
647
|
|
|
return $retval; |
648
|
|
|
} |
649
|
|
|
} |
650
|
|
|
|