Skip to content

Commit 0152240

Browse files
committed
make sure we only use the first storage. added FIXME to support multiple storage pods
1 parent a1845d0 commit 0152240

File tree

3 files changed

+264
-1
lines changed

3 files changed

+264
-1
lines changed

tests/phpunit/UserTest.php

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
<?php
2+
namespace Pdsinterop\PhpSolid\Tests;
3+
4+
require_once(__DIR__ . "/test-config.php");
5+
6+
use Pdsinterop\PhpSolid\User;
7+
use Pdsinterop\PhpSolid\Db;
8+
9+
class UserTest extends \PHPUnit\Framework\TestCase
10+
{
11+
protected function setUp(): void
12+
{
13+
$futureTimestamp = new \DateTime();
14+
$futureTimestamp->add(new \DateInterval('P120M'));
15+
$statements = [
16+
'DROP TABLE IF EXISTS allowedClients',
17+
'DROP TABLE IF EXISTS userStorage',
18+
'DROP TABLE IF EXISTS verify',
19+
'DROP TABLE IF EXISTS users',
20+
'CREATE TABLE IF NOT EXISTS allowedClients (
21+
userId VARCHAR(255) NOT NULL PRIMARY KEY,
22+
clientId VARCHAR(255) NOT NULL
23+
)',
24+
'CREATE TABLE IF NOT EXISTS userStorage (
25+
userId VARCHAR(255) NOT NULL PRIMARY KEY,
26+
storageUrl VARCHAR(255) NOT NULL
27+
)',
28+
'CREATE TABLE IF NOT EXISTS verify (
29+
code VARCHAR(255) NOT NULL PRIMARY KEY,
30+
data TEXT NOT NULL
31+
)',
32+
'CREATE TABLE IF NOT EXISTS users (
33+
user_id VARCHAR(255) NOT NULL PRIMARY KEY,
34+
email TEXT NOT NULL,
35+
password TEXT NOT NULL,
36+
data TEXT
37+
)',
38+
'INSERT INTO verify VALUES("test1", \'{"expires": 0, "hello": "world", "code": "test1"}\')',
39+
'INSERT INTO verify VALUES("test2", \'{"expires": ' . $futureTimestamp->getTimestamp() . ', "hello": "world", "code": "test2"}\')'
40+
];
41+
42+
Db::connect();
43+
try {
44+
// create tables
45+
foreach($statements as $statement){
46+
Db::$pdo->exec($statement);
47+
}
48+
} catch(\PDOException $e) {
49+
echo $e->getMessage();
50+
}
51+
}
52+
53+
public function testSaveVerifyToken() {
54+
$beforeExpires = new \DateTime();
55+
$beforeExpires->add(new \DateInterval('PT29M'));
56+
57+
$afterExpires = new \DateTime();
58+
$afterExpires->add(new \DateInterval('PT31M'));
59+
$token = User::saveVerifyToken("verify", [
60+
"hello" => "world"
61+
]);
62+
$this->assertTrue($token['expires'] > $beforeExpires->getTimestamp());
63+
$this->assertTrue($token['expires'] < $afterExpires->getTimestamp());
64+
65+
$storedToken = User::getVerifyToken($token['code']);
66+
$this->assertEquals($storedToken['hello'], "world");
67+
}
68+
69+
public function testSavePasswordResetToken() {
70+
$beforeExpires = new \DateTime();
71+
$beforeExpires->add(new \DateInterval('PT29M'));
72+
73+
$afterExpires = new \DateTime();
74+
$afterExpires->add(new \DateInterval('PT31M'));
75+
$token = User::saveVerifyToken("verify", [
76+
"hello" => "world"
77+
]);
78+
$this->assertTrue($token['expires'] > $beforeExpires->getTimestamp());
79+
$this->assertTrue($token['expires'] < $afterExpires->getTimestamp());
80+
81+
$storedToken = User::getVerifyToken($token['code']);
82+
$this->assertEquals($storedToken['hello'], "world");
83+
}
84+
85+
public function testSaveAccountDeleteToken() {
86+
$beforeExpires = new \DateTime();
87+
$beforeExpires->add(new \DateInterval('PT29M'));
88+
89+
$afterExpires = new \DateTime();
90+
$afterExpires->add(new \DateInterval('PT31M'));
91+
$token = User::saveVerifyToken("verify", [
92+
"hello" => "world"
93+
]);
94+
$this->assertTrue($token['expires'] > $beforeExpires->getTimestamp());
95+
$this->assertTrue($token['expires'] < $afterExpires->getTimestamp());
96+
97+
$storedToken = User::getVerifyToken($token['code']);
98+
$this->assertEquals($storedToken['hello'], "world");
99+
}
100+
101+
public function testExpiredToken() {
102+
$token = User::getVerifyToken("test1");
103+
$this->assertFalse($token);
104+
}
105+
106+
public function testNonExpiredToken() {
107+
$token = User::getVerifyToken("test2");
108+
$this->assertEquals($token['hello'], "world");
109+
}
110+
111+
public function testCreateUser() {
112+
$newUser = [
113+
"password" => "hello123!@#ABC",
114+
"email" => "[email protected]",
115+
"hello" => "world"
116+
];
117+
$createdUser = User::createUser($newUser);
118+
$this->assertEquals($createdUser['email'], "[email protected]");
119+
$this->assertTrue(isset($createdUser['webId']));
120+
$this->assertTrue(isset($createdUser['userId']));
121+
$this->assertTrue(strlen($createdUser['userId']) === 32);
122+
123+
$canLogIn = User::checkPassword($newUser['email'], $newUser['password']);
124+
$this->assertTrue($canLogIn);
125+
}
126+
127+
public function testGetUser() {
128+
$newUser = [
129+
"password" => "hello123!@#ABC",
130+
"email" => "[email protected]",
131+
"hello" => "world"
132+
];
133+
$createdUser = User::createUser($newUser);
134+
135+
$userByEmail = User::getUser($newUser['email']);
136+
$this->assertEquals($userByEmail['webId'], $createdUser['webId']);
137+
$this->assertEquals($userByEmail['hello'], 'world');
138+
$this->assertTrue(isset($userByEmail['allowedClients']));
139+
$this->assertEquals($userByEmail['issuer'], "https://solid.example.com");
140+
}
141+
142+
public function testGetUserById() {
143+
$newUser = [
144+
"password" => "hello123!@#ABC",
145+
"email" => "[email protected]",
146+
"hello" => "world"
147+
];
148+
$createdUser = User::createUser($newUser);
149+
150+
$userById = User::getUserById($createdUser['userId']);
151+
$this->assertEquals($userById['webId'], $createdUser['webId']);
152+
$this->assertEquals($userById['hello'], 'world');
153+
$this->assertTrue(isset($userById['allowedClients']));
154+
$this->assertEquals($userById['issuer'], "https://solid.example.com");
155+
}
156+
157+
public function testSetPasswordNonExistingUser() {
158+
$result = User::setUserPassword("[email protected]", "hello123!@#ABC");
159+
$this->assertFalse($result);
160+
}
161+
162+
public function testSetWeakPassword() {
163+
$newUser = [
164+
"password" => "hello123!@#ABC",
165+
"email" => "[email protected]",
166+
"hello" => "world"
167+
];
168+
$createdUser = User::createUser($newUser);
169+
$result = User::setUserPassword($newUser['email'], "a");
170+
$this->assertFalse($result);
171+
}
172+
173+
public function testLogin() {
174+
$newUser = [
175+
"password" => "hello123!@#ABC",
176+
"email" => "[email protected]",
177+
"hello" => "world"
178+
];
179+
$createdUser = User::createUser($newUser);
180+
181+
$canLogIn = User::checkPassword($newUser['email'], $newUser['password']);
182+
$this->assertTrue($canLogIn);
183+
}
184+
185+
public function testLoginFailed() {
186+
$newUser = [
187+
"password" => "hello123!@#ABC",
188+
"email" => "[email protected]",
189+
"hello" => "world"
190+
];
191+
$createdUser = User::createUser($newUser);
192+
193+
$canLogIn = User::checkPassword($newUser['email'], "something else");
194+
$this->assertFalse($canLogIn);
195+
}
196+
197+
public function testSetStrongPassword() {
198+
$newUser = [
199+
"password" => "hello123!@#ABC",
200+
"email" => "[email protected]",
201+
"hello" => "world"
202+
];
203+
$createdUser = User::createUser($newUser);
204+
205+
$result = User::setUserPassword($newUser['email'], "this is a strong password because it is long enough");
206+
$this->assertTrue($result);
207+
}
208+
209+
public function testLoginAfterChange() {
210+
$newUser = [
211+
"password" => "hello123!@#ABC",
212+
"email" => "[email protected]",
213+
"hello" => "world"
214+
];
215+
$createdUser = User::createUser($newUser);
216+
$canLogIn = User::checkPassword($newUser['email'], $newUser['password']);
217+
$this->assertTrue($canLogIn);
218+
219+
$newPassword = "this is a strong password because it is long enough";
220+
$result = User::setUserPassword($newUser['email'], $newPassword);
221+
$this->assertTrue($result);
222+
223+
$canLogIn = User::checkPassword($newUser['email'], "something else");
224+
$this->assertFalse($canLogIn);
225+
226+
$canLogIn = User::checkPassword($newUser['email'], $newUser['password']);
227+
$this->assertFalse($canLogIn);
228+
229+
$canLogIn = User::checkPassword($newUser['email'], $newPassword);
230+
$this->assertTrue($canLogIn);
231+
}
232+
233+
public function testUserStorage() {
234+
$newUser = [
235+
"password" => "hello123!@#ABC",
236+
"email" => "[email protected]",
237+
"hello" => "world"
238+
];
239+
$createdUser = User::createUser($newUser);
240+
$storageUrl = "https://storage.example.com";
241+
User::setStorage($createdUser['userId'], $storageUrl);
242+
243+
$savedStorage = User::getStorage($createdUser['userId']);
244+
245+
$this->assertTrue(in_array($storageUrl, $savedStorage));
246+
247+
$user = User::getUser($newUser['email']);
248+
$this->assertTrue(in_array($storageUrl, $user['storage']));
249+
}
250+
251+
// @TODO Write tests for these functions:
252+
// userIdExists
253+
// userEmailExists
254+
// deleteAccount
255+
// cleanupTokens
256+
}

tests/phpunit/test-config.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33

44
const DBPATH = ":memory:";
55
const TRUSTED_IPS = ['127.0.0.100'];
6+
const BANNED_PASSWORDS = [];
7+
const MINIMUM_PASSWORD_ENTROPY = 10;
8+
const BASEDOMAIN = "solid.example.com";
9+
const BASEURL = "https://solid.example.com";

www/user/profile.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
$userId = preg_replace("/^id-/", "", $idPart);
2424

2525
$user = User::getUserById($userId);
26-
if (!isset($user['storage'])) {
26+
if (!isset($user['storage']) || !$user['storage']) {
2727
$user['storage'] = "https://storage-" . $userId . "." . BASEDOMAIN . "/";
2828
}
29+
if (is_array($user['storage'])) { // empty array is already handled
30+
$user['storage'] = array_values($user['storage'])[0]; // FIXME: Handle multiple storage pods
31+
}
2932
if (!isset($user['issuer'])) {
3033
$user['issuer'] = BASEURL;
3134
}

0 commit comments

Comments
 (0)