From cbb54b6dfa3157f544a4539f22672a27e4ebc92b Mon Sep 17 00:00:00 2001
From: Maxence Lange
Date: Tue, 8 Nov 2022 10:40:20 -0100
Subject: [PATCH 1/3] confirmation popup
Signed-off-by: Maxence Lange
---
appinfo/routes.php | 1 +
lib/Controller/OAuthController.php | 57 +++++++++++++++++++++++++-----
templates/oauth2.php | 26 ++++++++++++++
3 files changed, 75 insertions(+), 9 deletions(-)
create mode 100644 templates/oauth2.php
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 90ef2f44..861bcb93 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -70,6 +70,7 @@ return [
['name' => 'OAuth#nodeinfo2', 'url' => '/.well-known/nodeinfo/2.0', 'verb' => 'GET'],
['name' => 'OAuth#apps', 'url' => '/api/v1/apps', 'verb' => 'POST'],
['name' => 'OAuth#authorize', 'url' => '/oauth/authorize', 'verb' => 'GET'],
+ ['name' => 'OAuth#authorizing', 'url' => '/oauth/authorize', 'verb' => 'POST'],
['name' => 'OAuth#token', 'url' => '/oauth/token', 'verb' => 'POST'],
// Api for 3rd party
diff --git a/lib/Controller/OAuthController.php b/lib/Controller/OAuthController.php
index 05836f99..238cb402 100644
--- a/lib/Controller/OAuthController.php
+++ b/lib/Controller/OAuthController.php
@@ -45,6 +45,7 @@ use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\TemplateResponse;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUserSession;
@@ -172,13 +173,57 @@ class OAuthController extends Controller {
string $redirect_uri,
string $response_type,
string $scope = 'read'
+ ): Response {
+ try {
+ $user = $this->userSession->getUser();
+
+ // check actor exists
+ $this->accountService->getActorFromUserId($user->getUID());
+
+ if ($response_type !== 'code') {
+ throw new ClientNotFoundException('invalid response type');
+ }
+
+ // check client exists in db
+ $this->clientService->getFromClientId($client_id);
+
+ return new TemplateResponse(Application::APP_NAME, 'oauth2', [
+ 'request' =>
+ [
+ 'clientId' => $client_id,
+ 'redirectUri' => $redirect_uri,
+ 'responseType' => $response_type,
+ 'scope' => $scope
+ ]
+ ]);
+
+ } catch (Exception $e) {
+ $this->logger->notice($e->getMessage() . ' ' . get_class($e));
+
+ return new TemplateResponse(
+ Application::APP_NAME,
+ 'oauth2',
+ ['error' => $e->getMessage()]
+ );
+ }
+ }
+
+
+ /**
+ * @NoAdminRequired
+ */
+ public function authorizing(
+ string $client_id,
+ string $redirect_uri,
+ string $response_type,
+ string $scope = 'read'
): DataResponse {
try {
$user = $this->userSession->getUser();
$account = $this->accountService->getActorFromUserId($user->getUID());
if ($response_type !== 'code') {
- return new DataResponse(['error' => 'invalid_type'], Http::STATUS_BAD_REQUEST);
+ throw new ClientNotFoundException('invalid response type');
}
$client = $this->clientService->getFromClientId($client_id);
@@ -204,18 +249,12 @@ class OAuthController extends Controller {
// TODO : finalize result if no redirect_url
return new DataResponse(
- [
- 'code' => $code,
- // 'access_token' => '',
- // "token_type" => "Bearer",
- // "scope" => "read write follow push",
- // "created_at" => 1573979017
- ], Http::STATUS_OK
+ ['code' => $code], Http::STATUS_OK
);
} catch (Exception $e) {
$this->logger->notice($e->getMessage() . ' ' . get_class($e));
- return new DataResponse(['error' => $e->getMessage()], Http::STATUS_UNAUTHORIZED);
+ return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
}
}
diff --git a/templates/oauth2.php b/templates/oauth2.php
new file mode 100644
index 00000000..2b192b05
--- /dev/null
+++ b/templates/oauth2.php
@@ -0,0 +1,26 @@
+
+ *
+ * @author Jonas Sulzer
+ * @author Julius Härtl
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+
+\OCP\Util::addScript('social', 'social-oauth2');
From fb266f056d2540e884ab56479c4ae47c5262637e Mon Sep 17 00:00:00 2001
From: Carl Schwan
Date: Mon, 21 Nov 2022 14:53:49 +0100
Subject: [PATCH 2/3] Implement UI
Signed-off-by: Carl Schwan
---
lib/Controller/OAuthController.php | 20 +++----
src/oauth.js | 38 ++++++++++++
src/views/OAuth2Authorize.vue | 95 ++++++++++++++++++++++++++++++
templates/oauth2.php | 4 +-
webpack.common.js | 3 +-
5 files changed, 145 insertions(+), 15 deletions(-)
create mode 100644 src/oauth.js
create mode 100644 src/views/OAuth2Authorize.vue
diff --git a/lib/Controller/OAuthController.php b/lib/Controller/OAuthController.php
index 238cb402..c1c20ec2 100644
--- a/lib/Controller/OAuthController.php
+++ b/lib/Controller/OAuthController.php
@@ -46,6 +46,7 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
use OCP\IRequest;
use OCP\IURLGenerator;
use OCP\IUserSession;
@@ -60,6 +61,7 @@ class OAuthController extends Controller {
private ClientService $clientService;
private ConfigService $configService;
private LoggerInterface $logger;
+ private IInitialState $initialState;
public function __construct(
IRequest $request,
@@ -70,7 +72,8 @@ class OAuthController extends Controller {
CacheActorService $cacheActorService,
ClientService $clientService,
ConfigService $configService,
- LoggerInterface $logger
+ LoggerInterface $logger,
+ IInitialState $initialState
) {
parent::__construct(Application::APP_NAME, $request);
@@ -82,6 +85,7 @@ class OAuthController extends Controller {
$this->clientService = $clientService;
$this->configService = $configService;
$this->logger = $logger;
+ $this->initialState = $initialState;
$body = file_get_contents('php://input');
$logger->debug('[OAuthController] input: ' . $body);
@@ -174,7 +178,6 @@ class OAuthController extends Controller {
string $response_type,
string $scope = 'read'
): Response {
- try {
$user = $this->userSession->getUser();
// check actor exists
@@ -185,7 +188,8 @@ class OAuthController extends Controller {
}
// check client exists in db
- $this->clientService->getFromClientId($client_id);
+ $client = $this->clientService->getFromClientId($client_id);
+ $this->initialState->provideInitialState('appName', $client->getAppName());
return new TemplateResponse(Application::APP_NAME, 'oauth2', [
'request' =>
@@ -196,16 +200,6 @@ class OAuthController extends Controller {
'scope' => $scope
]
]);
-
- } catch (Exception $e) {
- $this->logger->notice($e->getMessage() . ' ' . get_class($e));
-
- return new TemplateResponse(
- Application::APP_NAME,
- 'oauth2',
- ['error' => $e->getMessage()]
- );
- }
}
diff --git a/src/oauth.js b/src/oauth.js
new file mode 100644
index 00000000..7138183e
--- /dev/null
+++ b/src/oauth.js
@@ -0,0 +1,38 @@
+/**
+ * @copyright 2022 Carl Schwan
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import Vue from 'vue'
+import OAuth2Authorize from './views/OAuth2Authorize.vue'
+
+// CSP config for webpack dynamic chunk loading
+// eslint-disable-next-line
+__webpack_nonce__ = btoa(OC.requestToken)
+
+// Correct the root of the app for chunk loading
+// OC.linkTo matches the apps folders
+// eslint-disable-next-line
+__webpack_public_path__ = OC.linkTo('social', 'js/')
+
+Vue.prototype.t = t
+Vue.prototype.n = n
+Vue.prototype.OC = OC
+Vue.prototype.OCA = OCA
+
+new Vue({
+ render: h => h(OAuth2Authorize),
+}).$mount('#social-oauth2')
diff --git a/src/views/OAuth2Authorize.vue b/src/views/OAuth2Authorize.vue
new file mode 100644
index 00000000..0732f1ec
--- /dev/null
+++ b/src/views/OAuth2Authorize.vue
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/oauth2.php b/templates/oauth2.php
index 2b192b05..9cb80a07 100644
--- a/templates/oauth2.php
+++ b/templates/oauth2.php
@@ -22,5 +22,7 @@
*
*/
+\OCP\Util::addScript('social', 'social-oauth');
+?>
-\OCP\Util::addScript('social', 'social-oauth2');
+
diff --git a/webpack.common.js b/webpack.common.js
index dcacd5d9..48fef45f 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -8,7 +8,8 @@ webpackConfig.entry = {
social: path.join(__dirname, 'src', 'main.js'),
ostatus: path.join(__dirname, 'src', 'ostatus.js'),
profilePage: path.join(__dirname, 'src', 'profile.js'),
- dashboard: path.join(__dirname, 'src', 'dashboard.js'),
+ dashboard: path.join(__dirname, 'src', 'dashboard.js'),
+ oauth: path.join(__dirname, 'src', 'oauth.js'),
}
module.exports = webpackConfig
From 58ca8655231af322f3ab4c291ad774d6bf960805 Mon Sep 17 00:00:00 2001
From: Carl Schwan
Date: Mon, 21 Nov 2022 15:58:36 +0100
Subject: [PATCH 3/3] Fix csrf error
Signed-off-by: Carl Schwan
---
src/views/OAuth2Authorize.vue | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/views/OAuth2Authorize.vue b/src/views/OAuth2Authorize.vue
index 0732f1ec..01041d5a 100644
--- a/src/views/OAuth2Authorize.vue
+++ b/src/views/OAuth2Authorize.vue
@@ -24,6 +24,9 @@
{{ t('social', '{appDisplayName} would like permission to access your account. It is a third party application.', {appDisplayName: appName}) }}
{{ t('social', 'If you do not trust it, then you should not authorize it.') }}