RDF Format
-
- diff --git a/README.md b/README.md index d8a1729..4689dee 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,17 @@ _Standalone Solid Server written in PHP by PDS Interop_ - [Background](#background) - * [Installation](#installation) +- [Installation](#installation) - [Usage](#usage) - * [Docker images](#docker-images) - * [Local environment](#local-environment) - + [Built-in PHP HTTP server](#built-in-php-http-server) + - [Docker images](#docker-images) + - [Local environment](#local-environment) + - [Built-in PHP HTTP server](#built-in-php-http-server) - [Security](#security) - [Running solid/webid-provider-tests](#running-solidwebid-provider-tests) - [Available Features](#available-features) - [Development](#development) - * [Project structure](#project-structure) - * [Coding conventions](#coding-conventions) - * [Testing](#testing) + - [Project structure](#project-structure) + - [Testing](#testing) - [Contributing](#contributing) - [License](#license) @@ -47,10 +46,6 @@ they define: - Resource (reading and writing) API - Social Web App Protocols (Notifications, Friends Lists, Followers and Following) - - ## Installation To install the project, clone it from GitHub and install the PHP dependencies @@ -67,21 +62,15 @@ At this point, the application is ready to run. The PHP Solid server can be run in several different ways. - - The application can be run with a Docker image of your choice or on a local environment, using Apache, NginX, or PHP's internal HTTP server. The latter is only advised in development. For security reasons, the server expects to run on HTTPS (also known as HTTP+TLS). -To run insecure, set the environment variable `ENVIRONMENT` to `develop`. This -will prohibit the application from running in production mode. - - +To run insecure, for instance when the application is run behind a proxy or in a +PHP-FPM (or similar) setup, set the environment variable `PROXY_MODE`. +This will allow the application to accept HTTP requests. ### Docker images @@ -209,71 +198,61 @@ The underlying functionality for these features is provided by: ## Development +The easiest way to develop this project is by running the environment provided +by the `docker-compose.yml` file. This can be done by running `docker-compose up`. + +This will start the application and a pubsub server in separate docker containers. + ### Project structure This project is structured as follows: - ``` . - ├── src <- Source code - ├── vendor <- Third-party and vendor code - ├── web <- Web content + ├── bin/ <- CLI scripts + ├── config/ <- Empty directory where server configuration is generated + ├── docs/ <- Documentation + ├── src/ <- Source code + ├── tests/ <- Test fixtures, Integration- and unit-tests + ├── vendor/ <- Third-party and vendor code + ├── web/ <- Web content ├── composer.json <- PHP package and dependency configuration └── README.md <- You are now here ``` - ## Contributing -Questions or feedback can be given by [opening an issue on GitHub](https://github.com/pdsinterop/php-solid-server/issues). +Questions or feedback can be given by [opening an issue on GitHub][issues-link]. All PDS Interop projects are open source and community-friendly. Any contribution is welcome! -For more details read the [contribution guidelines](CONTRIBUTING.md). +For more details read the [contribution guidelines][contributing-link]. All PDS Interop projects adhere to [the Code Manifesto](http://codemanifesto.com) -as its [code-of-conduct](CODE_OF_CONDUCT.md). Contributors are expected to abide by its terms. +as its [code-of-conduct][code-of-conduct]. Contributors are expected to abide by its terms. There is [a list of all contributors on GitHub][contributors-page]. -For a list of changes see the [CHANGELOG](CHANGELOG.md) or the GitHub releases page. +For a list of changes see the [CHANGELOG][changelog] or [the GitHub releases page][releases-page]. ## License All code created by PDS Interop is licensed under the [MIT License][license-link]. -[contributors-page]: https://github.com/pdsinterop/php-solid-server/contributors +[changelog]: CHANGELOG.md +[code-of-conduct]: CODE_OF_CONDUCT.md +[contributing-link]: CONTRIBUTING.md +[contributors-page]: https://github.com/pdsinterop/php-solid-server/contributors +[issues-link]: https://github.com/pdsinterop/php-solid-server/issues +[releases-page]: https://github.com/pdsinterop/php-solid-server/releases [keep-a-changelog-link]: https://keepachangelog.com/ [keep-a-changelog-shield]: https://img.shields.io/badge/Keep%20a%20Changelog-f15d30.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHZpZXdCb3g9IjAgMCAxODcgMTg1Ij48cGF0aCBkPSJNNjIgN2MtMTUgMy0yOCAxMC0zNyAyMmExMjIgMTIyIDAgMDAtMTggOTEgNzQgNzQgMCAwMDE2IDM4YzYgOSAxNCAxNSAyNCAxOGE4OSA4OSAwIDAwMjQgNCA0NSA0NSAwIDAwNiAwbDMtMSAxMy0xYTE1OCAxNTggMCAwMDU1LTE3IDYzIDYzIDAgMDAzNS01MiAzNCAzNCAwIDAwLTEtNWMtMy0xOC05LTMzLTE5LTQ3LTEyLTE3LTI0LTI4LTM4LTM3QTg1IDg1IDAgMDA2MiA3em0zMCA4YzIwIDQgMzggMTQgNTMgMzEgMTcgMTggMjYgMzcgMjkgNTh2MTJjLTMgMTctMTMgMzAtMjggMzhhMTU1IDE1NSAwIDAxLTUzIDE2bC0xMyAyaC0xYTUxIDUxIDAgMDEtMTItMWwtMTctMmMtMTMtNC0yMy0xMi0yOS0yNy01LTEyLTgtMjQtOC0zOWExMzMgMTMzIDAgMDE4LTUwYzUtMTMgMTEtMjYgMjYtMzMgMTQtNyAyOS05IDQ1LTV6TTQwIDQ1YTk0IDk0IDAgMDAtMTcgNTQgNzUgNzUgMCAwMDYgMzJjOCAxOSAyMiAzMSA0MiAzMiAyMSAyIDQxLTIgNjAtMTRhNjAgNjAgMCAwMDIxLTE5IDUzIDUzIDAgMDA5LTI5YzAtMTYtOC0zMy0yMy01MWE0NyA0NyAwIDAwLTUtNWMtMjMtMjAtNDUtMjYtNjctMTgtMTIgNC0yMCA5LTI2IDE4em0xMDggNzZhNTAgNTAgMCAwMS0yMSAyMmMtMTcgOS0zMiAxMy00OCAxMy0xMSAwLTIxLTMtMzAtOS01LTMtOS05LTEzLTE2YTgxIDgxIDAgMDEtNi0zMiA5NCA5NCAwIDAxOC0zNSA5MCA5MCAwIDAxNi0xMmwxLTJjNS05IDEzLTEzIDIzLTE2IDE2LTUgMzItMyA1MCA5IDEzIDggMjMgMjAgMzAgMzYgNyAxNSA3IDI5IDAgNDJ6bS00My03M2MtMTctOC0zMy02LTQ2IDUtMTAgOC0xNiAyMC0xOSAzN2E1NCA1NCAwIDAwNSAzNGM3IDE1IDIwIDIzIDM3IDIyIDIyLTEgMzgtOSA0OC0yNGE0MSA0MSAwIDAwOC0yNCA0MyA0MyAwIDAwLTEtMTJjLTYtMTgtMTYtMzEtMzItMzh6bS0yMyA5MWgtMWMtNyAwLTE0LTItMjEtN2EyNyAyNyAwIDAxLTEwLTEzIDU3IDU3IDAgMDEtNC0yMCA2MyA2MyAwIDAxNi0yNWM1LTEyIDEyLTE5IDI0LTIxIDktMyAxOC0yIDI3IDIgMTQgNiAyMyAxOCAyNyAzM3MtMiAzMS0xNiA0MGMtMTEgOC0yMSAxMS0zMiAxMXptMS0zNHYxNGgtOFY2OGg4djI4bDEwLTEwaDExbC0xNCAxNSAxNyAxOEg5NnoiLz48L3N2Zz4K [license-link]: ./LICENSE diff --git a/docker-compose.yml b/docker-compose.yml index 9057a1a..d358389 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,12 +4,21 @@ services: build: context: . environment: + # During development it can be useful to set the ENVIRONMENT to "development" + # in order to see more details about the errors. + # ENVIRONMENT: development USERNAME: alice PASSWORD: alice123 + # to run in HTTP mode, set PROXY_MODE + # PROXY_MODE: true PUBSUB_URL: http://pubsub:8080 ports: - 80:80 - 443:443 + volumes: + - .:/app/ + # @TODO: The storage directory should be mounted separately + # as it really _should_ live outside the code directory pubsub: build: context: https://github.com/pdsinterop/php-solid-pubsub-server.git#main diff --git a/src/Controller/AuthorizeController.php b/src/Controller/AuthorizeController.php index bb0a427..267d10d 100644 --- a/src/Controller/AuthorizeController.php +++ b/src/Controller/AuthorizeController.php @@ -10,62 +10,99 @@ class AuthorizeController extends ServerController final public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface { if (!isset($_SESSION['userid'])) { - $response = $this->getResponse(); - $response = $response->withStatus(302, "Approval required"); - // FIXME: Generate a proper url for this; - $baseUrl = $this->baseUrl; - $loginUrl = $baseUrl . "/login/?returnUrl=" . urlencode($_SERVER['REQUEST_URI']); - $response = $response->withHeader("Location", $loginUrl); - return $response; + $loginUrl = $this->baseUrl . "/login/?returnUrl=" . urlencode($_SERVER['REQUEST_URI']); + + return $this->getResponse() + ->withHeader("Location", $loginUrl) + ->withStatus(302, "Approval required") + ; } + + $queryParams = $request->getQueryParams(); + + if (! isset($queryParams['request'])) { + return $this->getResponse() + ->withStatus(400, "Bad request, missing request") + ; + } + $parser = new \Lcobucci\JWT\Parser(); + try { + $token = $parser->parse($queryParams['request']); + } catch (\Exception $exception) { + return $this->getResponse() + ->withStatus(400, $exception->getMessage()) + ; + } + try { - $token = $parser->parse($request->getQueryParams()['request']); $_SESSION["nonce"] = $token->getClaim('nonce'); - } catch(\Exception $e) { - $_SESSION["nonce"] = $request->getQueryParams()['nonce']; + } catch(\OutOfBoundsException $e) { + if (! isset($queryParams['nonce'])) { + return $this->getResponse() + ->withStatus(400, "Bad request, missing nonce") + ; + } + + $_SESSION["nonce"] = $queryParams['nonce']; } - $getVars = $request->getQueryParams(); + /*/ Prepare GET parameters for OAUTH server request /*/ + $getVars = $queryParams; + + $getVars['response_type'] = $this->getResponseType($queryParams); + $getVars['scope'] = "openid" ; + if (!isset($getVars['grant_type'])) { $getVars['grant_type'] = 'implicit'; } - $getVars['response_type'] = $this->getResponseType(); - $getVars['scope'] = "openid" ; if (!isset($getVars['redirect_uri'])) { try { $getVars['redirect_uri'] = $token->getClaim("redirect_uri"); } catch(\Exception $e) { - $response = $this->getResponse(); - $response->withStatus(400, "Bad request, missing redirect uri"); - return $response; + return $this->getResponse() + ->withStatus(400, "Bad request, missing redirect uri") + ; } } - $clientId = $getVars['client_id']; - $approval = $this->checkApproval($clientId); + + if (! isset($queryParams['client_id'])) { + return $this->getResponse() + ->withStatus(400, "Bad request, missing client_id") + ; + } + + $clientId = $getVars['client_id']; + $approval = $this->checkApproval($clientId); if (!$approval) { - $response = $this->getResponse(); - $response = $response->withStatus(302, "Approval required"); - // FIXME: Generate a proper url for this; - $baseUrl = $this->baseUrl; - $approvalUrl = $baseUrl . "/sharing/$clientId/?returnUrl=" . urlencode($_SERVER['REQUEST_URI']); - $response = $response->withHeader("Location", $approvalUrl); - return $response; + $approvalUrl = $this->baseUrl . "/sharing/$clientId/?returnUrl=" . urlencode($_SERVER['REQUEST_URI']); + + return $this->getResponse() + ->withHeader("Location", $approvalUrl) + ->withStatus(302, "Approval required") + ; } + // replace the request getVars with the morphed version + $request = $request->withQueryParams($getVars); + $user = new \Pdsinterop\Solid\Auth\Entity\User(); $user->setIdentifier($this->getProfilePage()); - $request = $request->withQueryParams($getVars); // replace the request getVars with the morphed version; $response = new \Laminas\Diactoros\Response(); $server = new \Pdsinterop\Solid\Auth\Server($this->authServerFactory, $this->authServerConfig, $response); $response = $server->respondToAuthorizationRequest($request, $user, $approval); - $response = $this->tokenGenerator->addIdTokenToResponse($response, $clientId, $this->getProfilePage(), $_SESSION['nonce'], $this->config->getPrivateKey()); - return $response; + + return $this->tokenGenerator->addIdTokenToResponse($response, + $clientId, + $this->getProfilePage(), + $_SESSION['nonce'], + $this->config->getPrivateKey() + ); } } diff --git a/src/Controller/HelloWorldController.php b/src/Controller/HelloWorldController.php index 57ddbb2..b66f50e 100644 --- a/src/Controller/HelloWorldController.php +++ b/src/Controller/HelloWorldController.php @@ -9,10 +9,67 @@ class HelloWorldController extends AbstractController { final public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface { - $response = $this->getResponse(); - $response->getBody()->write('
The following main URL are available on this server:
+/.well-known/openid-configuration
+ Openid
+ /authorize
+ Authorize
+ /jwks
+ Jwks
+ /login/1, 3
+ Login
+ /profile/1
+ Profile
+ /profile/card2
+ Card
+ /register4
+ Register
+ /sharing/{clientId}3
+ Approval
+ /storage/{path}3
+ Resource
+ /token/1, 4
+ Token
+ //profile/card can be
+ requested as /profile/card.ttl to request a Turtle file, or /profile/card.json to
+ request a JSON-LD file
+
-
+ This will be replaced with content from other templates
diff --git a/src/Template/login.html b/src/Template/login.html index 89402d1..9a371a6 100644 --- a/src/Template/login.html +++ b/src/Template/login.html @@ -1,11 +1,12 @@ - - - -{$exception->getMessage()}
"; + $class = get_class($exception); + $html = "{$exception->getMessage()} ($class)
"; if (getenv('ENVIRONMENT') === 'development') { $html .=