Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
557 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
1086 daniel-mar 5
 * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
557 daniel-mar 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
 
1050 daniel-mar 20
namespace ViaThinkSoft\OIDplus;
557 daniel-mar 21
 
1086 daniel-mar 22
// phpcs:disable PSR1.Files.SideEffects
23
\defined('INSIDE_OIDPLUS') or die;
24
// phpcs:enable PSR1.Files.SideEffects
25
 
730 daniel-mar 26
class OIDplusCookieUtils extends OIDplusBaseClass {
557 daniel-mar 27
 
1116 daniel-mar 28
        /**
29
         * @param string $name
30
         * @return void
31
         * @throws OIDplusException
32
         */
33
        public function unsetcookie(string $name) {
557 daniel-mar 34
                $this->setcookie($name, '', time()-9999, true);
35
        }
36
 
1116 daniel-mar 37
        /**
38
         * @return string
39
         * @throws OIDplusException
40
         */
41
        private function getCookieDomain(): string {
1373 daniel-mar 42
                $domain = OIDplus::baseConfig()->getValue('COOKIE_DOMAIN', '');
812 daniel-mar 43
                if ($domain === '(auto)') {
1344 daniel-mar 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
                        }
812 daniel-mar 56
                }
57
                return $domain;
58
        }
806 daniel-mar 59
 
1116 daniel-mar 60
        /**
61
         * @return string
62
         * @throws OIDplusException
63
         */
64
        private function getCookiePath(): string {
1344 daniel-mar 65
                $path = OIDplus::baseConfig()->getValue('COOKIE_PATH', '(auto)');
812 daniel-mar 66
                if ($path === '(auto)') {
1344 daniel-mar 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'];
808 daniel-mar 81
 
1344 daniel-mar 82
                                // Alternatively:
83
                                //$path = OIDplus::webpath(null,OIDplus::PATH_RELATIVE_TO_ROOT_CANONICAL);
84
                                //if ($path === false) return $default_path;
85
                        }
812 daniel-mar 86
                }
87
                return $path;
88
        }
557 daniel-mar 89
 
1340 daniel-mar 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.
1116 daniel-mar 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
         */
1130 daniel-mar 101
        public function setcookie(string $name, string $value, int $expires=0, bool $allowJS=false, string $samesite=null, bool $forceInsecure=false) {
812 daniel-mar 102
                $domain = $this->getCookieDomain();
103
                $path = $this->getCookiePath();
1130 daniel-mar 104
                $secure = !$forceInsecure && OIDplus::isSSL();
557 daniel-mar 105
                $httponly = !$allowJS;
564 daniel-mar 106
                if (is_null($samesite)) {
107
                        $samesite = OIDplus::baseConfig()->getValue('COOKIE_SAMESITE_POLICY', 'Strict');
108
                }
557 daniel-mar 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
}