diff --git a/appinfo/info.xml b/appinfo/info.xml
index 1a73cd6b..da4c1683 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -50,12 +50,6 @@ For a demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
OCA\PassmanNext\BackgroundJob\ExpireCredentials
-
-
- OCA\PassmanNext\Migration\ServerSideEncryption
-
-
-
Passwords
@@ -64,6 +58,10 @@ For a demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
+
+ OCA\PassmanNext\Command\PassmanLegacyMigrateCommand
+
+
OCA\PassmanNext\Settings\Admin
OCA\PassmanNext\Settings\AdminSection
diff --git a/lib/Command/AbstractInteractiveCommand.php b/lib/Command/AbstractInteractiveCommand.php
new file mode 100644
index 00000000..c8ed19b7
--- /dev/null
+++ b/lib/Command/AbstractInteractiveCommand.php
@@ -0,0 +1,96 @@
+.
+ *
+ */
+
+namespace OCA\PassmanNext\Command;
+
+use OCA\PassmanNext\Exception\NonInteractiveShellException;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\QuestionHelper;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\Question;
+
+/**
+ * Class AbstractInteractiveCommand
+ *
+ * @package OCA\Passwords\Command
+ */
+abstract class AbstractInteractiveCommand extends Command
+{
+
+ /**
+ * AbstractInteractiveCommand constructor.
+ *
+ * @param string|null $name
+ */
+ public function __construct(?string $name = null) {
+ parent::__construct($name);
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ *
+ * @return int
+ * @throws NonInteractiveShellException
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ if (!$input->isInteractive() && !$input->getOption('no-interaction')) {
+ throw new NonInteractiveShellException();
+ } elseif (!$input->isInteractive()) {
+ $output->writeln('"--no-interaction" is set, will assume yes for all questions.');
+ $output->writeln('');
+ }
+
+ return 0;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @param string $description
+ *
+ * @return bool
+ */
+ protected function requestConfirmation(InputInterface $input, OutputInterface $output, string $description): bool {
+ $output->writeln("❗❗❗ {$description} ❗❗❗");
+ if (!$input->isInteractive()) {
+ $output->writeln('');
+ return true;
+ }
+
+ /** @var QuestionHelper $helper */
+ $helper = $this->getHelper('question');
+ $question = new Question('Type "yes" to confirm this: ');
+ $yes = $helper->ask($input, $output, $question);
+ $output->writeln('');
+
+ if ($yes !== 'yes') {
+ $output->writeln('aborting');
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/lib/Command/PassmanLegacyMigrateCommand.php b/lib/Command/PassmanLegacyMigrateCommand.php
new file mode 100644
index 00000000..822af18d
--- /dev/null
+++ b/lib/Command/PassmanLegacyMigrateCommand.php
@@ -0,0 +1,223 @@
+.
+ *
+ */
+
+namespace OCA\PassmanNext\Command;
+
+use OCA\PassmanNext\Exception\NonInteractiveShellException;
+use OCP\DB\Exception;
+use OCP\IAppConfig;
+use OCP\IDBConnection;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class PassmanLegacyMigrateCommand extends AbstractInteractiveCommand
+{
+ const OLD_TABLE_PREFIX = 'passman_';
+ const NEW_TABLE_PREFIX = 'passman_next_';
+ const MIGRATE_TABLE_NAMES = [
+ 'vaults',
+ 'credentials',
+ 'files',
+ 'revisions',
+ 'sharing_acl',
+ 'share_request',
+ 'delete_vault_request'
+ ];
+ const CHECK_ICON = "✅";
+ const PROBLEM_ICON = "❗";
+ const MINIMUM_PASSMAN_LEGACY_VERSION = "2.4.0";
+
+ /**
+ * PassmanLegacyMigrateCommand constructor.
+ *
+ * @param IDBConnection $db
+ * @param IAppConfig $config
+ * @param string|null $name
+ */
+ public function __construct(
+ private readonly IDBConnection $db,
+ private readonly IAppConfig $config,
+ ?string $name = null
+ ) {
+ parent::__construct($name);
+ }
+
+
+ protected function configure(): void {
+ $this->setName('passman-next:migrate-legacy')
+ ->setDescription('Migrates all data from the Passman (legacy) app into the Passman Next database tables');
+ parent::configure();
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ *
+ * @return int
+ * @throws NonInteractiveShellException|Exception
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ parent::execute($input, $output);
+
+ $installedPassmanVersion = $this->config->getValueString('passman', 'installed_version');
+ $passmanLegacyVersionSupported = false;
+ if (version_compare($installedPassmanVersion, self::MINIMUM_PASSMAN_LEGACY_VERSION, '>=')) {
+ $passmanLegacyVersionSupported = true;
+ }
+ $output->writeln(sprintf(
+ "Found legacy Passman %s installation %s",
+ $installedPassmanVersion,
+ $passmanLegacyVersionSupported ? self::CHECK_ICON : self::PROBLEM_ICON
+ ));
+ if (!$passmanLegacyVersionSupported) {
+ $output->writeln('Supported Passman versions: >= ' . self::MINIMUM_PASSMAN_LEGACY_VERSION);
+ return 1;
+ }
+
+ $oldTableEntriesCountMap = [];
+ $newDataTableEntries = 0;
+
+ $output->writeln("\nData to migrate:");
+ foreach (self::MIGRATE_TABLE_NAMES as $mainTableName) {
+ $oldTableEntriesCount = $this->countAll(self::OLD_TABLE_PREFIX . $mainTableName);
+ $newTableEntriesCount = $this->countAll(self::NEW_TABLE_PREFIX . $mainTableName);
+
+ $output->writeln(
+ sprintf(
+ "- %s: \n - Legacy: %d \n - Passman Next: %d %s",
+ $mainTableName,
+ $oldTableEntriesCount,
+ $newTableEntriesCount,
+ $newTableEntriesCount === 0 ? self::CHECK_ICON : self::PROBLEM_ICON
+ )
+ );
+
+ $newDataTableEntries += $newTableEntriesCount;
+ $oldTableEntriesCountMap[$mainTableName] = $oldTableEntriesCount;
+ }
+
+ if ($newDataTableEntries !== 0) {
+ $output->writeln(
+ "\n❗❗❗ You have already data in the Passman Next database tables. These will be deleted if you proceed! ❗❗❗\n"
+ );
+ }
+
+ if ($this->confirmMigration($input, $output)) {
+ try {
+ $this->db->beginTransaction();
+
+ foreach (self::MIGRATE_TABLE_NAMES as $mainTableName) {
+ $this->migrateTableData(
+ self::OLD_TABLE_PREFIX . $mainTableName,
+ self::NEW_TABLE_PREFIX . $mainTableName
+ );
+
+ $newCount = $this->countAll(self::NEW_TABLE_PREFIX . $mainTableName);
+ if ($oldTableEntriesCountMap[$mainTableName] !== $newCount) {
+ // new table entries count does not match the original ones
+ $output->writeln(
+ sprintf(
+ 'New table entries count in "%s" (%d) does not match the original ones (%d)',
+ self::NEW_TABLE_PREFIX . $mainTableName,
+ $newCount,
+ $oldTableEntriesCountMap[$mainTableName]
+ )
+ );
+ }
+ }
+
+ $this->db->commit();
+ } catch (\Exception $exception) {
+ $output->writeln($exception->getMessage());
+ $output->writeln("\nRoll back transaction ...");
+ $this->db->rollBack();
+ $output->writeln("No data has been changed.");
+ return 1;
+ }
+
+ $output->writeln('Done');
+ return 0;
+ }
+
+ return 1;
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return bool
+ */
+ protected function confirmMigration(InputInterface $input, OutputInterface $output): bool {
+ return $this->requestConfirmation(
+ $input,
+ $output,
+ 'Please confirm the data migration. It won\'t delete anything in the sources.'
+ );
+ }
+
+ /**
+ * KEEP THIS METHOD PRIVATE!!!
+ *
+ * @param string $table
+ * @return array
+ * @throws Exception
+ */
+ private function fetchAll(string $table): array {
+ $qb = $this->db->getQueryBuilder();
+ $result = $qb->select('*')
+ ->from($table)
+ ->executeQuery();
+ return $result->fetchAll();
+ }
+
+ private function countAll(string $table, string $uniqueColumn = 'id'): int {
+ $qb = $this->db->getQueryBuilder();
+ $result = $qb->select($uniqueColumn)
+ ->from($table)
+ ->executeQuery();
+ return $result->rowCount();
+ }
+
+ private function migrateTableData(string $legacyTableName, string $newTableName) {
+ // ensure the destination table is cleared
+ $deleteQueryBuilder = $this->db->getQueryBuilder();
+ $deleteQueryBuilder->delete($newTableName)->executeStatement();
+
+ $data = $this->fetchAll($legacyTableName);
+ foreach ($data as $datum) {
+ $qb = $this->db->getQueryBuilder();
+ $qb->insert($newTableName);
+
+ foreach ($datum as $key => $value) {
+ if (is_null($value)) {
+ $value = 'NULL';
+ } elseif (!is_numeric($value)) {
+ $value = "'{$value}'";
+ }
+
+ $qb->setValue($key, $value);
+ }
+
+ $qb->executeStatement();
+ }
+ }
+}
diff --git a/lib/Db/CredentialMapper.php b/lib/Db/CredentialMapper.php
index 075619cf..2b459616 100644
--- a/lib/Db/CredentialMapper.php
+++ b/lib/Db/CredentialMapper.php
@@ -35,7 +35,7 @@
* @template-extends QBMapper
*/
class CredentialMapper extends QBMapper {
- const TABLE_NAME = 'passman_credentials';
+ const TABLE_NAME = 'passman_next_credentials';
public function __construct(
IDBConnection $db,
diff --git a/lib/Db/CredentialRevisionMapper.php b/lib/Db/CredentialRevisionMapper.php
index 7b2797ef..a69dcdcd 100644
--- a/lib/Db/CredentialRevisionMapper.php
+++ b/lib/Db/CredentialRevisionMapper.php
@@ -34,7 +34,7 @@
* @template-extends QBMapper
*/
class CredentialRevisionMapper extends QBMapper {
- const TABLE_NAME = 'passman_revisions';
+ const TABLE_NAME = 'passman_next_revisions';
public function __construct(IDBConnection $db, private readonly Utils $utils) {
parent::__construct($db, self::TABLE_NAME);
diff --git a/lib/Db/DeleteVaultRequestMapper.php b/lib/Db/DeleteVaultRequestMapper.php
index efb7c542..c59949b7 100644
--- a/lib/Db/DeleteVaultRequestMapper.php
+++ b/lib/Db/DeleteVaultRequestMapper.php
@@ -34,7 +34,7 @@
* @template-extends QBMapper
*/
class DeleteVaultRequestMapper extends QBMapper {
- const TABLE_NAME = 'passman_delete_vault_request';
+ const TABLE_NAME = 'passman_next_delete_vault_request';
public function __construct(IDBConnection $db) {
parent::__construct($db, self::TABLE_NAME);
diff --git a/lib/Db/FileMapper.php b/lib/Db/FileMapper.php
index 486c6b01..b525983b 100644
--- a/lib/Db/FileMapper.php
+++ b/lib/Db/FileMapper.php
@@ -35,7 +35,7 @@
* @template-extends QBMapper
*/
class FileMapper extends QBMapper {
- const TABLE_NAME = 'passman_files';
+ const TABLE_NAME = 'passman_next_files';
public function __construct(
IDBConnection $db,
diff --git a/lib/Db/ShareRequestMapper.php b/lib/Db/ShareRequestMapper.php
index 72c6b144..04956fb4 100644
--- a/lib/Db/ShareRequestMapper.php
+++ b/lib/Db/ShareRequestMapper.php
@@ -35,7 +35,7 @@
* @template-extends QBMapper
*/
class ShareRequestMapper extends QBMapper {
- const TABLE_NAME = 'passman_share_request';
+ const TABLE_NAME = 'passman_next_share_request';
public function __construct(IDBConnection $db) {
parent::__construct($db, self::TABLE_NAME);
diff --git a/lib/Db/SharingACLMapper.php b/lib/Db/SharingACLMapper.php
index 9f30410c..b4417d34 100644
--- a/lib/Db/SharingACLMapper.php
+++ b/lib/Db/SharingACLMapper.php
@@ -34,10 +34,10 @@
* @template-extends QBMapper
*/
class SharingACLMapper extends QBMapper {
- const TABLE_NAME = 'passman_sharing_acl';
+ const TABLE_NAME = 'passman_next_sharing_acl';
public function __construct(IDBConnection $db) {
- parent::__construct($db, 'passman_sharing_acl');
+ parent::__construct($db, self::TABLE_NAME);
}
/**
diff --git a/lib/Db/VaultMapper.php b/lib/Db/VaultMapper.php
index 21d5ca5c..e7f1d95b 100644
--- a/lib/Db/VaultMapper.php
+++ b/lib/Db/VaultMapper.php
@@ -34,7 +34,7 @@
* @template-extends QBMapper
*/
class VaultMapper extends QBMapper {
- const TABLE_NAME = 'passman_vaults';
+ const TABLE_NAME = 'passman_next_vaults';
public function __construct(
IDBConnection $db,
diff --git a/lib/Exception/NonInteractiveShellException.php b/lib/Exception/NonInteractiveShellException.php
new file mode 100644
index 00000000..551661d6
--- /dev/null
+++ b/lib/Exception/NonInteractiveShellException.php
@@ -0,0 +1,8 @@
+.
- *
- */
-
-namespace OCA\PassmanNext\Migration;
-
-use OCA\PassmanNext\Db\CredentialRevision;
-use OCA\PassmanNext\Db\File;
-use OCA\PassmanNext\Service\CredentialRevisionService;
-use OCA\PassmanNext\Service\CredentialService;
-use OCA\PassmanNext\Service\EncryptService;
-use OCA\PassmanNext\Service\FileService;
-use OCP\DB\Exception;
-use OCP\IConfig;
-use OCP\IDBConnection;
-use OCP\Migration\IOutput;
-use OCP\Migration\IRepairStep;
-use Psr\Log\LoggerInterface;
-
-
-class ServerSideEncryption implements IRepairStep {
-
- /** @var string */
- private $installedVersion;
-
- public function __construct(
- private readonly EncryptService $encryptService,
- private readonly IDBConnection $db,
- private readonly LoggerInterface $logger,
- private readonly CredentialService $credentialService,
- private readonly CredentialRevisionService $revisionService,
- private readonly FileService $fileService,
- IConfig $config,
- ) {
- $this->installedVersion = $config->getAppValue('passman', 'installed_version');
- }
-
- public function getName() {
- return 'Enabling server side encryption for passman';
- }
-
- public function run(IOutput $output) {
- $output->info('Enabling Service Side Encryption for passman');
-
- if (version_compare($this->installedVersion, '2.0.0RC4', '<')) {
- $this->encryptCredentials();
- $this->encryptRevisions();
- $this->encryptFiles();
- }
- }
-
- /**
- * KEEP THIS METHOD PRIVATE!!!
- *
- * @param string $table
- * @return mixed[]
- * @throws Exception
- */
- private function fetchAll(string $table): array {
- $qb = $this->db->getQueryBuilder();
- $result = $qb->select('*')
- ->from($table)
- ->executeQuery();
- return $result->fetchAll();
- }
-
- private function encryptCredentials(): void {
- $credentials = $this->fetchAll('passman_credentials');
- foreach ($credentials as $credential) {
- $this->credentialService->updateCredential($credential);
- }
- }
-
- private function encryptRevisions(): void {
- $revisions = $this->fetchAll('passman_revisions');
- foreach ($revisions as $_revision) {
- $revision = new CredentialRevision();
- $revision->setId($_revision['id']);
- $revision->setGuid($_revision['guid']);
- $revision->setCredentialId($_revision['credential_id']);
- $revision->setUserId($_revision['user_id']);
- $revision->setCreated($_revision['created']);
- $revision->setEditedBy($_revision['edited_by']);
- $revision->setCredentialData($_revision['credential_data']);
- $this->revisionService->updateRevision($revision);
- }
- }
-
- private function encryptFiles() {
- $files = $this->fetchAll('passman_files');
- foreach ($files as $_file) {
- $file = new File();
- $file->setId($_file['id']);
- $file->setGuid($_file['guid']);
- $file->setUserId($_file['user_id']);
- $file->setMimetype($_file['minetype']);
- $file->setFilename($_file['filename']);
- $file->setSize($_file['size']);
- $file->setCreated($_file['created']);
- $file->setFileData($_file['file_data']);
- $this->fileService->updateFile($file);
- }
- }
-}
diff --git a/lib/Migration/Version02031334Date20210926234011.php b/lib/Migration/Version02031334Date20210926234011.php
deleted file mode 100644
index eaa2e86a..00000000
--- a/lib/Migration/Version02031334Date20210926234011.php
+++ /dev/null
@@ -1,60 +0,0 @@
-hasTable('passman_credentials')) {
- $table = $schema->getTable('passman_credentials');
- if ($table->hasIndex('passman_credential_label_index')) {
- $table->dropIndex('passman_credential_label_index');
- }
- $labelColumn = $table->getColumn('label');
- if ($labelColumn->getLength() < 2048 || $labelColumn->getType() !== Type::getType('string')) {
- $table->changeColumn('label', [
- 'type' => Type::getType('string'),
- 'length' => 2048
- ]);
- }
- }
-
- return $schema;
- }
-
- /**
- * @param IOutput $output
- * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
- * @param array $options
- */
- public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
- }
-}
diff --git a/lib/Migration/Version02031335Date20211001122343.php b/lib/Migration/Version02031335Date20211001122343.php
deleted file mode 100644
index 9cab6ba8..00000000
--- a/lib/Migration/Version02031335Date20211001122343.php
+++ /dev/null
@@ -1,87 +0,0 @@
-hasTable('passman_credentials')) {
- $table = $schema->getTable('passman_credentials');
- if ($table->hasColumn($this->oldColumn) && !$table->hasColumn($this->newColumn)) {
- $table->addColumn($this->newColumn, 'text', [
- 'notnull' => false,
- ]);
- $this->dataMigrationRequired = true;
- }
- }
-
- return $schema;
- }
-
- /**
- * @param IOutput $output
- * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
- * @param array $options
- */
- public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
- if ($this->dataMigrationRequired) {
- $updateQuery = $this->connection->getQueryBuilder();
- $updateQuery->update('passman_credentials')
- ->set($this->newColumn, $this->oldColumn)
- ->where($this->newColumn . ' IS NULL')
- ->andWhere($this->oldColumn . ' IS NOT NULL')
- ->executeStatement();
-
- /** @var ISchemaWrapper $schema */
- $schema = $schemaClosure();
-
- if ($schema->hasTable('passman_credentials')) {
- $table = $schema->getTable('passman_credentials');
- if ($table->hasColumn($this->oldColumn) && $table->hasColumn($this->newColumn)) {
- $dropColumnStatement = $this->connection->prepare('ALTER TABLE ' . $table->getName() . ' DROP COLUMN ' . $this->oldColumn . ';');
- $dropColumnStatement->execute();
- }
- }
- }
- }
-}
diff --git a/lib/Migration/Version020308Date20210711121919.php b/lib/Migration/VersionNext030000Date20260110234900.php
similarity index 64%
rename from lib/Migration/Version020308Date20210711121919.php
rename to lib/Migration/VersionNext030000Date20260110234900.php
index e785f250..342655f8 100644
--- a/lib/Migration/Version020308Date20210711121919.php
+++ b/lib/Migration/VersionNext030000Date20260110234900.php
@@ -6,67 +6,70 @@
use Closure;
use OCP\DB\ISchemaWrapper;
+use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
- * Auto-generated migration step: Please modify to your needs!
+ * Initial migration for Passman Next, based on the combination of migrations from the Passman (legacy v2.4.12) app.
*/
-class Version020308Date20210711121919 extends SimpleMigrationStep {
+class VersionNext030000Date20260110234900 extends SimpleMigrationStep
+{
+
+ const TABLE_PREFIX = 'passman_next_';
/**
- * @param IOutput $output
- * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
- * @param array $options
+ * @param IDBConnection $connection
*/
- public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
+ public function __construct(
+ protected IDBConnection $connection,
+ ) {
}
/**
* @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): ?ISchemaWrapper {
- /** @var ISchemaWrapper $schema */
- $schema = $schemaClosure();
+ public function preSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void {
+ }
- if (!$schema->hasTable('passman_vaults')) {
- $table = $schema->createTable('passman_vaults');
+ private function vaultsTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'vaults')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'vaults');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('guid', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
'default' => '',
]);
$table->addColumn('user_id', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
'default' => '',
]);
$table->addColumn('name', 'string', [
'notnull' => true,
- 'length' => 100,
+ 'length' => 100,
]);
$table->addColumn('vault_settings', 'text', [
'notnull' => false,
]);
$table->addColumn('created', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 8,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('last_access', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 8,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('public_sharing_key', 'text', [
@@ -77,7 +80,7 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
]);
$table->addColumn('sharing_keys_generated', 'bigint', [
'notnull' => false,
- 'length' => 8,
+ 'length' => 8,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['last_access'], 'passman_vault_last_access_index');
@@ -85,43 +88,46 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table->addIndex(['id'], 'npassman_vault_id_index');
$table->addIndex(['user_id'], 'passman_vault_uid_id_index');
}
+ }
- if (!$schema->hasTable('passman_credentials')) {
- $table = $schema->createTable('passman_credentials');
+ private function credentialsTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'credentials')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'credentials');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('guid', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('user_id', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('vault_id', 'bigint', [
'notnull' => true,
- 'length' => 8,
+ 'length' => 8,
]);
- $table->addColumn('label', 'text', [
+ $table->addColumn('label', 'string', [
'notnull' => true,
+ 'length' => 2048
]);
$table->addColumn('description', 'text', [
'notnull' => false,
]);
$table->addColumn('created', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 8,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('changed', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 8,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('tags', 'text', [
@@ -140,16 +146,16 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
'notnull' => false,
]);
$table->addColumn('renew_interval', 'bigint', [
- 'notnull' => false,
+ 'notnull' => false,
'unsigned' => true,
]);
$table->addColumn('expire_time', 'bigint', [
- 'notnull' => false,
+ 'notnull' => false,
'unsigned' => true,
]);
$table->addColumn('delete_time', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
+ 'notnull' => false,
+ 'length' => 8,
'unsigned' => true,
]);
$table->addColumn('files', 'text', [
@@ -179,26 +185,28 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table->addIndex(['vault_id'], 'passman_credential_vault_id_index');
$table->addIndex(['user_id'], 'passman_credential_user_id_index');
}
+ }
- if (!$schema->hasTable('passman_files')) {
- $table = $schema->createTable('passman_files');
+ private function filesTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'files')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'files');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('guid', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('user_id', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('mimetype', 'string', [
'notnull' => true,
- 'length' => 255,
+ 'length' => 255,
]);
$table->addColumn('filename', 'text', [
'notnull' => true,
@@ -216,31 +224,33 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
$table->addIndex(['id'], 'passman_file_id_index');
$table->addIndex(['user_id'], 'passman_file_user_id_index');
}
+ }
- if (!$schema->hasTable('passman_revisions')) {
- $table = $schema->createTable('passman_revisions');
+ private function revisionsTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'revisions')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'revisions');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('guid', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('credential_id', 'bigint', [
'notnull' => true,
- 'length' => 8,
+ 'length' => 8,
]);
$table->addColumn('user_id', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('created', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 8,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('credential_data', 'text', [
@@ -248,65 +258,67 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
]);
$table->addColumn('edited_by', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->setPrimaryKey(['id']);
$table->addIndex(['id'], 'passman_revision_id_index');
$table->addIndex(['user_id'], 'passman_revision_user_id_index');
$table->addIndex(['credential_id'], 'passman_revision_credential_id_index');
}
+ }
- if (!$schema->hasTable('passman_sharing_acl')) {
- $table = $schema->createTable('passman_sharing_acl');
+ private function sharingAclTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'sharing_acl')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'sharing_acl');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('item_id', 'bigint', [
'notnull' => true,
- 'length' => 8,
+ 'length' => 8,
]);
$table->addColumn('item_guid', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('vault_id', 'bigint', [
- 'notnull' => false,
- 'length' => 8,
+ 'notnull' => false,
+ 'length' => 8,
'unsigned' => true,
]);
$table->addColumn('vault_guid', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('user_id', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('created', 'bigint', [
- 'notnull' => false,
- 'length' => 64,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 64,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('expire', 'bigint', [
- 'notnull' => false,
- 'length' => 64,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 64,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('expire_views', 'bigint', [
- 'notnull' => false,
- 'length' => 64,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 64,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('permissions', 'smallint', [
- 'notnull' => true,
- 'length' => 3,
- 'default' => 0,
+ 'notnull' => true,
+ 'length' => 3,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('shared_key', 'text', [
@@ -314,86 +326,110 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt
]);
$table->setPrimaryKey(['id']);
}
+ }
- if (!$schema->hasTable('passman_share_request')) {
- $table = $schema->createTable('passman_share_request');
+ private function shareRequestsTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'share_request')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'share_request');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('item_id', 'bigint', [
'notnull' => true,
- 'length' => 8,
+ 'length' => 8,
]);
$table->addColumn('item_guid', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('target_user_id', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('from_user_id', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('target_vault_id', 'bigint', [
- 'notnull' => true,
- 'length' => 8,
+ 'notnull' => true,
+ 'length' => 8,
'unsigned' => true,
]);
$table->addColumn('target_vault_guid', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('shared_key', 'text', [
'notnull' => true,
]);
$table->addColumn('permissions', 'smallint', [
- 'notnull' => true,
- 'length' => 3,
- 'default' => 0,
+ 'notnull' => true,
+ 'length' => 3,
+ 'default' => 0,
'unsigned' => true,
]);
$table->addColumn('created', 'bigint', [
- 'notnull' => false,
- 'length' => 64,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 64,
+ 'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
}
+ }
- if (!$schema->hasTable('passman_delete_vault_request')) {
- $table = $schema->createTable('passman_delete_vault_request');
+ private function deleteVaultRequestsTable(ISchemaWrapper $schema): void {
+ if (!$schema->hasTable(self::TABLE_PREFIX . 'delete_vault_request')) {
+ $table = $schema->createTable(self::TABLE_PREFIX . 'delete_vault_request');
$table->addColumn('id', 'bigint', [
'autoincrement' => true,
- 'notnull' => true,
- 'length' => 8,
- 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 8,
+ 'unsigned' => true,
]);
$table->addColumn('vault_guid', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('reason', 'string', [
'notnull' => true,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('requested_by', 'string', [
'notnull' => false,
- 'length' => 64,
+ 'length' => 64,
]);
$table->addColumn('created', 'bigint', [
- 'notnull' => false,
- 'length' => 64,
- 'default' => 0,
+ 'notnull' => false,
+ 'length' => 64,
+ 'default' => 0,
'unsigned' => true,
]);
$table->setPrimaryKey(['id']);
}
+ }
+
+ /**
+ * @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): ?ISchemaWrapper {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ $this->vaultsTable($schema);
+ $this->credentialsTable($schema);
+ $this->filesTable($schema);
+ $this->revisionsTable($schema);
+ $this->sharingAclTable($schema);
+ $this->shareRequestsTable($schema);
+ $this->deleteVaultRequestsTable($schema);
+
return $schema;
}