Skip to content

Commit

Permalink
Merge pull request #13 from pdsinterop/dev
Browse files Browse the repository at this point in the history
merge dev branch
  • Loading branch information
michielbdejong authored Sep 28, 2020
2 parents f751c95 + d6e04f1 commit bf4e171
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 4 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,17 @@ If you discover any security related issues, please email <[email protected]
-->

## Running solid/webid-provider-tests
Due to https://github.com/pdsinterop/php-solid-server/issues/8 you should run, in one terminal window:
```sh
HOST=127.0.0.1 composer serve-dev
```
and in another you run the [webid-provider-test](https://github.com/solid/webid-provider-tests) as:
```sh
SERVER_ROOT=http://localhost:8080 ./node_modules/.bin/jest test/surface/fetch-openid-config.test.ts
```
The current `dev` branch of php-solid-server should pass roughly 7 out of 17 tests.

## Available Features

Based on the specifications, the following features are available:
Expand Down
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"config": {
"bin-dir": "./bin",
"platform": {
"php": "7.1.33",
"php": "7.3.11",
"ext-dom": "0.0.0",
"ext-mbstring": "0.0.0"
},
Expand All @@ -28,7 +28,8 @@
"league/flysystem": "^1.0.",
"league/oauth2-server": "^8.0",
"league/route": "^4.5",
"pdsinterop/flysystem-rdf": "^0.1",
"pdsinterop/flysystem-rdf": "dev-dev",
"pdsinterop/solid-auth": "dev-feature/implicit-grant",
"php-http/httplug": "^2.1",
"phptal/phptal": "^1.4"
},
Expand All @@ -37,7 +38,7 @@
},
"scripts": {
"lint":"",
"serve-dev":"ENVIRONMENT=development php -S \"${HOST:-localhost}:${PORT:-8080}\" -t web/ web/index.php",
"serve-dev":"USER=alice PASSWORD=alice123 ENVIRONMENT=development php -S \"${HOST:-localhost}:${PORT:-8080}\" -t web/ web/index.php",
"serve-dev-docker":"bash ./bin/serve-docker-dev.sh",
"test":"phpunit"
},
Expand Down
54 changes: 54 additions & 0 deletions src/Controller/AuthorizeController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php declare(strict_types=1);

namespace Pdsinterop\Solid\Controller;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class AuthorizeController extends AbstractController
{
final public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface
{
$httpHost = $request->getServerParams()['HTTP_HOST'];

// // Create a request
// if (!$this->userManager->userExists($this->userId)) {
// $result = new JSONResponse('Authorization required');
// $result->setStatus(401);
// return $result;
// }

$parser = new \Lcobucci\JWT\Parser();
$token = $parser->parse($_GET['request']);
$_SESSION['token'] = $token;

$user = new \Pdsinterop\Solid\Auth\Entity\User();
$user->setIdentifier('https://server/profile/card#me');

$getVars = $_GET;
if (!isset($getVars['grant_type'])) {
$getVars['grant_type'] = 'implicit';
}
$getVars['response_type'] = 'token';
$getVars['scope'] = "openid";

if (!isset($getVars['redirect_uri'])) {
$getVars['redirect_uri'] = 'https://solid.community/.well-known/solid/login';
}
$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $getVars, $_POST, $_COOKIE, $_FILES);
$response = new \Laminas\Diactoros\Response();
$server = new \Pdsinterop\Solid\Auth\Server($this->authServerFactory, $this->authServerConfig, $response);

// if (!$this->checkApproval()) {
// $result = new JSONResponse('Approval required');
// $result->setStatus(302);
// $result->addHeader("Location", $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.server.sharing")));
// return $result;
// }

// FIXME: check if the user has approved - if not, show approval screen;
$approval = \Pdsinterop\Solid\Auth\Enum\Authorization::APPROVED;
// $approval = false;
return $server->respondToAuthorizationRequest($request, $user, $approval);
}
}
34 changes: 34 additions & 0 deletions src/Controller/LoginController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

