3 * @copyright Copyright (C) 2010-2023, the Friendica project
5 * @license GNU AGPL version 3 or any later version
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.
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.
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/>.
22 namespace Friendica\Test\src\Model\User;
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;
32 class CookieTest extends MockedTest
34 /** @var MockInterface|IManageConfigValues */
36 /** @var MockInterface|BaseURL */
39 const SERVER_ARRAY = ['REMOTE_ADDR' => '1.2.3.4'];
41 protected function setUp(): void
43 StaticCookie::clearStatic();
47 $this->config = \Mockery::mock(IManageConfigValues::class);
48 $this->baseUrl = \Mockery::mock(BaseURL::class);
51 protected function tearDown(): void
53 StaticCookie::clearStatic();
59 * Test if we can create a basic cookie instance
61 public function testInstance()
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();
68 $request = new Request($this->config,static::SERVER_ARRAY);
70 $cookie = new Cookie($request, $this->config, $this->baseUrl);
71 self::assertInstanceOf(Cookie::class, $cookie);
74 public function dataGet()
79 Cookie::NAME => json_encode([
101 Cookie::NAME => 'test',
103 'hasValues' => false,
110 Cookie::NAME => json_encode([
124 * Test the get() method of the cookie class
126 * @dataProvider dataGet
128 public function testGet(array $cookieData, bool $hasValues, $uid, $hash, $ip)
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();
135 $request = new Request($this->config, static::SERVER_ARRAY);
137 $cookie = new Cookie($request, $this->config, $this->baseUrl, $cookieData);
138 self::assertInstanceOf(Cookie::class, $cookie);
141 self::assertEquals($uid, $cookie->get('uid'));
143 self::assertNull($cookie->get('uid'));
146 self::assertEquals($hash, $cookie->get('hash'));
148 self::assertNull($cookie->get('hash'));
151 self::assertEquals($ip, $cookie->get('ip'));
153 self::assertNull($cookie->get('ip'));
157 public function dataCheck()
161 'serverPrivateKey' => 'serverkey',
162 'userPrivateKey' => 'userkey',
163 'password' => 'test',
164 'assertHash' => 'e9b4eb16275a2907b5659d22905b248221d0517dde4a9d5c320b8fe051b1267b',
165 'assertTrue' => true,
168 'serverPrivateKey' => 'serverkey',
169 'userPrivateKey' => '',
172 'assertTrue' => false,
175 'serverPrivateKey' => 'serverkey',
176 'userPrivateKey' => 'bla',
177 'password' => 'nope',
178 'assertHash' => 'real wrong!',
179 'assertTrue' => false,
185 * Test the check() method of the cookie class
187 * @dataProvider dataCheck
189 public function testCheck(string $serverPrivateKey, string $userPrivateKey, string $password, string $assertHash, bool $assertTrue)
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();
196 $request = new Request($this->config, static::SERVER_ARRAY);
198 $cookie = new Cookie($request, $this->config, $this->baseUrl);
199 self::assertInstanceOf(Cookie::class, $cookie);
201 self::assertEquals($assertTrue, $cookie->comparePrivateDataHash($assertHash, $password, $userPrivateKey));
204 public function dataSet()
211 'privateKey' => '124',
212 'assertHash' => 'b657a15cfe7ed1f7289c9aa51af14a9a26c966f4ddd74e495fba103d8e872a39',
213 'remoteIp' => '0.0.0.0',
216 'withServerArray' => [
220 'privateKey' => '124',
221 'assertHash' => 'b657a15cfe7ed1f7289c9aa51af14a9a26c966f4ddd74e495fba103d8e872a39',
222 'remoteIp' => '1.2.3.4',
223 'serverArray' => ['REMOTE_ADDR' => '1.2.3.4',],
228 public function assertCookie($uid, $hash, $remoteIp)
230 self::assertArrayHasKey(Cookie::NAME, StaticCookie::$_COOKIE);
232 $data = json_decode(StaticCookie::$_COOKIE[Cookie::NAME]);
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);
241 self::assertLessThanOrEqual(time() + Cookie::DEFAULT_EXPIRE * 24 * 60 * 60, StaticCookie::$_EXPIRE);
245 * Test the set() method of the cookie class
247 * @dataProvider dataSet
249 public function testSet($serverKey, $uid, $password, $privateKey, $assertHash, $remoteIp, $serverArray)
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);
258 $request = new Request($this->config, $serverArray);
260 $cookie = new StaticCookie($request, $this->config, $this->baseUrl);
261 self::assertInstanceOf(Cookie::class, $cookie);
263 $cookie->setMultiple([
265 'hash' => $assertHash,
268 self::assertCookie($uid, $assertHash, $remoteIp);
272 * Test the set() method of the cookie class
274 * @dataProvider dataSet
276 public function testDoubleSet($serverKey, $uid, $password, $privateKey, $assertHash, $remoteIp, $serverArray)
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);
284 $request = new Request($this->config, $serverArray);
286 $cookie = new StaticCookie($request, $this->config, $this->baseUrl, $serverArray);
287 self::assertInstanceOf(Cookie::class, $cookie);
289 $cookie->set('uid', $uid);
290 $cookie->set('hash', $assertHash);
292 self::assertCookie($uid, $assertHash, $remoteIp);
296 * Test the clear() method of the cookie class
298 public function testClear()
300 StaticCookie::$_COOKIE = [
301 Cookie::NAME => 'test'
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();
309 $request = new Request($this->config, static::SERVER_ARRAY);
311 $cookie = new StaticCookie($request, $this->config, $this->baseUrl);
312 self::assertInstanceOf(Cookie::class, $cookie);
314 self::assertEquals('test', StaticCookie::$_COOKIE[Cookie::NAME]);
315 self::assertEquals(null, StaticCookie::$_EXPIRE);
319 self::assertEmpty(StaticCookie::$_COOKIE[Cookie::NAME]);
320 self::assertEquals(-3600, StaticCookie::$_EXPIRE);