[ Index ]
 

Code source de eZ Publish 3.9.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/kernel/classes/ -> ezsslzone.php (source)

   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  ?>


Généré le : Sat Feb 24 10:30:04 2007 par Balluche grâce à PHPXref 0.7