namespace Pdsinterop\Solid\Controller;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class LoginController extends AbstractController
{
final public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface
{
$postBody = $request->getParsedBody();
$response = $this->getResponse();
// var_dump($_SESSION);
if (isset($_SESSION['userid'])) {
$user = $_SESSION['userid'];
$response->getBody()->write("<h1>Already logged in as $user</h1>");
} else if ($postBody['user'] == $_ENV['USER'] && $postBody['password'] == $_ENV['PASSWORD']) {
$user = $postBody['user'];
$response->getBody()->write("<h1>Welcome $user</h1>\n");
$_SESSION['userid'] = $user;
echo("session started\n");
var_dump($_SESSION);
} else {
// var_dump($postBody);
echo("cookie:\n");
var_dump($_COOKIE);
echo("session:\n");
var_dump($_SESSION);
$response->getBody()->write("<h1>No (try posting user=alice&password=alice123)</h1>\n");
}
return $response;
}
}
159 changes: 159 additions & 0 deletions src/Controller/OpenidController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php declare(strict_types=1);

namespace Pdsinterop\Solid\Controller;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

class OpenidController extends AbstractController
{
private $keys;

public function __construct(){
// parent::__construct();
require_once(__DIR__.'/../../vendor/autoload.php');

$this->keys = $this->getKeys();
}
private function linkToRoute($route) {
return "/$route";
}
private function getBaseUrl($httpHost) {
return "https://$httpHost";
}
private function getAbsoluteUrl($relativeUrl, $baseUrl) {
return "$baseUrl$relativeUrl";
}
private function getOpenIdConfiguration($baseUrl) {
return array(
'issuer' => $baseUrl,
'authorization_endpoint' => $this->getAbsoluteUrl($this->linkToRoute("authorize"), $baseUrl),
'jwks_uri' => $this->getAbsoluteUrl($this->linkToRoute("jwks"), $baseUrl),
"response_types_supported" => array("code","code token","code id_token","id_token code","id_token","id_token token","code id_token token","none"),
"token_types_supported" => array("legacyPop","dpop"),
"response_modes_supported" => array("query","fragment"),
"grant_types_supported" => array("authorization_code","implicit","refresh_token","client_credentials"),
"subject_types_supported" => ["public"],
"id_token_signing_alg_values_supported" => ["RS256"],
"token_endpoint_auth_methods_supported" => "client_secret_basic",
"token_endpoint_auth_signing_alg_values_supported" => ["RS256"],
"display_values_supported" => [],
"claim_types_supported" => ["normal"],
"claims_supported" => [],
"claims_parameter_supported" => false,
"request_parameter_supported" => true,
"request_uri_parameter_supported" => false,
"require_request_uri_registration" => false,
"check_session_iframe" => $this->getAbsoluteUrl($this->linkToRoute("session"), $baseUrl),
"end_session_endpoint" => $this->getAbsoluteUrl($this->linkToRoute("logout"), $baseUrl),
"token_endpoint" => $this->getAbsoluteUrl($this->linkToRoute("token"), $baseUrl),
"userinfo_endpoint" => $this->getAbsoluteUrl($this->linkToRoute("userinfo"), $baseUrl),
"registration_endpoint" => $this->getAbsoluteUrl($this->linkToRoute("register"), $baseUrl),
// "sharing_endpoint" => $this->getAbsoluteUrl($this->linkToRoute("sharing"), $baseUrl)
);
}
private function getKeys() {
// FIXME: read these from the solid config in nextcloud;
$encryptionKey = 'P76gcBVeXsVzrHiYp4IIwore5rQz4cotdZ2j9GV5V04=';
$privateKey = <<<EOF
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvqb0htUFZaZ+z5rn7cHWg0VzsSoVnusbtJvwWtHfD0T0s6Hb
OqzE5h2fgdGbB49HRtc21SNHx6jeEStGv03yyqYkLUKrJJSg+ksrL+pT3Nd0h25q
sx7YUoPPxnm6sbd3XTg5efCb2yyV2dOoAegUPjK46Ra6PqUvmICQWDsjnv0VJIx+
TdDWmKY2xElk0T6CVNMD08OZVTHPwJgpGdRZyCK/SSmrvmAZ6K3ocKySJdKgYriR
bVMdx9NsczRkYU9b7tUpPmLu3IvsLboTbfRN23Y70Gx3Z8fuI1FRn23sEuQSIRW+
NsAi7l+AEdJ7MdYn0xSY6YMNJ0/aGXi55gagQwIDAQABAoIBAQCz8CNNtnPXkqKR
EmTfk1kAoGYmyc+KI+AMQDlDnlzmrnA9sf+Vi0Zy4XaQMeId6m6dP7Yyx4+Rs6GT
lsK4/7qs5M20If4hEl40nQlvubvY7UjAIch2sh/9EQbjDjTUUpJH2y70FdEjtRrh
cdBZrE6evYSkCZ1STtlzF7QkcfyWqilTHEntrHRaM3N+B6F74Yi5g6VyGE9uqKEM
EuGDHVSXizdUjauTTVEa4o7pxTh+eTIdQsfRewer7iuxFPo2vBNOTU2O/obNUsVK
mgmGM4QDjurgXLL2XPr0dVVo3eiFvIdmtZgGVyLfL/vUXH7bwUIfkV6qWyRmdBiY
Dfsm8BJBAoGBAOGebDUVnP3NgFacWVYrtvBXcH2Q6X1W6JEAxctDDsnjchTdyG9E
zcsMVM/gFKXIDF5VeNoSt2pwCTBL6K0oPC31c01clActbHStaJWOOCuifzrvmu4n
X51TNGoKggbbSVx1UTifKte2t6SPRaZ26EqVrmO44fGkA3ip6TRYnSFzAoGBANhT
J47EieRWiNflq9XqDAZ1fZzo3AHB+b+pO4r8GZr3Dw0ShCAnQXv7Gb2JAJvE3UrC
Aq5r3yZMM7nI+n/OT06+UcJ3/vDGAPx9trNrpWkwmcWBmoBfp86vDRhT0kEIiKbO
wLYMmSNLHNkmQQdBX2ytnsRxRyCWtQmm09bzOJHxAoGBAKEB/nSPnP5elfS5FOPy
xFWWANgK/yWMTOGV7JFWpIocvz/22d/V+QqrHSdP4UxBi9oSIvF1I+FYXKZTtZNE
wFWH8SXHKHhKyTgmvBjmal1xVFyJu0WzYX+TbjcykoI0IZFSw4ilxdw1L67G88yM
1M7NLKtLuCpKgpOspZjOmCvTAoGAGji6KswYCt2SaNkmIx/jpUTInSR8xpnEtD7H
QOmeEPKxmFwON/eKMIUXcaoRsNAEIvOxb4MT4YiLHJIIC0XuxxS6xF/XP0hBBloW
s1jxC/cgLJixKa5uoNcHN1OxwMBQECgvo+GTDnwkWw4QA9kgwAOroxQ4EvMxrqHS
O9Pvn4ECgYA7xr/3Sz8n+BhgOdABW0m91P144rK9QDYiaClSxAha1KiFunmAy3pB
Uxdl4yTCTA9yKIH7X3bShDXnj+RmEZ+SkwzpPuKvAE8ZkZQuXv41anFrZYkR2PZy
oYiERqXgH5yS/mkDeXRFx1nWsVxjoLWfd/Vi7Lr43cuYFy4UjqXZdg==
-----END RSA PRIVATE KEY-----
EOF;

$key = openssl_pkey_get_private($privateKey);
$publicKey = openssl_pkey_get_details($key)['key'];

return array(
"encryptionKey" => $encryptionKey,
"privateKey" => $privateKey,
"publicKey" => $publicKey
);
}
private function getClientId() {
return "coolApp";
}
private function getClient($clientId, $baseUrl) {
if (!$clientId) {
$clientId = $this->getClientId(); // FIXME: only continue if a clientId is set;
}

if ($clientId) { // FIXME: and check that we know this client and get the client secret/client name for this client;
$clientSecret = "super-secret-secret-squirrel";

// FIXME: use the redirect URIs as indicated by the client;
$clientRedirectUris = array(
$this->getAbsoluteURL($this->linkToRoute("token"), $baseUrl),
'https://solid.community/.well-known/solid/login',
'http://localhost:3001/redirect'
);
$clientName = "Nextcloud";

return new \Pdsinterop\Solid\Auth\Config\Client(
$clientId,
$clientSecret,
$clientRedirectUris,
$clientName
);
} else {
return new \Pdsinterop\Solid\Auth\Config\Client('','',array(),'');
}
}

private function createConfig($baseUrl) {
// if (isset($_GET['client_id'])) {
$clientId = $_GET['client_id'];
$client = $this->getClient($clientId, $baseUrl);
// }
try {
$config = (new \Pdsinterop\Solid\Auth\Factory\ConfigFactory(
$client,
$this->keys['encryptionKey'],
$this->keys['privateKey'],
$this->keys['publicKey'],
$this->openIdConfiguration
))->create();
} catch(\Throwable $e) {
var_dump($e);
}
return $config;
}

final public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface
{
$httpHost = $request->getServerParams()['HTTP_HOST'];
$baseUrl = $this->getBaseUrl($httpHost);
$this->openIdConfiguration = $this->getOpenIdConfiguration($baseUrl);

$this->authServerConfig = $this->createConfig($baseUrl);
$this->authServerFactory = (new \Pdsinterop\Solid\Auth\Factory\AuthorizationServerFactory($this->authServerConfig))->create();

$response = $this->getResponse();
$server = new \Pdsinterop\Solid\Auth\Server($this->authServerFactory, $this->authServerConfig, $response);
return $server->respondToOpenIdMetadataRequest();
}
}
3 changes: 2 additions & 1 deletion src/Controller/Profile/CardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ final public function __invoke(ServerRequestInterface $request, array $args): Re
$contentType = $this->getContentTypeForFormat($format);

