| [ Index ] |
|
Code source de eZ Publish 3.9.0 |
1 <?php 2 // 3 // Definition of eZSSLZone class 4 // 5 // Created on: <12-Jul-2005 13:01:07 vs> 6 // 7 // SOFTWARE NAME: eZ publish 8 // SOFTWARE RELEASE: 3.9.0 9 // BUILD VERSION: 17785 10 // COPYRIGHT NOTICE: Copyright (C) 1999-2006 eZ systems AS 11 // SOFTWARE LICENSE: GNU General Public License v2.0 12 // NOTICE: > 13 // This program is free software; you can redistribute it and/or 14 // modify it under the terms of version 2.0 of the GNU General 15 // Public License as published by the Free Software Foundation. 16 // 17 // This program is distributed in the hope that it will be useful, 18 // but WITHOUT ANY WARRANTY; without even the implied warranty of 19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 // GNU General Public License for more details. 21 // 22 // You should have received a copy of version 2.0 of the GNU General 23 // Public License along with this program; if not, write to the Free 24 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 25 // MA 02110-1301, USA. 26 // 27 // 28 29 30 /*! 31 \class eZSSLZone ezsslzone.php 32 \brief SSL zones handling functionality. 33 34 Using functionality of this class you can mark certain parts of you site 35 as "SSL zones". After that users will be able to access those parts only over SSL. 36 When entering an SSL zone, user will be automatically switched to SSL. 37 When leaving an SSL zone, user will be automatically switched to plain HTTP. 38 Such a switch is called "access mode change" in the comments below. 39 40 SSL zones may be defined on either module/view basis, or on subtree basis. 41 42 For more details pleaase see doc/feautures/3.8/ssl_zones.txt 43 */ 44 45 include_once ( 'lib/ezutils/classes/ezini.php' ); 46 include_once ( 'lib/ezutils/classes/ezsys.php' ); 47 48 class eZSSLZone 49 { 50 /*! \privatesection */ 51 52 /** 53 * \static 54 * Returns true if the SSL zones functionality is enabled, false otherwise. 55 * The result is cached in memory to save time on multiple invocations. 56 */ 57 function enabled() 58 { 59 if ( isset( $GLOBALS['eZSSLZoneEnabled'] ) ) 60 return $GLOBALS['eZSSLZoneEnabled']; 61 62 $enabled = false; 63 $ini =& eZINI::instance(); 64 if ( $ini->hasVariable( 'SSLZoneSettings', 'SSLZones' ) ) 65 $enabled = ( $ini->variable( 'SSLZoneSettings', 'SSLZones' ) == 'enabled' ); 66 67 return $GLOBALS['eZSSLZoneEnabled'] = $enabled; 68 } 69 70 /** 71 * \static 72 */ 73 function cacheFileName() 74 { 75 include_once ( 'lib/ezutils/classes/ezsys.php' ); 76 include_once ( 'lib/ezfile/classes/ezdir.php' ); 77 return eZDir::path( array( eZSys::cacheDirectory(), 'ssl_zones_cache.php' ) ); 78 } 79 80 /** 81 * \static 82 */ 83 function clearCacheIfNeeded() 84 { 85 if ( eZSSLZone::enabled() ) 86 eZSSLZone::clearCache(); 87 } 88 89 /** 90 * \static 91 */ 92 function clearCache() 93 { 94 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 'Clearing caches.' ); 95 96 // clear in-memory cache 97 unset( $GLOBALS['eZSSLZonesCachedPathStrings'] ); 98 99 // and remove cache file 100 $cacheFileName = eZSSLZone::cacheFileName(); 101 if ( file_exists( $cacheFileName ) ) 102 unlink( $cacheFileName ); 103 } 104 105 /** 106 * \static 107 * Load content SSL zones definitions. 108 * Substitute URIs with corresponding path strings 109 * (e.g. "/news" would be subsituted with "/1/2/50"). 110 * The result is cached in memory to save time on multiple invocations. 111 * It is also saved in a cache file that is usually updated by eZContentCacheManager along with content cache. 112 */ 113 function getSSLZones() 114 { 115 if ( !isset( $GLOBALS['eZSSLZonesCachedPathStrings'] ) ) // if in-memory cache does not exist 116 { 117 $cacheFileName = eZSSLZone::cacheFileName(); 118 119 // if file cache does not exist then create it 120 if ( !is_readable( $cacheFileName ) ) 121 { 122 $ini =& eZINI::instance(); 123 $sslSubtrees = $ini->variable( 'SSLZoneSettings', 'SSLSubtrees' ); 124 125 if ( !isset( $sslSubtrees ) || !$sslSubtrees ) 126 return array(); 127 128 // if there are some content SSL zones defined in the ini settings 129 // then let's calculate path strings for them 130 $pathStringsArray = array(); 131 foreach ( $sslSubtrees as $uri ) 132 { 133 $node = eZContentObjectTreeNode::fetchByURLPath( preg_replace( '/^\//', '', $uri ) ); 134 if ( !is_object( $node ) ) 135 { 136 eZDebug::writeError( "cannot fetch node by URI '$uri'", 'eZSSLZone::getSSLZones' ); 137 continue; 138 } 139 $pathStringsArray[$uri] = $node->attribute( 'path_string' ); 140 unset( $node ); 141 } 142 143 // write calculated path strings to the file 144 $fh = fopen( $cacheFileName, 'w' ); 145 fwrite( $fh, "<?php\n\$pathStringsArray = " . var_export( $pathStringsArray, true ) . ";\n?>" ); 146 fclose( $fh ); 147 148 return $GLOBALS['eZSSLZonesCachedPathStrings'] = $pathStringsArray; 149 } 150 else // if the cache file exists 151 { 152 // let's read its contents and return them 153 include_once( $cacheFileName ); // stores array to $pathStringsArray 154 return $GLOBALS['eZSSLZonesCachedPathStrings'] = $pathStringsArray; 155 } 156 } 157 158 // else if in-memory cache already exists then return its contents 159 $pathStringsArray = $GLOBALS['eZSSLZonesCachedPathStrings']; 160 161 return $pathStringsArray; 162 } 163 164 /** 165 * \static 166 * Checks if a given module/view pair is in the given list of views. 167 * Wildcard matching on view name is done. 168 * 169 * \return 2 if wildcard match occurs on the given view 170 * 1 if exact match occurs on the given view 171 * 0 if the view is not found in the list 172 */ 173 function viewIsInArray( $module, $view, $moduleViews ) 174 { 175 if ( in_array( "$module/$view", $moduleViews ) ) 176 return 2; 177 if ( in_array( "$module/*", $moduleViews ) ) 178 return 1; 179 return 0; 180 } 181 182 /** 183 * \static 184 * \return true if the view is defined as 'keep' 185 */ 186 function isKeepModeView( $module, $view ) 187 { 188 $ini =& eZINI::instance(); 189 $viewsModes = $ini->variable( 'SSLZoneSettings', 'ModuleViewAccessMode' ); 190 $sslViews = array_keys( $viewsModes, 'ssl' ); 191 $keepModeViews = array_keys( $viewsModes, 'keep' ); 192 193 if ( eZSSLZone::viewIsInArray( $module, $view, $keepModeViews ) < 194 eZSSLZone::viewIsInArray( $module, $view, $sslViews ) ) 195 { 196 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 'The view cannot choose access mode itself.' ); 197 return false; 198 } 199 200 return true; 201 } 202 203 /** 204 * \static 205 * \param $inSSL The desired access mode. 206 * 207 * Change access mode (HTTP/HTTPS): 208 * - If previous mode was HHTP but $inSSL is true, we switch to SSL. 209 * - If previous mode was SSL but $inSSL is false, we switch to HTTP. 210 * - Otherwise no mode change is occured. 211 * 212 * Mode change is done by redirect to the same URL, but with changed 213 * protocol (http/https) and TCP port. 214 * 215 * In case of mode change this method does not return (exit() is called). 216 */ 217 function switchIfNeeded( $inSSL ) 218 { 219 // if it's undefined whether we should redirect we do nothing 220 if ( !isset( $inSSL ) ) 221 return; 222 223 // $nowSSl is true if current access mode is HTTPS. 224 $nowSSL = eZSys::isSSLNow(); 225 226 $requestURI = eZSys::requestURI(); 227 228 $sslZoneRedirectionURL = false; 229 if ( $nowSSL && !$inSSL ) 230 { 231 // switch to plain HTTP 232 $ini =& eZINI::instance(); 233 $host = $ini->variable( 'SiteSettings', 'SiteURL' ); 234 $sslZoneRedirectionURL = "http://" . $host . $requestURI; 235 } 236 elseif ( !$nowSSL && $inSSL ) 237 { 238 // switch to HTTPS 239 $host = preg_replace( '/:\d+$/', '', $host = eZSys::serverVariable( 'HTTP_HOST' ) ); 240 $sslPortString = ( $sslPort == EZSSLZONE_DEFAULT_SSL_PORT ) ? '' : ":$sslPort"; 241 $indexDir = eZSys::indexDir( false ); 242 $sslZoneRedirectionURL = "https://" . $host . $sslPortString . $indexDir . $requestURI; 243 } 244 245 if ( $sslZoneRedirectionURL ) // if a redirection URL is found 246 { 247 eZDebugSetting::writeDebug( 'kernel-ssl-zone', "redirecting to [$sslZoneRedirectionURL]" ); 248 eZHTTPTool::redirect( $sslZoneRedirectionURL ); 249 eZExecution::cleanExit(); 250 } 251 } 252 253 /*! \publicsection */ 254 255 /** 256 * \static 257 * Check whether the given node should cause access mode change. 258 * It it should, this method does not return. 259 * 260 * \see checkNode() 261 */ 262 function checkNodeID( $module, $view, $nodeID ) 263 { 264 if ( !eZSSLZone::enabled() ) 265 return; 266 267 /* If the given module/view is not in the list of 'keep mode' views, 268 * i.e. it cannot choose access mode itself, 269 * then do nothing. 270 */ 271 if ( !eZSSLZone::isKeepModeView( $module, $view ) ) 272 return; 273 274 // Fetch path string for the given node. 275 $pathStrings = eZPersistentObject::fetchObjectList( 276 eZContentObjectTreeNode::definition(), // def 277 array( 'path_string' ), // field_filters 278 array( 'node_id' => $nodeID ), // conds 279 null, // sorts 280 null, // limit 281 false // asObject 282 ); 283 284 if ( !$pathStrings ) 285 { 286 eZDebug::writeError( "Node #$nodeID not found", "eZSSLZone::checkNodeID" ); 287 return; 288 } 289 290 eZSSLZone::checkNodePath( $module, $view, $pathStrings[0]['path_string'] ); 291 } 292 293 /** 294 * \static 295 * Check whether the given node should cause access mode change. 296 * It it should, this method does not return. 297 */ 298 function checkNode( $module, $view, &$node, $redirect = true ) 299 { 300 if ( !eZSSLZone::enabled() ) 301 return; 302 303 /* If the given module/view is not in the list of 'keep mode' views, 304 * i.e. it cannot choose access mode itself, 305 * then do nothing. 306 */ 307 if ( !$redirect && !eZSSLZone::isKeepModeView( $module, $view ) ) 308 return; 309 310 include_once ( 'kernel/classes/ezcontentobjecttreenode.php' ); 311 $pathString = $node->attribute( 'path_string' ); 312 313 return eZSSLZone::checkNodePath( $module, $view, $pathString, $redirect ); 314 } 315 316 /** 317 * \static 318 * Check whether the given node should cause access mode change. 319 * It it should, this method does not return. 320 */ 321 function checkNodePath( $module, $view, $pathString, $redirect = true ) 322 { 323 if ( !eZSSLZone::enabled() ) 324 return; 325 326 /* If the given module/view is not in the list of 'keep mode' views, 327 * i.e. it cannot choose access mode itself, 328 * then do nothing. 329 */ 330 if ( !$redirect && !eZSSLZone::isKeepModeView( $module, $view ) ) 331 return; 332 333 // Decide whether the node belongs to an SSL zone or not. 334 $sslZones = eZSSLZone::getSSLZones(); 335 336 $inSSLZone = false; 337 foreach ( $sslZones as $sslZonePathString ) 338 { 339 if ( strpos( $pathString, $sslZonePathString ) === 0 ) 340 { 341 $inSSLZone = true; 342 break; 343 } 344 } 345 346 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 347 ( $inSSLZone ? 'yes' : 'no' ), 348 "Does the node having path $pathString belong to an SSL zone?" ); 349 350 if ( $redirect ) 351 eZSSLZone::switchIfNeeded( $inSSLZone ); 352 353 return $inSSLZone; 354 } 355 356 /** 357 * \static 358 * Check whether the given object should cause access mode change. 359 * It it should, this method does not return. 360 */ 361 function checkObject( $module, $view, $object ) 362 { 363 if ( !eZSSLZone::enabled() ) 364 return; 365 366 /* If the given module/view is not in the list of 'keep mode' views, 367 * i.e. it cannot choose access mode itself, 368 * then do nothing. 369 */ 370 if ( !eZSSLZone::isKeepModeView( $module, $view ) ) 371 return; 372 373 $pathStringList = eZPersistentObject::fetchObjectList( 374 eZContentObjectTreeNode::definition(), // def 375 array( 'path_string' ), // field_filters 376 array( 'contentobject_id' => $object->attribute( 'id' ) ), // conds 377 null, // sorts 378 null, // limit 379 false // asObject 380 ); 381 382 if ( is_array( $pathStringList ) && count( $pathStringList ) ) 383 { 384 /* The object has some assigned nodes. 385 * If at least one of those nodes belongs to an SSL zone, 386 * we switch to SSL. 387 */ 388 389 // "flatten" the array 390 array_walk( $pathStringList, create_function( '&$a', '$a = $a[\'path_string\'];' ) ); 391 } 392 else 393 { 394 /* The object has no assigned nodes. 395 * Let's work with its parent nodes. 396 * If at least one of the parent nodes belongs to an SSL zone, 397 * we switch to SSL. 398 */ 399 $pathStringList = array(); 400 $nodes = $object->parentNodes( $object->attribute( 'current' ) ); 401 if ( !is_array( $nodes ) ) 402 { 403 eZDebug::writeError( 'Object ' . $object->attribute( 'is' ) . 404 'does not have neither assigned nor parent nodes.' ); 405 } 406 else 407 { 408 foreach( $nodes as $node ) 409 { 410 $pathStringList[] = $node->attribute( 'path_string' ); 411 } 412 } 413 } 414 415 $inSSL = false; // does the object belong to an SSL zone? 416 foreach ( $pathStringList as $pathString ) 417 { 418 if ( eZSSLZone::checkNodePath( $module, $view, $pathString, false ) ) 419 { 420 $inSSL = true; 421 break; 422 } 423 } 424 425 eZSSLZone::switchIfNeeded( $inSSL ); 426 } 427 428 /** 429 * \static 430 * Decide whether we should change access mode for this module view or not. 431 * Called from index.php. 432 */ 433 function checkModuleView( $module, $view ) 434 { 435 if ( !eZSSLZone::enabled() ) 436 return; 437 438 $ini =& eZINI::instance(); 439 $viewsModes = $ini->variable( 'SSLZoneSettings', 'ModuleViewAccessMode' ); 440 441 $sslViews = array_keys( $viewsModes, 'ssl' ); 442 $keepModeViews = array_keys( $viewsModes, 'keep' ); 443 444 $sslPriority = eZSSLZone::viewIsInArray( $module, $view, $sslViews ); 445 $keepModePriority = eZSSLZone::viewIsInArray( $module, $view, $keepModeViews ); 446 447 if ( $sslPriority && $keepModePriority && $sslPriority == $keepModePriority ) 448 { 449 eZDebug::writeError( "Configuration error: view $module/$view is defined both as 'ssl' and 'keep'", 450 'eZSSLZone' ); 451 return; 452 } 453 454 /* If the view belongs to the list of views we should not change access mode for, 455 * then do nothing. 456 * (however, the view may do access mode switch itself later) 457 */ 458 if ( $keepModePriority > $sslPriority ) 459 { 460 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 'Keeping current access mode...' ); 461 return; 462 } 463 464 /* Otherwise we look if the view is in the list of SSL views, 465 * and if it is, we switch to SSL. Else, if it's not, we switch to plain HTTP. 466 */ 467 $inSSL = ( $sslPriority > 0 ); 468 469 eZDebugSetting::writeDebug( 'kernel-ssl-zone', 470 ( isset( $inSSL ) ? ( $inSSL?'yes':'no') : 'dunno' ), 471 'Should we use SSL for this view?' ); 472 473 // Change access mode if we need to. 474 eZSSLZone::switchIfNeeded( $inSSL ); 475 } 476 } 477 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sat Feb 24 10:30:04 2007 | par Balluche grâce à PHPXref 0.7 |