diff --git a/.config/phpcs.xml.dist b/.config/phpcs.xml.dist index a6147742..c63bc0a9 100644 --- a/.config/phpcs.xml.dist +++ b/.config/phpcs.xml.dist @@ -20,6 +20,13 @@ + + + + + + + diff --git a/init.sh b/init.sh index 4612a96b..e066c923 100644 --- a/init.sh +++ b/init.sh @@ -9,3 +9,4 @@ php console.php config:system:set trusted_domains 3 --value=thirdparty # set 'tester' and 'https://tester' as allowed clients for the test suite to run php console.php user:setting alice solid allowedClients '["f5d1278e8109edd94e1e4197e04873b9", "2e5cddcf0f663544e98982931e6cc5a6"]' echo configured +mkdir -p /var/www/html/data/files_trashbin/versions \ No newline at end of file diff --git a/solid/appinfo/info.xml b/solid/appinfo/info.xml index ae64a0ff..5948943f 100644 --- a/solid/appinfo/info.xml +++ b/solid/appinfo/info.xml @@ -16,6 +16,9 @@ When you do this, the Solid App can store data in your Nextcloud account through Auke van Slooten Solid integration + + + https://github.com/pdsinterop/solid-nextcloud/issues diff --git a/solid/lib/AppInfo/Application.php b/solid/lib/AppInfo/Application.php index cb507bc0..ab6d2014 100644 --- a/solid/lib/AppInfo/Application.php +++ b/solid/lib/AppInfo/Application.php @@ -10,21 +10,31 @@ use OCA\Solid\Service\SolidWebhookService; use OCA\Solid\Db\SolidWebhookMapper; use OCA\Solid\Middleware\SolidCorsMiddleware; +use OCA\Solid\ClientAuth; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\IDBConnection; +use OCP\IRequest; +use OCP\Server; class Application extends App implements IBootstrap { public const APP_ID = 'solid'; - public static $userSubDomainsEnabled; + public static $userSubDomainsEnabled; /** * @param array $urlParams */ public function __construct(array $urlParams = []) { + $request = \OCP\Server::get(\OCP\IRequest::class); + $rawPathInfo = $request->getRawPathInfo(); + + if ($rawPathInfo == '/apps/solid/token') { + $backend = new \OCA\Solid\ClientAuth(); + \OC::$server->getUserManager()->registerBackend($backend); + } parent::__construct(self::APP_ID, $urlParams); } diff --git a/solid/lib/ClientAuth.php b/solid/lib/ClientAuth.php new file mode 100644 index 00000000..9eb9f0ee --- /dev/null +++ b/solid/lib/ClientAuth.php @@ -0,0 +1,62 @@ +getClient($clientId); $keys = $this->getKeys(); try { @@ -316,7 +323,25 @@ public function session() { */ public function token() { $request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES); - $code = $request->getParsedBody()['code']; + $grantType = $request->getParsedBody()['grant_type']; + switch ($grantType) { + case "authorization_code": + $code = $request->getParsedBody()['code']; + // FIXME: not sure if decoding this here is the way to go. + // FIXME: because this is a public page, the nonce from the session is not available here. + $codeInfo = $this->tokenGenerator->getCodeInfo($code); + $userId = $codeInfo['user_id']; + break; + case "refresh_token": + $refreshToken = $request->getParsedBody()['refresh_token']; + $tokenInfo = $this->tokenGenerator->getCodeInfo($refreshToken); // FIXME: getCodeInfo should be named 'decrypt' or 'getInfo'? + $userId = $tokenInfo['user_id']; + break; + default: + $userId = false; + break; + } + $clientId = $request->getParsedBody()['client_id']; $httpDpop = $request->getServerParams()['HTTP_DPOP']; @@ -325,17 +350,16 @@ public function token() { $server = new \Pdsinterop\Solid\Auth\Server($this->authServerFactory, $this->authServerConfig, $response); $response = $server->respondToAccessTokenRequest($request); - // FIXME: not sure if decoding this here is the way to go. - // FIXME: because this is a public page, the nonce from the session is not available here. - $codeInfo = $this->tokenGenerator->getCodeInfo($code); - $response = $this->tokenGenerator->addIdTokenToResponse( - $response, - $clientId, - $codeInfo['user_id'], - ($_SESSION['nonce'] ?? ''), - $this->config->getPrivateKey(), - $httpDpop - ); + if ($userId) { + $response = $this->tokenGenerator->addIdTokenToResponse( + $response, + $clientId, + $userId, + ($_SESSION['nonce'] ?? ''), + $this->config->getPrivateKey(), + $httpDpop + ); + } return $this->respond($response); // ->addHeader('Access-Control-Allow-Origin', '*'); } @@ -380,14 +404,7 @@ public function register() { $clientData = $this->config->saveClientRegistration($origin, $clientData); $registration = array( 'client_id' => $clientData['client_id'], - /* - FIXME: returning client_secret will trigger calls with basic auth to us. To get this to work, we need this patch: - // File /var/www/vhosts/solid-nextcloud/site/www/lib/base.php not changed so no update needed - // ($request->getRawPathInfo() !== '/apps/oauth2/api/v1/token') && - // ($request->getRawPathInfo() !== '/apps/solid/token') - */ - // 'client_secret' => $clientData['client_secret'], // FIXME: Returning this means we need to patch Nextcloud to accept tokens on calls to - + 'client_secret' => $clientData['client_secret'], 'registration_client_uri' => $this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkToRoute("solid.server.registeredClient", array("clientId" => $clientData['client_id']))), 'client_id_issued_at' => $clientData['client_id_issued_at'], 'redirect_uris' => $clientData['redirect_uris'], diff --git a/solid/tests/Integration/AppTest.php b/solid/tests/Integration/AppTest.php index 6347f963..f12c4b5e 100644 --- a/solid/tests/Integration/AppTest.php +++ b/solid/tests/Integration/AppTest.php @@ -5,7 +5,6 @@ use OCP\AppFramework\App; use Test\TestCase; - /** * This test shows how to make a small Integration Test. Query your class * directly from the container, only pass in mocks if needed and run your tests diff --git a/solid/tests/Unit/Controller/ServerControllerTest.php b/solid/tests/Unit/Controller/ServerControllerTest.php index b1104cbd..2920b0dd 100644 --- a/solid/tests/Unit/Controller/ServerControllerTest.php +++ b/solid/tests/Unit/Controller/ServerControllerTest.php @@ -16,7 +16,6 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; - function file_get_contents($filename) { if ($filename === 'php://input') {