/** @noinspection PhpUndefinedMethodInspection */ // Method `readRdf` is defined by plugin
$content = $filesystem->readRdf($filePath, $format);
$url = $request->getServerParams()["REQUEST_URI"];
$content = $filesystem->readRdf($filePath, $format, $url);

return $this->createTextResponse($content)->withHeader('Content-Type', $contentType);
}
Expand Down
10 changes: 10 additions & 0 deletions tests/fixtures/foaf.rdf
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,18 @@
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:ldp="http://www.w3.org/ns/ldp#"
xmlns:solid="http://www.w3.org/ns/solid/terms#"
xmlns:space="http://www.w3.org/ns/pim/space#"
>
<foaf:Person rdf:ID="me">
<ldp:inbox rdf:resource="/inbox/"/>
<solid:account rdf:resource="/"/>
<space:storage rdf:resource="/"/>
<solid:privateTypeIndex rdf:resource="/settings/privateTypeIndex.ttl"/>
<solid:publicTypeIndex rdf:resource="/settings/publicTypeIndex.ttl"/>
<space:preferencesFile rdf:resource="/settings/preferencesFile.ttl"/>
<rdf:type rdf:resource="http://schema.org/Person"/>
<foaf:depiction rdf:resource="https://www.gravatar.com/avatar/f8d7c4a4899736c59ec1e40c7021d477?s=1024"/>
<foaf:family_name>Peachey</foaf:family_name>
<foaf:givenname>Ben</foaf:givenname>
Expand Down
10 changes: 10 additions & 0 deletions web/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@
use League\Route\Http\Exception\NotFoundException;
use League\Route\Router;
use League\Route\Strategy\ApplicationStrategy;
use Pdsinterop\Solid\Controller\LoginController;
use Pdsinterop\Solid\Controller\AddSlashToPathController;
use Pdsinterop\Solid\Controller\HelloWorldController;
use Pdsinterop\Solid\Controller\HttpToHttpsController;
use Pdsinterop\Solid\Controller\Profile\CardController;
use Pdsinterop\Solid\Controller\Profile\ProfileController;
use Pdsinterop\Solid\Controller\OpenidController;
use Pdsinterop\Solid\Controller\AuthorizeController;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

