-
Notifications
You must be signed in to change notification settings - Fork 1
WIP: two small fixes in Server and Account #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
16d33d4
a831df7
f1905ac
efe77bc
df2e3eb
e7fb606
a3174fb
a8ca2b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one can be removed - there is already a script for this in the testsuite directory that can be reused, it already creates the 'alice' and 'bob' accounts. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <?php | ||
| require_once(__DIR__ . "/config.php"); | ||
| require_once(__DIR__ . "/vendor/autoload.php"); | ||
|
|
||
| function addStorage($userId, $ownerWebId) { | ||
| $storageId = $userId; | ||
| try { | ||
| $pdo = new \PDO("sqlite:" . DBPATH); | ||
| $query = $pdo->prepare('INSERT INTO storage VALUES(:storageId, :owner)'); | ||
| $query->execute([ | ||
| ':storageId' => $storageId, | ||
| ':owner' => $ownerWebId | ||
| ]); | ||
| } catch(\PDOException $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
| } | ||
|
|
||
| function addUser($userId) { | ||
| try { | ||
| $pdo = new \PDO("sqlite:" . DBPATH); | ||
| $query = $pdo->prepare('INSERT INTO users VALUES (:userId, :email, :passwordHash, :data)'); | ||
| $webId = "https://id-" . $userId . "." . BASEDOMAIN . "/#me"; | ||
| $userData = [ | ||
| "id" => $userId, | ||
| "email" => $userId, | ||
| "webId" => $webId | ||
| ]; | ||
| $query->execute([ | ||
| ':userId' => $userId, | ||
| ':email' => $userId, | ||
| ':passwordHash' => password_hash($userId, PASSWORD_BCRYPT), | ||
| ':data' => json_encode($userData) | ||
| ]); | ||
| } catch(\PDOException $e) { | ||
| echo $e->getMessage(); | ||
| } | ||
| return $webId; | ||
| } | ||
|
|
||
| $users = [ | ||
| 'alice', | ||
| 'bob' | ||
| ]; | ||
|
|
||
| foreach ($users as $user) { | ||
| $webId = addUser($user); | ||
| addStorage($user, $webId); | ||
| } | ||
|
|
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this file split up? This change is adding a layer of indirection I think we don't need to add. This change reduces the file to a glue layer, but we already have a glue layer www directory.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is so that I can write unit tests for the SolidStorageHandler, which accepts request/response objects. This avoids adding complex mocks/stubs.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the www directory, would it be a good idea to move the construction of the request/response objects there, and pass them to all the separate route handlers? That fixes the problem without adding another layer. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,86 +1,21 @@ | ||
| <?php | ||
| namespace Pdsinterop\PhpSolid\Routes; | ||
|
|
||
| use Pdsinterop\PhpSolid\User; | ||
| use Pdsinterop\PhpSolid\StorageServer; | ||
| use Pdsinterop\PhpSolid\ClientRegistration; | ||
| use Pdsinterop\PhpSolid\SolidNotifications; | ||
| use Pdsinterop\PhpSolid\Util; | ||
| use Pdsinterop\Solid\Auth\WAC; | ||
| use Pdsinterop\Solid\Resources\Server as ResourceServer; | ||
| use Laminas\Diactoros\ServerRequestFactory; | ||
| use Laminas\Diactoros\Response; | ||
| namespace Pdsinterop\PhpSolid\Routes; | ||
|
|
||
| class SolidStorage { | ||
| public static function respondToStorage() { | ||
| $requestFactory = new ServerRequestFactory(); | ||
| $rawRequest = $requestFactory->fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); | ||
| use Laminas\Diactoros\ServerRequestFactory; | ||
| use Pdsinterop\PhpSolid\SolidStorageHandler; | ||
| use Pdsinterop\PhpSolid\StorageServer; | ||
|
|
||
| try { | ||
| StorageServer::initializeStorage(); | ||
| $filesystem = StorageServer::getFileSystem(); | ||
| } catch (\Exception $e) { | ||
| $response = new Response(); | ||
| $response = $response->withStatus(404, "Not found"); | ||
| StorageServer::respond($response); | ||
| exit(); | ||
| } | ||
| class SolidStorage | ||
| { | ||
| public static function respondToStorage() | ||
| { | ||
| $requestFactory = new ServerRequestFactory(); | ||
| $rawRequest = $requestFactory->fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); | ||
|
|
||
| $resourceServer = new ResourceServer($filesystem, new Response(), null); | ||
| $solidNotifications = new SolidNotifications(); | ||
| $resourceServer->setNotifications($solidNotifications); | ||
| $handler = new SolidStorageHandler(); | ||
| $response = $handler->handle($rawRequest); | ||
|
|
||
| $wac = new WAC($filesystem); | ||
|
|
||
| $baseUrl = Util::getServerBaseUrl(); | ||
| $resourceServer->setBaseUrl($baseUrl); | ||
| $wac->setBaseUrl($baseUrl); | ||
|
|
||
| try { | ||
| $webId = StorageServer::getWebId($rawRequest); | ||
| } catch(\Exception $e) { | ||
| $response = $resourceServer->getResponse() | ||
| -> withStatus(400, "Bad request"); | ||
| StorageServer::respond($response); | ||
| exit(); | ||
| } | ||
|
|
||
| if (!isset($webId)) { | ||
| $response = $resourceServer->getResponse() | ||
| ->withStatus(409, "Invalid token"); | ||
| StorageServer::respond($response); | ||
| exit(); | ||
| } | ||
|
|
||
| $origin = $rawRequest->getHeaderLine("Origin"); | ||
|
|
||
| // FIXME: Read allowed clients from the profile instead; | ||
|
|
||
| $ownerWebId = StorageServer::getOwnerWebId(); | ||
| $owner = User::getUserByWebId($ownerWebId); | ||
|
|
||
| $allowedClients = $owner['allowedClients'] ?? []; | ||
| $allowedOrigins = array_merge( | ||
| ($owner['allowedOrigins'] ?? []), | ||
| (TRUSTED_APPS ?? []) | ||
| ); | ||
| $allowedOrigins = array_unique($allowedOrigins); | ||
|
|
||
| if (!isset($origin) || ($origin === "")) { | ||
| $allowedOrigins[] = "app://unset"; // FIXME: this should not be here. | ||
| $origin = "app://unset"; | ||
| } | ||
|
|
||
| if (!$wac->isAllowed($rawRequest, $webId, $origin, $allowedOrigins)) { | ||
| $response = new Response(); | ||
| $response = $response->withStatus(403, "Access denied!"); | ||
| StorageServer::respond($response); | ||
| exit(); | ||
| } | ||
|
|
||
| $response = $resourceServer->respondToRequest($rawRequest); | ||
| $response = $wac->addWACHeaders($rawRequest, $response, $webId); | ||
| StorageServer::respond($response); | ||
| } | ||
| StorageServer::respond($response); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| <?php | ||
|
|
||
| namespace Pdsinterop\PhpSolid; | ||
|
|
||
| use Laminas\Diactoros\Response; | ||
| use Pdsinterop\Solid\Auth\WAC; | ||
| use Pdsinterop\Solid\Resources\Server as ResourceServer; | ||
| use Psr\Http\Message\ResponseInterface; | ||
| use Psr\Http\Message\ServerRequestInterface; | ||
|
|
||
| class SolidStorageHandler | ||
| { | ||
| public function handle(ServerRequestInterface $rawRequest): ResponseInterface | ||
| { | ||
| try { | ||
| StorageServer::initializeStorage(); | ||
| $filesystem = StorageServer::getFileSystem(); | ||
| } catch (\Exception $e) { | ||
| return (new Response())->withStatus(404, "Not found"); | ||
| } | ||
|
|
||
| $resourceServer = new ResourceServer($filesystem, new Response(), null); | ||
|
|
||
| $solidNotifications = new SolidNotifications(); | ||
| $resourceServer->setNotifications($solidNotifications); | ||
|
|
||
| $wac = new WAC($filesystem); | ||
|
|
||
| $baseUrl = Util::getServerBaseUrl(); | ||
| $resourceServer->setBaseUrl($baseUrl); | ||
| $wac->setBaseUrl($baseUrl); | ||
|
|
||
| try { | ||
| $webId = StorageServer::getWebId($rawRequest); | ||
| } catch (\Exception $e) { | ||
| return $resourceServer->getResponse() | ||
| ->withStatus(400, "Bad request"); | ||
| } | ||
|
|
||
| if (!isset($webId)) { | ||
| return $resourceServer->getResponse() | ||
| ->withStatus(409, "Invalid token"); | ||
| } | ||
|
|
||
| $origin = $rawRequest->getHeaderLine("Origin"); | ||
|
|
||
| // FIXME: Read allowed clients from the profile instead; | ||
| $ownerWebId = StorageServer::getOwnerWebId(); | ||
| $owner = User::getUserByWebId($ownerWebId); | ||
| $allowedClients = $owner['allowedClients'] ?? []; | ||
|
|
||
| $allowedOrigins = array_merge( | ||
| ($owner['allowedOrigins'] ?? []), | ||
| (TRUSTED_APPS ?? []) | ||
| ); | ||
| $allowedOrigins = array_unique($allowedOrigins); | ||
|
|
||
| if (!isset($origin) || ($origin === "")) { | ||
| $allowedOrigins[] = "app://unset"; // FIXME: this should not be here. | ||
| $origin = "app://unset"; | ||
| } | ||
|
|
||
| if (!$wac->isAllowed($rawRequest, $webId, $origin, $allowedOrigins)) { | ||
| return (new Response())->withStatus(403, "Access denied!"); | ||
| } | ||
|
|
||
| $response = $resourceServer->respondToRequest($rawRequest); | ||
|
|
||
| return $wac->addWACHeaders($rawRequest, $response, $webId); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a developer thing, but should not be in the default docker compose. Only the data (and maybe config) should persist to the host by default