]> git.mxchange.org Git - friendica.git/blob - tests/src/Model/User/CookieTest.php
spelling: cached
[friendica.git] / tests / src / Model / User / CookieTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Test\src\Model\User;
23
24 use Friendica\App\BaseURL;
25 use Friendica\App\Request;
26 use Friendica\Core\Config\Capability\IManageConfigValues;
27 use Friendica\Model\User\Cookie;
28 use Friendica\Test\MockedTest;
29 use Friendica\Test\Util\StaticCookie;
30 use Mockery\MockInterface;
31
32 class CookieTest extends MockedTest
33 {
34         /** @var MockInterface|IManageConfigValues */
35         private $config;
36         /** @var MockInterface|BaseURL */
37         private $baseUrl;
38
39         const SERVER_ARRAY = ['REMOTE_ADDR' => '1.2.3.4'];
40
41         protected function setUp(): void
42         {
43                 StaticCookie::clearStatic();
44
45                 parent::setUp();
46
47                 $this->config  = \Mockery::mock(IManageConfigValues::class);
48                 $this->baseUrl = \Mockery::mock(BaseURL::class);
49         }
50
51         protected function tearDown(): void
52         {
53                 StaticCookie::clearStatic();
54
55                 parent::tearDown();
56         }
57
58         /**
59          * Test if we can create a basic cookie instance
60          */
61         public function testInstance()
62         {
63                 $this->baseUrl->shouldReceive('getScheme')->andReturn('https')->once();
64                 $this->config->shouldReceive('get')->with('system', 'site_prvkey')->andReturn('1235')->once();
65                 $this->config->shouldReceive('get')->with('system', 'auth_cookie_lifetime', Cookie::DEFAULT_EXPIRE)->andReturn('7')->once();
66                 $this->config->shouldReceive('get')->with('proxy', 'trusted_proxies', '')->andReturn('')->once();
67
68                 $request = new Request($this->config,static::SERVER_ARRAY);
69
70                 $cookie = new Cookie($request, $this->config, $this->baseUrl);
71                 self::assertInstanceOf(Cookie::class, $cookie);
72         }
73
74         public function dataGet()
75         {
76                 return [
77                         'default'    => [
78                                 'cookieData' => [
79                                         Cookie::NAME => json_encode([
80                                                 'uid'  => -1,
81                                                 'hash' => 12345,
82                                                 'ip'   => '127.0.0.1',
83                                         ])
84                                 ],
85                                 'hasValues'  => true,
86                                 'uid'        => -1,
87                                 'hash'       => 12345,
88                                 'ip'         => '127.0.0.1',
89                         ],
90                         'missing'    => [
91                                 'cookieData' => [
92
93                                 ],
94                                 'hasValues'  => false,
95                                 'uid'        => null,
96                                 'hash'       => null,
97                                 'ip'         => null,
98                         ],
99                         'invalid'    => [
100                                 'cookieData' => [
101                                         Cookie::NAME => 'test',
102                                 ],
103                                 'hasValues'  => false,
104                                 'uid'        => null,
105                                 'hash'       => null,
106                                 'ip'         => null,
107                         ],
108                         'incomplete' => [
109                                 'cookieData' => [
110                                         Cookie::NAME => json_encode([
111                                                 'uid'  => -1,
112                                                 'hash' => 12345,
113                                         ])
114                                 ],
115                                 'hasValues'  => true,
116                                 'uid'        => -1,
117                                 'hash'       => 12345,
118                                 'ip'         => null,
119                         ],
120                 ];
121         }
122
123         /**
124          * Test the get() method of the cookie class
125          *
126          * @dataProvider dataGet
127          */
128         public function testGet(array $cookieData, bool $hasValues, $uid, $hash, $ip)
129         {
130                 $this->baseUrl->shouldReceive('getScheme')->andReturn('https')->once();
131                 $this->config->shouldReceive('get')->with('system', 'site_prvkey')->andReturn('1235')->once();
132                 $this->config->shouldReceive('get')->with('system', 'auth_cookie_lifetime', Cookie::DEFAULT_EXPIRE)->andReturn('7')->once();
133                 $this->config->shouldReceive('get')->with('proxy', 'trusted_proxies', '')->andReturn('')->once();
134
135                 $request = new Request($this->config, static::SERVER_ARRAY);
136
137                 $cookie = new Cookie($request, $this->config, $this->baseUrl, $cookieData);
138                 self::assertInstanceOf(Cookie::class, $cookie);
139
140                 if (isset($uid)) {
141                         self::assertEquals($uid, $cookie->get('uid'));
142                 } else {
143                         self::assertNull($cookie->get('uid'));
144                 }
145                 if (isset($hash)) {
146                         self::assertEquals($hash, $cookie->get('hash'));
147                 } else {
148                         self::assertNull($cookie->get('hash'));
149                 }
150                 if (isset($ip)) {
151                         self::assertEquals($ip, $cookie->get('ip'));
152                 } else {
153                         self::assertNull($cookie->get('ip'));
154                 }
155         }
156
157         public function dataCheck()
158         {
159                 return [
160                         'default'   => [
161                                 'serverPrivateKey' => 'serverkey',
162                                 'userPrivateKey'   => 'userkey',
163                                 'password'         => 'test',
164                                 'assertHash'       => 'e9b4eb16275a2907b5659d22905b248221d0517dde4a9d5c320b8fe051b1267b',
165                                 'assertTrue'       => true,
166                         ],
167                         'emptyUser' => [
168                                 'serverPrivateKey' => 'serverkey',
169                                 'userPrivateKey'   => '',
170                                 'password'         => '',
171                                 'assertHash'       => '',
172                                 'assertTrue'       => false,
173                         ],
174                         'invalid'   => [
175                                 'serverPrivateKey' => 'serverkey',
176                                 'userPrivateKey'   => 'bla',
177                                 'password'         => 'nope',
178                                 'assertHash'       => 'real wrong!',
179                                 'assertTrue'       => false,
180                         ]
181                 ];
182         }
183
184         /**
185          * Test the check() method of the cookie class
186          *
187          * @dataProvider dataCheck
188          */
189         public function testCheck(string $serverPrivateKey, string $userPrivateKey, string $password, string $assertHash, bool $assertTrue)
190         {
191                 $this->baseUrl->shouldReceive('getScheme')->andReturn('https')->once();
192                 $this->config->shouldReceive('get')->with('system', 'site_prvkey')->andReturn($serverPrivateKey)->once();
193                 $this->config->shouldReceive('get')->with('system', 'auth_cookie_lifetime', Cookie::DEFAULT_EXPIRE)->andReturn('7')->once();
194                 $this->config->shouldReceive('get')->with('proxy', 'trusted_proxies', '')->andReturn('')->once();
195
196                 $request = new Request($this->config, static::SERVER_ARRAY);
197
198                 $cookie = new Cookie($request, $this->config, $this->baseUrl);
199                 self::assertInstanceOf(Cookie::class, $cookie);
200
201                 self::assertEquals($assertTrue, $cookie->comparePrivateDataHash($assertHash, $password, $userPrivateKey));
202         }
203
204         public function dataSet()
205         {
206                 return [
207                         'default'         => [
208                                 'serverKey'   => 23,
209                                 'uid'         => 0,
210                                 'password'    => '234',
211                                 'privateKey'  => '124',
212                                 'assertHash'  => 'b657a15cfe7ed1f7289c9aa51af14a9a26c966f4ddd74e495fba103d8e872a39',
213                                 'remoteIp'    => '0.0.0.0',
214                                 'serverArray' => [],
215                         ],
216                         'withServerArray' => [
217                                 'serverKey'   => 23,
218                                 'uid'         => 0,
219                                 'password'    => '234',
220                                 'privateKey'  => '124',
221                                 'assertHash'  => 'b657a15cfe7ed1f7289c9aa51af14a9a26c966f4ddd74e495fba103d8e872a39',
222                                 'remoteIp'    => '1.2.3.4',
223                                 'serverArray' => ['REMOTE_ADDR' => '1.2.3.4',],
224                         ],
225                 ];
226         }
227
228         public function assertCookie($uid, $hash, $remoteIp)
229         {
230                 self::assertArrayHasKey(Cookie::NAME, StaticCookie::$_COOKIE);
231
232                 $data = json_decode(StaticCookie::$_COOKIE[Cookie::NAME]);
233
234                 self::assertObjectHasAttribute('uid', $data);
235                 self::assertEquals($uid, $data->uid);
236                 self::assertObjectHasAttribute('hash', $data);
237                 self::assertEquals($hash, $data->hash);
238                 self::assertObjectHasAttribute('ip', $data);
239                 self::assertEquals($remoteIp, $data->ip);
240
241                 self::assertLessThanOrEqual(time() + Cookie::DEFAULT_EXPIRE * 24 * 60 * 60, StaticCookie::$_EXPIRE);
242         }
243
244         /**
245          * Test the set() method of the cookie class
246          *
247          * @dataProvider dataSet
248          */
249         public function testSet($serverKey, $uid, $password, $privateKey, $assertHash, $remoteIp, $serverArray)
250         {
251                 $this->baseUrl->shouldReceive('getScheme')->andReturn('https')->once();
252                 $this->config->shouldReceive('get')->with('system', 'site_prvkey')->andReturn($serverKey)->once();
253                 $this->config->shouldReceive('get')->with('system', 'auth_cookie_lifetime', Cookie::DEFAULT_EXPIRE)->andReturn(Cookie::DEFAULT_EXPIRE)->once();
254                 $this->config->shouldReceive('get')->with('proxy', 'trusted_proxies', '')->andReturn('')->once();
255                 $this->config->shouldReceive('get')->with('proxy', 'forwarded_for_headers')->andReturn(Request::DEFAULT_FORWARD_FOR_HEADER);
256
257
258                 $request = new Request($this->config, $serverArray);
259
260                 $cookie = new StaticCookie($request, $this->config, $this->baseUrl);
261                 self::assertInstanceOf(Cookie::class, $cookie);
262
263                 $cookie->setMultiple([
264                         'uid' => $uid,
265                         'hash' => $assertHash,
266                 ]);
267
268                 self::assertCookie($uid, $assertHash, $remoteIp);
269         }
270
271         /**
272          * Test the set() method of the cookie class
273          *
274          * @dataProvider dataSet
275          */
276         public function testDoubleSet($serverKey, $uid, $password, $privateKey, $assertHash, $remoteIp, $serverArray)
277         {
278                 $this->baseUrl->shouldReceive('getScheme')->andReturn('https')->once();
279                 $this->config->shouldReceive('get')->with('system', 'site_prvkey')->andReturn($serverKey)->once();
280                 $this->config->shouldReceive('get')->with('system', 'auth_cookie_lifetime', Cookie::DEFAULT_EXPIRE)->andReturn(Cookie::DEFAULT_EXPIRE)->once();
281                 $this->config->shouldReceive('get')->with('proxy', 'trusted_proxies', '')->andReturn('')->once();
282                 $this->config->shouldReceive('get')->with('proxy', 'forwarded_for_headers')->andReturn(Request::DEFAULT_FORWARD_FOR_HEADER);
283
284                 $request = new Request($this->config, $serverArray);
285
286                 $cookie = new StaticCookie($request, $this->config, $this->baseUrl, $serverArray);
287                 self::assertInstanceOf(Cookie::class, $cookie);
288
289                 $cookie->set('uid', $uid);
290                 $cookie->set('hash', $assertHash);
291
292                 self::assertCookie($uid, $assertHash, $remoteIp);
293         }
294
295         /**
296          * Test the clear() method of the cookie class
297          */
298         public function testClear()
299         {
300                 StaticCookie::$_COOKIE = [
301                         Cookie::NAME => 'test'
302                 ];
303
304                 $this->baseUrl->shouldReceive('getScheme')->andReturn('https')->once();
305                 $this->config->shouldReceive('get')->with('system', 'site_prvkey')->andReturn(24)->once();
306                 $this->config->shouldReceive('get')->with('system', 'auth_cookie_lifetime', Cookie::DEFAULT_EXPIRE)->andReturn(Cookie::DEFAULT_EXPIRE)->once();
307                 $this->config->shouldReceive('get')->with('proxy', 'trusted_proxies', '')->andReturn('')->once();
308
309                 $request = new Request($this->config, static::SERVER_ARRAY);
310
311                 $cookie = new StaticCookie($request, $this->config, $this->baseUrl);
312                 self::assertInstanceOf(Cookie::class, $cookie);
313
314                 self::assertEquals('test', StaticCookie::$_COOKIE[Cookie::NAME]);
315                 self::assertEquals(null, StaticCookie::$_EXPIRE);
316
317                 $cookie->clear();
318
319                 self::assertEmpty(StaticCookie::$_COOKIE[Cookie::NAME]);
320                 self::assertEquals(-3600, StaticCookie::$_EXPIRE);
321         }
322 }