Subversion Repositories oidplus

Rev

Rev 1344 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. namespace ViaThinkSoft\OIDplus;
  21.  
  22. // phpcs:disable PSR1.Files.SideEffects
  23. \defined('INSIDE_OIDPLUS') or die;
  24. // phpcs:enable PSR1.Files.SideEffects
  25.  
  26. class OIDplusCookieUtils extends OIDplusBaseClass {
  27.  
  28.         /**
  29.          * @param string $name
  30.          * @return void
  31.          * @throws OIDplusException
  32.          */
  33.         public function unsetcookie(string $name) {
  34.                 $this->setcookie($name, '', time()-9999, true);
  35.         }
  36.  
  37.         /**
  38.          * @return string
  39.          * @throws OIDplusException
  40.          */
  41.         private function getCookieDomain(): string {
  42.                 $domain = OIDplus::baseConfig()->getValue('COOKIE_DOMAIN', '');
  43.                 if ($domain === '(auto)') {
  44.                         if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
  45.                                 // If OIDplus is called through a Reverse Proxy, we must make sure that the cookies are working.
  46.                                 $domain = $_SERVER['HTTP_X_FORWARDED_HOST'];
  47.                         } else {
  48.                                 $default_domain = ''; // ini_get('session.cookie_domain');
  49.                                 $tmp = OIDplus::webpath(null,OIDplus::PATH_ABSOLUTE/*_CANONICAL*/);
  50.                                 if ($tmp === false) return $default_domain;
  51.                                 $tmp = parse_url($tmp);
  52.                                 if ($tmp === false) return $default_domain;
  53.                                 if (!isset($tmp['host'])) return $default_domain;
  54.                                 $domain = $tmp['host'];
  55.                         }
  56.                 }
  57.                 return $domain;
  58.         }
  59.  
  60.         /**
  61.          * @return string
  62.          * @throws OIDplusException
  63.          */
  64.         private function getCookiePath(): string {
  65.                 $path = OIDplus::baseConfig()->getValue('COOKIE_PATH', '(auto)');
  66.                 if ($path === '(auto)') {
  67.                         if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
  68.                                 // If OIDplus is called through a Reverse Proxy, we must make sure that the cookies are working.
  69.                                 // Since we don't know the path the client is using, we need to set the path to '/'
  70.                                 // Alternatively, the system owner can evaluate HTTP_X_FORWARDED_HOST inside the base configuration file
  71.                                 // and set the COOKIE_PATH setting based on HTTP_X_FORWARDED_HOST.
  72.                                 $path = '/';
  73.                         } else {
  74.                                 $default_path = '/'; // ini_get('session.cookie_path');
  75.                                 $tmp = OIDplus::webpath(null, OIDplus::PATH_ABSOLUTE/*_CANONICAL*/);
  76.                                 if ($tmp === false) return $default_path;
  77.                                 $tmp = parse_url($tmp);
  78.                                 if ($tmp === false) return $default_path;
  79.                                 if (!isset($tmp['path'])) return $default_path;
  80.                                 $path = $tmp['path'];
  81.  
  82.                                 // Alternatively:
  83.                                 //$path = OIDplus::webpath(null,OIDplus::PATH_RELATIVE_TO_ROOT_CANONICAL);
  84.                                 //if ($path === false) return $default_path;
  85.                         }
  86.                 }
  87.                 return $path;
  88.         }
  89.  
  90.         // TODO: In a HTTP request, there are usually several setcookie() for the same name that overwrite each other. That's not very nice. We should collect the cookies and then at script ending only send the last definition one time.
  91.         /**
  92.          * @param string $name
  93.          * @param string $value
  94.          * @param int $expires
  95.          * @param bool $allowJS
  96.          * @param string|null $samesite
  97.          * @param bool $forceInsecure
  98.          * @return void
  99.          * @throws OIDplusException
  100.          */
  101.         public function setcookie(string $name, string $value, int $expires=0, bool $allowJS=false, string $samesite=null, bool $forceInsecure=false) {
  102.                 $domain = $this->getCookieDomain();
  103.                 $path = $this->getCookiePath();
  104.                 $secure = !$forceInsecure && OIDplus::isSSL();
  105.                 $httponly = !$allowJS;
  106.                 if (is_null($samesite)) {
  107.                         $samesite = OIDplus::baseConfig()->getValue('COOKIE_SAMESITE_POLICY', 'Strict');
  108.                 }
  109.  
  110.                 if (strnatcmp(phpversion(),'7.3.0') >= 0) {
  111.                         $options = array(
  112.                                 "expires" => $expires,
  113.                                 "path" => $path,
  114.                                 "domain" => $domain,
  115.                                 "secure" => $secure,
  116.                                 "httponly" => $httponly,
  117.                                 "samesite" => $samesite
  118.                         );
  119.                         setcookie($name, $value, $options);
  120.                 } else {
  121.                         setcookie($name, $value, $expires, $path.'; samesite='.$samesite, $domain, $secure, $httponly);
  122.                 }
  123.         }
  124.  
  125. }
  126.