]> git.mxchange.org Git - friendica.git/blob - src/Model/User/Cookie.php
Remove copy&paste failure
[friendica.git] / src / Model / User / Cookie.php
1 <?php
2
3 namespace Friendica\Model\User;
4
5 use Friendica\App;
6 use Friendica\Core\Config\Configuration;
7
8 /**
9  * Interacting with the Friendica Cookie of a user
10  */
11 class Cookie
12 {
13         /** @var int Default expire duration in days */
14         const DEFAULT_EXPIRE = 7;
15         /** @var string The name of the Friendica cookie */
16         const NAME = 'Friendica';
17
18         /** @var string The remote address of this node */
19         private $remoteAddr = '0.0.0.0';
20         /** @var bool True, if the connection is ssl enabled */
21         private $sslEnabled = false;
22         /** @var string The private key of this Friendica node */
23         private $sitePrivateKey;
24         /** @var int The default cookie lifetime */
25         private $lifetime = self::DEFAULT_EXPIRE * 24 * 60 * 60;
26         /** @var array The $_COOKIE array */
27         private $cookie;
28
29         public function __construct(Configuration $config, array $server = [], array $cookie = [])
30         {
31                 if (!empty($server['REMOTE_ADDR'])) {
32                         $this->remoteAddr = $server['REMOTE_ADDR'];
33                 }
34
35                 $this->sslEnabled     = $config->get('system', 'ssl_policy') === App\BaseURL::SSL_POLICY_FULL;
36                 $this->sitePrivateKey = $config->get('system', 'site_prvkey');
37
38                 $authCookieDays = $config->get('system', 'auth_cookie_lifetime',
39                         self::DEFAULT_EXPIRE);
40                 $this->lifetime = $authCookieDays * 24 * 60 * 60;
41                 $this->cookie   = $cookie;
42         }
43
44         /**
45          * Checks if the Friendica cookie is set for a user
46          *
47          * @param string $hash       The cookie hash
48          * @param string $password   The user password
49          * @param string $privateKey The private Key of the user
50          *
51          * @return boolean True, if the cookie is set
52          *
53          */
54         public function check(string $hash, string $password, string $privateKey)
55         {
56                 return hash_equals(
57                         $this->getHash($password, $privateKey),
58                         $hash
59                 );
60         }
61
62         /**
63          * Set the Friendica cookie for a user
64          *
65          * @param int    $uid        The user id
66          * @param string $password   The user password
67          * @param string $privateKey The user private key
68          * @param int|null    $seconds    optional the seconds
69          *
70          * @return bool
71          */
72         public function set(int $uid, string $password, string $privateKey, int $seconds = null)
73         {
74                 if (!isset($seconds)) {
75                         $seconds = $this->lifetime;
76                 } elseif (isset($seconds) && $seconds != 0) {
77                         $seconds = $seconds + time();
78                 }
79
80                 $value = json_encode([
81                         'uid'  => $uid,
82                         'hash' => $this->getHash($password, $privateKey),
83                         'ip'   => $this->remoteAddr,
84                 ]);
85
86                 return $this->setCookie(self::NAME, $value, $seconds,
87                         '/', '', $this->sslEnabled, true);
88         }
89
90         /**
91          * Returns the data of the Friendicas user cookie
92          *
93          * @return mixed|null The JSON data, null if not set
94          */
95         public function getData()
96         {
97                 // When the "Friendica" cookie is set, take the value to authenticate and renew the cookie.
98                 if (isset($this->cookie[self::NAME])) {
99                         $data = json_decode($this->cookie[self::NAME]);
100                         if (!empty($data)) {
101                                 return $data;
102                         }
103                 }
104
105                 return null;
106         }
107
108         /**
109          * Clears the Friendica cookie of this user after leaving the page
110          */
111         public function clear()
112         {
113                 // make sure cookie is deleted on browser close, as a security measure
114                 return $this->setCookie(self::NAME, '', -3600,
115                         '/', '', $this->sslEnabled, true);
116         }
117
118         /**
119          * Calculate the hash that is needed for the Friendica cookie
120          *
121          * @param string $password   The user password
122          * @param string $privateKey The private key of the user
123          *
124          * @return string Hashed data
125          */
126         private function getHash(string $password, string $privateKey)
127         {
128                 return hash_hmac(
129                         'sha256',
130                         hash_hmac('sha256', $password, $privateKey),
131                         $this->sitePrivateKey
132                 );
133         }
134
135         /**
136          * Send a cookie - protected, internal function for test-mocking possibility
137          *
138          * @link  https://php.net/manual/en/function.setcookie.php
139          *
140          * @param string $name
141          * @param string $value    [optional]
142          * @param int    $expire   [optional]
143          * @param string $path     [optional]
144          * @param string $domain   [optional]
145          * @param bool   $secure   [optional]
146          * @param bool   $httponly [optional]
147          *
148          * @return bool If output exists prior to calling this function,
149          *
150          */
151         protected function setCookie(string $name, string $value = null, int $expire = null,
152                                      string $path = null, string $domain = null,
153                                      bool $secure = null, bool $httponly = null)
154         {
155                 return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
156         }
157 }