diff options
Diffstat (limited to 'apps/oauth2/lib/Migration')
7 files changed, 391 insertions, 0 deletions
diff --git a/apps/oauth2/lib/Migration/SetTokenExpiration.php b/apps/oauth2/lib/Migration/SetTokenExpiration.php new file mode 100644 index 00000000000..dc925e26bb2 --- /dev/null +++ b/apps/oauth2/lib/Migration/SetTokenExpiration.php @@ -0,0 +1,51 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use OC\Authentication\Token\IProvider as TokenProvider; +use OCA\OAuth2\Db\AccessToken; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\Authentication\Exceptions\InvalidTokenException; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; + +class SetTokenExpiration implements IRepairStep { + + public function __construct( + private IDBConnection $connection, + private ITimeFactory $time, + private TokenProvider $tokenProvider, + ) { + } + + public function getName(): string { + return 'Update OAuth token expiration times'; + } + + public function run(IOutput $output) { + $qb = $this->connection->getQueryBuilder(); + $qb->select('*') + ->from('oauth2_access_tokens'); + + $cursor = $qb->executeQuery(); + + while ($row = $cursor->fetch()) { + $token = AccessToken::fromRow($row); + try { + $appToken = $this->tokenProvider->getTokenById($token->getTokenId()); + $appToken->setExpires($this->time->getTime() + 3600); + $this->tokenProvider->updateToken($appToken); + } catch (InvalidTokenException $e) { + //Skip this token + } + } + $cursor->closeCursor(); + } +} diff --git a/apps/oauth2/lib/Migration/Version010401Date20181207190718.php b/apps/oauth2/lib/Migration/Version010401Date20181207190718.php new file mode 100644 index 00000000000..8648826d53c --- /dev/null +++ b/apps/oauth2/lib/Migration/Version010401Date20181207190718.php @@ -0,0 +1,82 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +class Version010401Date20181207190718 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if (!$schema->hasTable('oauth2_clients')) { + $table = $schema->createTable('oauth2_clients'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'unsigned' => true, + ]); + $table->addColumn('name', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('redirect_uri', 'string', [ + 'notnull' => true, + 'length' => 2000, + ]); + $table->addColumn('client_identifier', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->addColumn('secret', 'string', [ + 'notnull' => true, + 'length' => 64, + ]); + $table->setPrimaryKey(['id']); + $table->addIndex(['client_identifier'], 'oauth2_client_id_idx'); + } + + if (!$schema->hasTable('oauth2_access_tokens')) { + $table = $schema->createTable('oauth2_access_tokens'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'unsigned' => true, + ]); + $table->addColumn('token_id', 'integer', [ + 'notnull' => true, + ]); + $table->addColumn('client_id', 'integer', [ + 'notnull' => true, + ]); + $table->addColumn('hashed_code', 'string', [ + 'notnull' => true, + 'length' => 128, + ]); + $table->addColumn('encrypted_token', 'string', [ + 'notnull' => true, + 'length' => 786, + ]); + $table->setPrimaryKey(['id']); + $table->addUniqueIndex(['hashed_code'], 'oauth2_access_hash_idx'); + $table->addIndex(['client_id'], 'oauth2_access_client_id_idx'); + } + return $schema; + } +} diff --git a/apps/oauth2/lib/Migration/Version010402Date20190107124745.php b/apps/oauth2/lib/Migration/Version010402Date20190107124745.php new file mode 100644 index 00000000000..08099c625f7 --- /dev/null +++ b/apps/oauth2/lib/Migration/Version010402Date20190107124745.php @@ -0,0 +1,36 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +class Version010402Date20190107124745 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + // During an ownCloud migration, the client_identifier column identifier might not exist yet. + if ($schema->getTable('oauth2_clients')->hasColumn('client_identifier')) { + $table = $schema->getTable('oauth2_clients'); + $table->dropIndex('oauth2_client_id_idx'); + $table->addUniqueIndex(['client_identifier'], 'oauth2_client_id_idx'); + return $schema; + } + } +} diff --git a/apps/oauth2/lib/Migration/Version011601Date20230522143227.php b/apps/oauth2/lib/Migration/Version011601Date20230522143227.php new file mode 100644 index 00000000000..f2998202e02 --- /dev/null +++ b/apps/oauth2/lib/Migration/Version011601Date20230522143227.php @@ -0,0 +1,65 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; +use OCP\Security\ICrypto; + +class Version011601Date20230522143227 extends SimpleMigrationStep { + + public function __construct( + private IDBConnection $connection, + private ICrypto $crypto, + ) { + } + + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('oauth2_clients')) { + $table = $schema->getTable('oauth2_clients'); + if ($table->hasColumn('secret')) { + $column = $table->getColumn('secret'); + $column->setLength(512); + return $schema; + } + } + + return null; + } + + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { + $qbUpdate = $this->connection->getQueryBuilder(); + $qbUpdate->update('oauth2_clients') + ->set('secret', $qbUpdate->createParameter('updateSecret')) + ->where( + $qbUpdate->expr()->eq('id', $qbUpdate->createParameter('updateId')) + ); + + $qbSelect = $this->connection->getQueryBuilder(); + $qbSelect->select('id', 'secret') + ->from('oauth2_clients'); + $req = $qbSelect->executeQuery(); + while ($row = $req->fetch()) { + $id = $row['id']; + $secret = $row['secret']; + $encryptedSecret = $this->crypto->encrypt($secret); + $qbUpdate->setParameter('updateSecret', $encryptedSecret, IQueryBuilder::PARAM_STR); + $qbUpdate->setParameter('updateId', $id, IQueryBuilder::PARAM_INT); + $qbUpdate->executeStatement(); + } + $req->closeCursor(); + } +} diff --git a/apps/oauth2/lib/Migration/Version011602Date20230613160650.php b/apps/oauth2/lib/Migration/Version011602Date20230613160650.php new file mode 100644 index 00000000000..06efce324b2 --- /dev/null +++ b/apps/oauth2/lib/Migration/Version011602Date20230613160650.php @@ -0,0 +1,39 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +class Version011602Date20230613160650 extends SimpleMigrationStep { + + public function __construct( + ) { + } + + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('oauth2_clients')) { + $table = $schema->getTable('oauth2_clients'); + if ($table->hasColumn('secret')) { + $column = $table->getColumn('secret'); + // we still change the column length in case Version011601Date20230522143227 + // has run before it was changed to set the length to 512 + $column->setLength(512); + return $schema; + } + } + + return null; + } +} diff --git a/apps/oauth2/lib/Migration/Version011603Date20230620111039.php b/apps/oauth2/lib/Migration/Version011603Date20230620111039.php new file mode 100644 index 00000000000..853eacd2873 --- /dev/null +++ b/apps/oauth2/lib/Migration/Version011603Date20230620111039.php @@ -0,0 +1,69 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use Closure; +use OCP\DB\ISchemaWrapper; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\DB\Types; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; + +class Version011603Date20230620111039 extends SimpleMigrationStep { + + public function __construct( + private IDBConnection $connection, + ) { + } + + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('oauth2_access_tokens')) { + $table = $schema->getTable('oauth2_access_tokens'); + $dbChanged = false; + if (!$table->hasColumn('code_created_at')) { + $table->addColumn('code_created_at', Types::BIGINT, [ + 'notnull' => true, + 'default' => 0, + 'unsigned' => true, + ]); + $dbChanged = true; + } + if (!$table->hasColumn('token_count')) { + $table->addColumn('token_count', Types::BIGINT, [ + 'notnull' => true, + 'default' => 0, + 'unsigned' => true, + ]); + $dbChanged = true; + } + if (!$table->hasIndex('oauth2_tk_c_created_idx')) { + $table->addIndex(['token_count', 'code_created_at'], 'oauth2_tk_c_created_idx'); + $dbChanged = true; + } + if ($dbChanged) { + return $schema; + } + } + + return null; + } + + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + // we consider that existing access_tokens have already produced at least one oauth token + // which prevents cleaning them up + $qbUpdate = $this->connection->getQueryBuilder(); + $qbUpdate->update('oauth2_access_tokens') + ->set('token_count', $qbUpdate->createNamedParameter(1, IQueryBuilder::PARAM_INT)); + $qbUpdate->executeStatement(); + } +} diff --git a/apps/oauth2/lib/Migration/Version011901Date20240829164356.php b/apps/oauth2/lib/Migration/Version011901Date20240829164356.php new file mode 100644 index 00000000000..20f5754bf11 --- /dev/null +++ b/apps/oauth2/lib/Migration/Version011901Date20240829164356.php @@ -0,0 +1,49 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +namespace OCA\OAuth2\Migration; + +use Closure; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; +use OCP\Security\ICrypto; + +class Version011901Date20240829164356 extends SimpleMigrationStep { + + public function __construct( + private IDBConnection $connection, + private ICrypto $crypto, + ) { + } + + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + $qbUpdate = $this->connection->getQueryBuilder(); + $qbUpdate->update('oauth2_clients') + ->set('secret', $qbUpdate->createParameter('updateSecret')) + ->where( + $qbUpdate->expr()->eq('id', $qbUpdate->createParameter('updateId')) + ); + + $qbSelect = $this->connection->getQueryBuilder(); + $qbSelect->select('id', 'secret') + ->from('oauth2_clients'); + $req = $qbSelect->executeQuery(); + while ($row = $req->fetch()) { + $id = $row['id']; + $storedEncryptedSecret = $row['secret']; + $secret = $this->crypto->decrypt($storedEncryptedSecret); + $hashedSecret = bin2hex($this->crypto->calculateHMAC($secret)); + $qbUpdate->setParameter('updateSecret', $hashedSecret, IQueryBuilder::PARAM_STR); + $qbUpdate->setParameter('updateId', $id, IQueryBuilder::PARAM_INT); + $qbUpdate->executeStatement(); + } + $req->closeCursor(); + } +} |