diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2020-09-18 10:55:47 -0100 |
---|---|---|
committer | Maxence Lange <maxence@artificial-owl.com> | 2020-09-18 10:55:47 -0100 |
commit | 638838cd50ea498f634ef8b54ffbc75fce3f4216 (patch) | |
tree | 38ff9b8758647995305b178b9edfaaf8378b83f2 /lib | |
parent | c827dd3ef2ec0d2ed475f65c8f70471b0ad6788b (diff) |
single table/model for all exchange
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Diffstat (limited to 'lib')
28 files changed, 985 insertions, 2014 deletions
diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index ea369955..9f0b1169 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -34,12 +34,13 @@ use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; use Exception; use OCA\Social\AppInfo\Application; use OCA\Social\Exceptions\AccountDoesNotExistException; -use OCA\Social\Exceptions\ClientAuthDoesNotExistException; +use OCA\Social\Exceptions\ClientDoesNotExistException; use OCA\Social\Exceptions\InstanceDoesNotExistException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Stream; use OCA\Social\Model\Client\Options\TimelineOptions; +use OCA\Social\Model\Client\SocialClient; use OCA\Social\Service\AccountService; use OCA\Social\Service\CacheActorService; use OCA\Social\Service\ClientService; @@ -97,6 +98,9 @@ class ApiController extends Controller { /** @var string */ private $bearer = ''; + /** @var SocialClient */ + private $client; + /** @var Person */ private $viewer; @@ -134,7 +138,6 @@ class ApiController extends Controller { $this->miscService = $miscService; $authHeader = trim($this->request->getHeader('Authorization')); - if (strpos($authHeader, ' ')) { list($authType, $authToken) = explode(' ', $authHeader); if (strtolower($authType) === 'bearer') { @@ -150,13 +153,47 @@ class ApiController extends Controller { * * @return DataResponse */ + public function appsCredentials() { + try { + $this->initViewer(true); + + if ($this->client === null) { + return new DataResponse( + [ + 'name' => 'Nextcloud Social', + 'website' => 'https://github.com/nextcloud/social/' + ], Http::STATUS_OK + ); + } else { + return new DataResponse( + [ + 'name' => $this->client->getAppName(), + 'website' => $this->client->getAppWebsite() + ], Http::STATUS_OK + ); + } + + } catch (Exception $e) { + return $this->fail($e, [], Http::STATUS_UNAUTHORIZED); + } + + } + + + /** + * @NoCSRFRequired + * @PublicPage + * + * @return DataResponse + */ public function verifyCredentials() { try { $this->initViewer(true); return new DataResponse($this->viewer, Http::STATUS_OK); } catch (Exception $e) { - return $this->fail($e); + return $this->fail($e, [], Http::STATUS_UNAUTHORIZED); + } } @@ -184,7 +221,7 @@ class ApiController extends Controller { return new DataResponse([], Http::STATUS_OK); } catch (Exception $e) { - return $this->fail($e); + return $this->fail($e, [], Http::STATUS_UNAUTHORIZED); } } @@ -201,7 +238,7 @@ class ApiController extends Controller { return new DataResponse([], Http::STATUS_OK); } catch (Exception $e) { - return $this->fail($e); + return $this->fail($e, [], Http::STATUS_UNAUTHORIZED); } } @@ -240,7 +277,11 @@ class ApiController extends Controller { return new DataResponse($posts, Http::STATUS_OK); } catch (Exception $e) { - return $this->fail($e); + return new DataResponse( + [ + 'error' => 'The access token was revoked' + ], Http::STATUS_UNAUTHORIZED + ); } } @@ -282,6 +323,7 @@ class ApiController extends Controller { /** * @return string * @throws AccountDoesNotExistException + * @throws ClientDoesNotExistException */ private function currentSession(): string { $user = $this->userSession->getUser(); @@ -290,12 +332,9 @@ class ApiController extends Controller { } if ($this->bearer !== '') { - try { - $clientAuth = $this->clientService->getAuthFromToken($this->bearer); + $this->client = $this->clientService->getFromToken($this->bearer); - return $clientAuth->getUserId(); - } catch (ClientAuthDoesNotExistException $e) { - } + return $this->client->getAuthUserId(); } throw new AccountDoesNotExistException('userId not defined'); diff --git a/lib/Controller/OAuthController.php b/lib/Controller/OAuthController.php index 1edfd377..7a2e1d43 100644 --- a/lib/Controller/OAuthController.php +++ b/lib/Controller/OAuthController.php @@ -31,20 +31,11 @@ namespace OCA\Social\Controller; use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; -use OC\User\NoUserException; +use Exception; use OCA\Social\AppInfo\Application; -use OCA\Social\Exceptions\AccountAlreadyExistsException; -use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Exceptions\ClientAppDoesNotExistException; -use OCA\Social\Exceptions\ClientAuthDoesNotExistException; use OCA\Social\Exceptions\ClientException; use OCA\Social\Exceptions\InstanceDoesNotExistException; -use OCA\Social\Exceptions\ItemAlreadyExistsException; -use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Exceptions\UrlCloudException; -use OCA\Social\Model\Client\ClientApp; -use OCA\Social\Model\Client\ClientAuth; -use OCA\Social\Model\Client\ClientToken; +use OCA\Social\Model\Client\SocialClient; use OCA\Social\Service\AccountService; use OCA\Social\Service\CacheActorService; use OCA\Social\Service\ClientService; @@ -202,15 +193,24 @@ class OAuthController extends Controller { $redirect_uris = [$redirect_uris]; } - $clientApp = new ClientApp(); - $clientApp->setWebsite($website); - $clientApp->setRedirectUris($redirect_uris); - $clientApp->setScopesFromString($scopes); - $clientApp->setName($client_name); + $client = new SocialClient(); + $client->setAppWebsite($website); + $client->setAppRedirectUris($redirect_uris); + $client->setAppScopes($client->getScopesFromString($scopes)); + $client->setAppName($client_name); - $this->clientService->createClient($clientApp); + $this->clientService->createApp($client); - return new DataResponse($clientApp, Http::STATUS_OK); + return new DataResponse( + [ + 'id' => $client->getId(), + 'name' => $client->getAppName(), + 'website' => $client->getAppWebsite(), + 'scopes' => implode(' ', $client->getAppScopes()), + 'client_id' => $client->getAppClientId(), + 'client_secret' => $client->getAppClientSecret() + ], Http::STATUS_OK + ); } @@ -224,57 +224,52 @@ class OAuthController extends Controller { * @param string $scope * * @return DataResponse - * @throws AccountAlreadyExistsException - * @throws ActorDoesNotExistException - * @throws ClientAppDoesNotExistException - * @throws ClientException - * @throws ItemAlreadyExistsException - * @throws NoUserException - * @throws SocialAppConfigException - * @throws UrlCloudException */ public function authorize( string $client_id, string $redirect_uri, string $response_type, string $scope = 'read' ): DataResponse { - $user = $this->userSession->getUser(); - $account = $this->accountService->getActorFromUserId($user->getUID()); - - if ($response_type !== 'code') { - return new DataResponse(['error' => 'invalid_type'], Http::STATUS_BAD_REQUEST); - } - - $clientApp = $this->clientService->getClientByClientId($client_id); - $this->clientService->confirmData( - $clientApp, - [ - 'scopes' => $scope, - ] - ); - - $clientAuth = new ClientAuth(); - $clientAuth->setRedirectUri($redirect_uri); - $clientAuth->setScopes(explode(' ', $scope)); - $clientAuth->setAccount($account->getPreferredUsername()); - $clientAuth->setUserId($user->getUID()); + try { + $user = $this->userSession->getUser(); + $account = $this->accountService->getActorFromUserId($user->getUID()); - $this->clientService->authClient($clientApp, $clientAuth); - $code = $clientAuth->getCode(); + if ($response_type !== 'code') { + return new DataResponse(['error' => 'invalid_type'], Http::STATUS_BAD_REQUEST); + } - if ($redirect_uri !== 'urn:ietf:wg:oauth:2.0:oob') { - header('Location: ' . $redirect_uri . '?code=' . $code); - exit(); - } + $client = $this->clientService->getFromClientId($client_id); + $this->clientService->confirmData( + $client, + [ + 'app_scopes' => $scope, + 'redirect_uri', $redirect_uri + ] + ); + + $client->setAuthScopes($client->getScopesFromString($scope)); + $client->setAuthAccount($account->getPreferredUsername()); + $client->setAuthUserId($user->getUID()); + + $this->clientService->authClient($client); + $code = $client->getAuthCode(); + + if ($redirect_uri !== 'urn:ietf:wg:oauth:2.0:oob') { + header('Location: ' . $redirect_uri . '?code=' . $code); + exit(); + } - // TODO : finalize result if no redirect_url - return new DataResponse( - [ + // TODO : finalize result if no redirect_url + return new DataResponse( + [ // 'access_token' => '', // "token_type" => "Bearer", // "scope" => "read write follow push", // "created_at" => 1573979017 - ], Http::STATUS_OK - ); + ], Http::STATUS_OK + ); + } catch (Exception $e) { + return new DataResponse(['error' => $e->getMessage()], Http::STATUS_UNAUTHORIZED); + } } @@ -291,71 +286,54 @@ class OAuthController extends Controller { * @param string $code * * @return DataResponse - * @throws ClientAppDoesNotExistException - * @throws ClientException - * @throws ClientAuthDoesNotExistException */ public function token( string $client_id, string $client_secret, string $redirect_uri, string $grant_type, string $scope = 'read', string $code = '' ) { - $clientApp = $this->clientService->getClientByClientId($client_id); - $this->clientService->confirmData( - $clientApp, - [ - 'client_secret' => $client_secret, - 'redirect_uri' => $redirect_uri, - 'scopes' => $scope - ] - ); - - $clientToken = new ClientToken(); - $clientToken->setScopes(explode(' ', $scope)); - - if ($grant_type === 'authorization_code') { - if ($code === '') { - return new DataResponse(['error' => 'missing code'], Http::STATUS_BAD_REQUEST); + try { + $client = $this->clientService->getFromClientId($client_id); + $this->clientService->confirmData( + $client, + [ + 'client_secret' => $client_secret, + 'redirect_uri' => $redirect_uri, + 'auth_scopes' => $scope + ] + ); + + if ($grant_type === 'authorization_code') { + if ($code === '') { + return new DataResponse(['error' => 'missing code'], Http::STATUS_BAD_REQUEST); + } + + $this->clientService->confirmData($client, ['code' => $code]); + $this->clientService->generateToken($client); + } else if ($grant_type === 'client_credentials') { + // TODO: manage client_credentials + } else { + return new DataResponse( + ['error' => 'invalid value for grant_type'], Http::STATUS_BAD_REQUEST + ); } - $clientAuth = $this->clientService->getAuthByCode($code); - - $this->clientService->generateToken($clientApp, $clientAuth, $clientToken); - - } else if ($grant_type === 'client_credentials') { - // TODO: manage client_credentials - } else { - return new DataResponse(['error' => 'invalid value for grant_type'], Http::STATUS_BAD_REQUEST); - } + if ($client->getToken() === '') { + return new DataResponse( + ['error' => 'issue generating access_token'], Http::STATUS_BAD_REQUEST + ); + } - if ($clientToken->getToken() === '') { - return new DataResponse(['error' => 'issue generating access_token'], Http::STATUS_BAD_REQUEST); + return new DataResponse( + [ + "access_token" => $client->getToken(), + "token_type" => 'Bearer', + "scope" => $scope, + "created_at" => $client->getCreation() + ], Http::STATUS_OK + ); + } catch (Exception $e) { + return new DataResponse(['error' => $e->getMessage()], Http::STATUS_UNAUTHORIZED); } - - return new DataResponse( - [ - "access_token" => $clientToken->getToken(), - "token_type" => 'Bearer', - "scope" => $scope, - "created_at" => $clientToken->getCreation() - ], 200 - ); - } - - - /** - * @NoCSRFRequired - * @NoAdminRequired - * @PublicPage - * - * @return DataResponse - */ - public function appsCredentials() { - return new DataResponse( - [ - 'name' => 'Twidere for Android', - 'website' => 'https://github.com/TwidereProject/' - ], 200 - ); } } diff --git a/lib/Db/ClientAppRequest.php b/lib/Db/ClientAppRequest.php deleted file mode 100644 index 8a7eb375..00000000 --- a/lib/Db/ClientAppRequest.php +++ /dev/null @@ -1,110 +0,0 @@ -<?php -declare(strict_types=1); - - -/** - * Nextcloud - Social Support - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> - * @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 <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Social\Db; - - -use daita\MySmallPhpTools\Traits\TArrayTools; -use DateTime; -use Exception; -use OCA\Social\Exceptions\ClientAppDoesNotExistException; -use OCA\Social\Model\Client\ClientApp; -use OCP\DB\QueryBuilder\IQueryBuilder; - - -/** - * Class ClientAppRequest - * - * @package OCA\Social\Db - */ -class ClientAppRequest extends ClientAppRequestBuilder { - - - use TArrayTools; - - - /** - * Insert a new OAuth client in the database. - * - * @param ClientApp $clientApp - */ - public function save(ClientApp $clientApp) { - $qb = $this->getClientAppInsertSql(); - $qb->setValue('name', $qb->createNamedParameter($clientApp->getName())) - ->setValue('website', $qb->createNamedParameter($clientApp->getWebsite())) - ->setValue('redirect_uris', $qb->createNamedParameter(json_encode($clientApp->getRedirectUris()))) - ->setValue('client_id', $qb->createNamedParameter($clientApp->getClientId())) - ->setValue('client_secret', $qb->createNamedParameter($clientApp->getClientSecret())) - ->setValue('scopes', $qb->createNamedParameter(json_encode($clientApp->getScopes()))); - - try { - $qb->setValue( - 'creation', - $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) - ); - } catch (Exception $e) { - } - - $qb->execute(); - - $clientApp->setId($qb->getLastInsertId()); - } - - - /** - * @param string $clientId - * @param string $account - */ - public function assignAccount(string $clientId, string $account): void { - $qb = $this->getClientAppUpdateSql(); - $qb->set('account', $qb->createNamedParameter($account)); - - $qb->limitToClientId($clientId); - $qb->limitToAccount(''); - - $qb->execute(); - } - - - /** - * @param string $clientId - * - * @return ClientApp - * @throws ClientAppDoesNotExistException - */ - public function getByClientId(string $clientId): ClientApp { - $qb = $this->getClientAppSelectSql(); - $qb->limitToClientId($clientId); - - return $this->getClientAppFromRequest($qb); - } - -} - diff --git a/lib/Db/ClientAuthRequest.php b/lib/Db/ClientAuthRequest.php deleted file mode 100644 index cba766c4..00000000 --- a/lib/Db/ClientAuthRequest.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php -declare(strict_types=1); - - -/** - * Nextcloud - Social Support - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> - * @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 <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Social\Db; - - -use daita\MySmallPhpTools\Traits\TArrayTools; -use DateTime; -use OCA\Social\Exceptions\ClientAuthDoesNotExistException; -use OCA\Social\Model\ActivityStream\ClientApp; -use OCA\Social\Model\Client\ClientAuth; -use OCP\DB\QueryBuilder\IQueryBuilder; - - -/** - * Class ClientAuthRequest - * - * @package OCA\Social\Db - */ -class ClientAuthRequest extends ClientAuthRequestBuilder { - - - use TArrayTools; - - - /** - * @param ClientAuth $clientAuth - */ - public function save(ClientAuth $clientAuth) { - $qb = $this->getClientAuthInsertSql(); - - $now = new DateTime('now'); - $qb->setValue('client_id', $qb->createNamedParameter($clientAuth->getClientId())) - ->setValue('account', $qb->createNamedParameter($clientAuth->getAccount())) - ->setValue('code', $qb->createNamedParameter($clientAuth->getCode())) - ->setValue('user_id', $qb->createNamedParameter($clientAuth->getUserId())) - ->setValue('last_update', $qb->createNamedParameter($now, IQueryBuilder::PARAM_DATE)) - ->setValue('creation', $qb->createNamedParameter($now, IQueryBuilder::PARAM_DATE)); - - $qb->execute(); - } - - - /** - * @param string $code - * - * @return ClientAuth - * @throws ClientAuthDoesNotExistException - */ - public function getByCode(string $code): ClientAuth { - $qb = $this->getClientAuthSelectSql(); - $qb->limitToDBField('code', $code); - - return $this->getClientAuthFromRequest($qb); - } - - - /** - * @param string $token - * - * @return ClientAuth - * @throws ClientAuthDoesNotExistException - */ - public function getByToken(string $token): ClientAuth { - $qb = $this->getClientAuthSelectSql(); - $qb->leftJoinClientToken('clt'); - $qb->limitToToken($token, 'clt'); - - return $this->getClientAuthFromRequest($qb); - } - -} - diff --git a/lib/Db/ClientAuthRequestBuilder.php b/lib/Db/ClientAuthRequestBuilder.php deleted file mode 100644 index 02f20167..00000000 --- a/lib/Db/ClientAuthRequestBuilder.php +++ /dev/null @@ -1,162 +0,0 @@ -<?php -declare(strict_types=1); - - -/** - * Nextcloud - Social Support - * - * This file is licensed under the Affero General Public License version 3 or - * later. See the COPYING file. - * - * @author Maxence Lange <maxence@artificial-owl.com> - * @copyright 2018, Maxence Lange <maxence@artificial-owl.com> - * @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 <http://www.gnu.org/licenses/>. - * - */ - - -namespace OCA\Social\Db; - - -use daita\MySmallPhpTools\Exceptions\RowNotFoundException; -use daita\MySmallPhpTools\Traits\TArrayTools; -use OCA\Social\Exceptions\ClientAuthDoesNotExistException; -use OCA\Social\Exceptions\InvalidResourceException; -use OCA\Social\Model\ActivityStream\ClientApp; -use OCA\Social\Model\Client\ClientAuth; - - -/** - * Class ClientAppRequestBuilder - * - * @package OCA\Social\Db - */ -class ClientAuthRequestBuilder extends CoreRequestBuilder { - - - use TArrayTools; - - - /** - * Base of the Sql Insert request - * - * @return SocialQueryBuilder - */ - protected function getClientAuthInsertSql(): SocialQueryBuilder { - $qb = $this->getQueryBuilder(); - $qb->insert(self::TABLE_CLIENT_AUTH); - - return $qb; - } - - - /** - * Base of the Sql Update request - * - * @return SocialQueryBuilder - */ - protected function getClientAuthUpdateSql(): SocialQueryBuilder { - $qb = $this->getQueryBuilder(); - $qb->update(self::TABLE_CLIENT_AUTH); - - return $qb; - } - - - /** - * Base of the Sql Select request for Shares - * - * @return SocialQueryBuilder - */ - protected function getClientAuthSelectSql(): SocialQueryBuilder { - $qb = $this->getQueryBuilder(); - - /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->select('cla.id', 'cla.client_id', 'cla.account', 'cla.user_id', 'cla.code') - ->from(self::TABLE_CLIENT_AUTH, 'cla'); - - $this->defaultSelectAlias = 'cla'; - $qb->setDefaultSelectAlias('cla'); - - return $qb; - } - - - /** - * Base of the Sql Delete request - * - * @return SocialQueryBuilder - */ - protected function getClientAuthDeleteSql(): SocialQueryBuilder { - $qb = $this->getQueryBuilder(); - $qb->delete(self::TABLE_CLIENT_AUTH); - - return $qb; - } - - - /** - * @param SocialQueryBuilder $qb - * - * @return ClientAuth - * @throws ClientAuthDoesNotExistException - */ - public function getClientAuthFromRequest(SocialQueryBuilder $qb): ClientAuth { - /** @var ClientAuth $result */ - try { - $result = $qb->getRow([$this, 'parseClientAuthSelectSql']); - } catch (RowNotFoundException $e) { - throw new ClientAuthDoesNotExistException($e->getMessage()); - } - - return $result; - } - - - /** - * @param SocialQueryBuilder $qb - * - * @return ClientAuth[] - */ - public function getClientAuthsFromRequest(SocialQueryBuilder $qb): array { - /** @var ClientAuth[] $result */ - $result = $qb->getRows([$this, 'parseClientAuthSelectSql']); - - return $result; - } - - - /** - * @param array $data - * - * @param SocialQueryBuilder $qb - * - * @return ClientAuth - */ - public function parseClientAuthSelectSql($data, SocialQueryBuilder $qb): ClientAuth {< |