Expand All @@ -32,6 +35,7 @@
);
$strategy = new ApplicationStrategy();

session_start();
$router = new Router();

/*/ Wire objects together /*/
Expand Down Expand Up @@ -68,11 +72,14 @@
});

$controllers = [
LoginController::class,
AddSlashToPathController::class,
CardController::class,
HelloWorldController::class,
HttpToHttpsController::class,
ProfileController::class,
OpenidController::class,
AuthorizeController::class
];

$traits = [
Expand Down Expand Up @@ -110,10 +117,13 @@
$router->map('GET', '/', HelloWorldController::class)->setScheme($scheme);

/*/ Create URI groups /*/
$router->map('POST', '/login', LoginController::class)->setScheme($scheme);
$router->map('GET', '/profile', AddSlashToPathController::class)->setScheme($scheme);
$router->map('GET', '/profile/', ProfileController::class)->setScheme($scheme);
$router->map('GET', '/profile/card', CardController::class)->setScheme($scheme);
$router->map('GET', '/profile/card{extension}', CardController::class)->setScheme($scheme);
$router->map('GET', '/.well-known/openid-configuration', OpenidController::class)->setScheme($scheme);
$router->map('GET', '/authorize', AuthorizeController::class)->setScheme($scheme);

try {
$response = $router->dispatch($request);
Expand Down

0 comments on commit bf4e171

Please sign in to comment.