From b77c8232f9e008b6b79776a85725f2975320b217 Mon Sep 17 00:00:00 2001 From: Lukas Metzger Date: Sun, 29 Apr 2018 19:03:01 +0200 Subject: [PATCH] Added Update APIs --- backend/src/config/ConfigDefault.php | 3 +- backend/src/controllers/Setup.php | 3 +- backend/src/controllers/Update.php | 86 +++++++++++++++++++++++ backend/src/public/index.php | 3 + backend/src/sql/Update1.sql | 21 ++++++ backend/src/sql/Update2.sql | 22 ++++++ backend/src/sql/Update3.sql | 12 ++++ backend/src/sql/Update4.sql | 12 ++++ backend/src/sql/Update5.sql | 100 +++++++++++++++++++++++++++ backend/src/sql/setup.sql | 46 ++++++++++-- backend/test/db.sql | 19 +++++ 11 files changed, 317 insertions(+), 10 deletions(-) create mode 100644 backend/src/controllers/Update.php create mode 100644 backend/src/sql/Update1.sql create mode 100644 backend/src/sql/Update2.sql create mode 100644 backend/src/sql/Update3.sql create mode 100644 backend/src/sql/Update4.sql create mode 100644 backend/src/sql/Update5.sql diff --git a/backend/src/config/ConfigDefault.php b/backend/src/config/ConfigDefault.php index de0a803..562a667 100644 --- a/backend/src/config/ConfigDefault.php +++ b/backend/src/config/ConfigDefault.php @@ -37,7 +37,8 @@ $defaultConfig = [ 'SRV', 'TKEY', 'SSHFP', 'TLSA', 'TSIG', 'TXT', 'WKS', 'MBOXFW', 'URL' ] ], - 'proxys' => [] + 'proxys' => [], + 'dbVersion' => 5 ]; if (file_exists('../config/ConfigOverride.php')) { diff --git a/backend/src/controllers/Setup.php b/backend/src/controllers/Setup.php index 179fa5a..b8b79f0 100644 --- a/backend/src/controllers/Setup.php +++ b/backend/src/controllers/Setup.php @@ -75,8 +75,7 @@ class Setup $sqlLines = explode(';', file_get_contents('../sql/setup.sql')); foreach ($sqlLines as $sql) { - if (strlen(trim($sql)) > 0) { - var_dump($sql); + if (strlen(preg_replace('/\s+/', '', $sql)) > 0) { $pdo->exec($sql); } } diff --git a/backend/src/controllers/Update.php b/backend/src/controllers/Update.php new file mode 100644 index 0000000..ce60fde --- /dev/null +++ b/backend/src/controllers/Update.php @@ -0,0 +1,86 @@ +logger = $c->logger; + $this->db = $c->db; + $this->c = $c; + } + + public function get(Request $req, Response $res, array $args) + { + $currentVersion = $this->getCurrentVersion(); + + $targetVersion = $this->c['config']['dbVersion']; + + if ($currentVersion < $targetVersion) { + return $res->withJson([ + 'updateRequired' => true, + 'currentVersion' => $currentVersion, + 'targetVersion' => $targetVersion + ], 200); + } else { + return $res->withJson(['updateRequired' => false], 200); + } + } + + public function post(Request $req, Response $res, array $args) + { + $currentVersion = $this->getCurrentVersion(); + + $targetVersion = $this->c['config']['dbVersion']; + + if ($currentVersion < $targetVersion) { + try { + for ($i = $currentVersion + 1; $i <= $targetVersion; $i++) { + $sqlLines = explode(';', file_get_contents('../sql/Update' . $i . '.sql')); + + foreach ($sqlLines as $sql) { + if (strlen(preg_replace('/\s+/', '', $sql)) > 0) { + $this->db->exec($sql); + } + } + + $this->logger->info('Upgrade to version ' . $i . ' successfull!'); + } + } catch (\Exception $e) { + $this->logger->error('Upgrade failed with: ' . $e->getMessage()); + return $res->withJson(['error' => $e->getMessage()], 500); + } + } + + return $res->withStatus(204); + } + + private function getCurrentVersion() : int + { + $query = $this->db->prepare('SHOW TABLES LIKE \'options\';'); + $query->execute(); + if ($query->fetch() === false) { + return 0; + } + + $query = $this->db->prepare('SELECT value FROM options WHERE name=\'schema_version\''); + $query->execute(); + + return intval($query->fetch()['value']); + } +} diff --git a/backend/src/public/index.php b/backend/src/public/index.php index ecd2ab9..49c4735 100644 --- a/backend/src/public/index.php +++ b/backend/src/public/index.php @@ -35,6 +35,9 @@ $app->group('/v1', function () { $this->get('/remote/updatepw', '\Controllers\Remote:updatePassword'); $this->post('/remote/updatekey', '\Controllers\Remote:updateKey'); + $this->get('/update', '\Controllers\Update:get'); + $this->post('/update', '\Controllers\Update:post'); + $this->group('', function () { $this->delete('/sessions/{sessionId}', '\Controllers\Sessions:delete'); diff --git a/backend/src/sql/Update1.sql b/backend/src/sql/Update1.sql new file mode 100644 index 0000000..48dbf6d --- /dev/null +++ b/backend/src/sql/Update1.sql @@ -0,0 +1,21 @@ +CREATE TABLE IF NOT EXISTS remote ( + id int(11) NOT NULL AUTO_INCREMENT, + record int(11) NOT NULL, + description varchar(255) NOT NULL, + type varchar(20) NOT NULL, + security varchar(2000) NOT NULL, + nonce varchar(255) DEFAULT NULL, + PRIMARY KEY (id), + KEY record (record) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +ALTER TABLE `remote` + ADD CONSTRAINT `remote_ibfk_1` FOREIGN KEY (`record`) REFERENCES `records` (`id`); + +CREATE TABLE IF NOT EXISTS options ( + name varchar(255) NOT NULL, + value varchar(2000) DEFAULT NULL, + PRIMARY KEY (name) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO options(name,value) VALUES ('schema_version', 1); \ No newline at end of file diff --git a/backend/src/sql/Update2.sql b/backend/src/sql/Update2.sql new file mode 100644 index 0000000..248c9aa --- /dev/null +++ b/backend/src/sql/Update2.sql @@ -0,0 +1,22 @@ +ALTER TABLE permissions + DROP FOREIGN KEY permissions_ibfk_1; + +ALTER TABLE permissions + DROP FOREIGN KEY permissions_ibfk_2; + +ALTER TABLE permissions + ADD CONSTRAINT permissions_ibfk_1 FOREIGN KEY (domain) REFERENCES domains (id) ON DELETE CASCADE; + +ALTER TABLE permissions + ADD CONSTRAINT permissions_ibfk_2 FOREIGN KEY (user) REFERENCES user (id) ON DELETE CASCADE; + +ALTER TABLE remote + DROP FOREIGN KEY remote_ibfk_1; + +ALTER TABLE remote + ADD CONSTRAINT remote_ibfk_1 FOREIGN KEY (record) REFERENCES records (id) ON DELETE CASCADE; + +ALTER TABLE records + ADD CONSTRAINT records_ibfk_1 FOREIGN KEY (domain_id) REFERENCES domains (id) ON DELETE CASCADE; + +UPDATE options SET value=2 WHERE name='schema_version'; \ No newline at end of file diff --git a/backend/src/sql/Update3.sql b/backend/src/sql/Update3.sql new file mode 100644 index 0000000..1d082c7 --- /dev/null +++ b/backend/src/sql/Update3.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS domainmetadata ( + id INT AUTO_INCREMENT, + domain_id INT NOT NULL, + kind VARCHAR(32), + content TEXT, + PRIMARY KEY (id) +) Engine=InnoDB; + +ALTER TABLE records ADD disabled TINYINT(1) DEFAULT 0; +ALTER TABLE records ADD auth TINYINT(1) DEFAULT 1; + +UPDATE options SET value=3 WHERE name='schema_version'; \ No newline at end of file diff --git a/backend/src/sql/Update4.sql b/backend/src/sql/Update4.sql new file mode 100644 index 0000000..0723e3e --- /dev/null +++ b/backend/src/sql/Update4.sql @@ -0,0 +1,12 @@ +ALTER TABLE permissions DROP FOREIGN KEY permissions_ibfk_2; + +RENAME TABLE user TO users; + +ALTER TABLE permissions CHANGE user userid INT(11); + +ALTER TABLE permissions + ADD CONSTRAINT permissions_ibfk_2 FOREIGN KEY (userid) REFERENCES users (id) ON DELETE CASCADE; + +ALTER TABLE users ADD CONSTRAINT UNIQUE KEY user_name_index (name); + +UPDATE options SET value=4 WHERE name='schema_version'; \ No newline at end of file diff --git a/backend/src/sql/Update5.sql b/backend/src/sql/Update5.sql new file mode 100644 index 0000000..e10ed44 --- /dev/null +++ b/backend/src/sql/Update5.sql @@ -0,0 +1,100 @@ +ALTER DATABASE CHARACTER SET utf8 COLLATE = utf8_general_ci; + +ALTER TABLE `domainmetadata` + ADD INDEX domainmetadata_idx (domain_id,kind); + +ALTER TABLE `domains` + DROP PRIMARY KEY, + DROP INDEX name_index, + ADD PRIMARY KEY(`id`), + ADD UNIQUE INDEX name_index (name), + CHANGE COLUMN notified_serial notified_serial int(10) unsigned NULL; + +ALTER TABLE `permissions` + DROP FOREIGN KEY permissions_ibfk_1, + DROP FOREIGN KEY permissions_ibfk_2, + DROP INDEX domain, + DROP PRIMARY KEY, + CHANGE `userid` `user_id` INT(11) NOT NULL, + CHANGE `domain` `domain_id` INT(11) NOT NULL; + +ALTER TABLE `permissions` + ADD CONSTRAINT permissions_ibfk_1 FOREIGN KEY(user_id) REFERENCES `users`(id), + ADD CONSTRAINT permissions_ibfk_2 FOREIGN KEY(domain_id) REFERENCES `domains`(id), + ADD PRIMARY KEY(`domain_id`,`user_id`), + ADD INDEX permissions_ibfk_3 (domain_id), + COLLATE=utf8_general_ci; + +ALTER TABLE `records` + DROP FOREIGN KEY records_ibfk_1, + DROP INDEX rec_name_index, + DROP INDEX nametype_index, + DROP PRIMARY KEY, + ADD PRIMARY KEY(`id`), + DROP INDEX domain_id; + +ALTER TABLE `records` + ADD CONSTRAINT records_ibfk_1 FOREIGN KEY(domain_id) REFERENCES `domains`(id), + ADD INDEX nametype_index (name,type), + ADD INDEX domain_id (domain_id), + ADD INDEX ordername (ordername), + CHANGE COLUMN content content varchar(64000) NULL, + CHANGE COLUMN type type varchar(10) NULL, + ADD COLUMN ordername varchar(255) NULL AFTER disabled, + CHANGE COLUMN prio prio int(11) NULL, + CHANGE COLUMN auth auth tinyint(1) NULL DEFAULT '1'; + +ALTER TABLE `remote` + DROP FOREIGN KEY remote_ibfk_1, + DROP INDEX record, + DROP PRIMARY KEY, + ADD PRIMARY KEY(`id`); + +ALTER TABLE `remote` + ADD CONSTRAINT remote_ibfk_1 FOREIGN KEY(record) REFERENCES `records`(id), + ADD INDEX remote_ibfk_2 (record), + COLLATE=utf8_general_ci; + +ALTER TABLE `users` + DROP PRIMARY KEY, + ADD PRIMARY KEY(`id`), + CHANGE COLUMN password password varchar(255) NULL AFTER type, + ADD COLUMN backend varchar(50) NOT NULL AFTER name, + COLLATE=utf8_general_ci; + +CREATE TABLE `comments` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain_id` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `type` varchar(10) NOT NULL, + `modified_at` int(11) NOT NULL, + `account` varchar(40) CHARACTER SET utf8 DEFAULT NULL, + `comment` text CHARACTER SET utf8 NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE `cryptokeys` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `domain_id` int(11) NOT NULL, + `flags` int(11) NOT NULL, + `active` tinyint(1) DEFAULT NULL, + `content` text, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE `supermasters` ( + `ip` varchar(64) NOT NULL, + `nameserver` varchar(255) NOT NULL, + `account` varchar(40) CHARACTER SET utf8 NOT NULL, + PRIMARY KEY (`ip`, `nameserver`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE `tsigkeys` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `algorithm` varchar(50) DEFAULT NULL, + `secret` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +UPDATE options SET value=5 WHERE name='schema_version'; \ No newline at end of file diff --git a/backend/src/sql/setup.sql b/backend/src/sql/setup.sql index 6a32d52..9cd5e04 100644 --- a/backend/src/sql/setup.sql +++ b/backend/src/sql/setup.sql @@ -67,7 +67,6 @@ CREATE TABLE `domains` ( -- Table structure for table `permissions` -- -DROP TABLE IF EXISTS `permissions`; CREATE TABLE `permissions` ( `domain_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, @@ -80,9 +79,8 @@ CREATE TABLE `permissions` ( -- Table structure for table `records` -- -DROP TABLE IF EXISTS `records`; CREATE TABLE `records` ( - `id` bigint(20) NOT NULL AUTO_INCREMENT, + `id` int(11) NOT NULL AUTO_INCREMENT, `domain_id` int(11) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `type` varchar(10) DEFAULT NULL, @@ -102,7 +100,6 @@ CREATE TABLE `records` ( -- Table structure for table `remote` -- -DROP TABLE IF EXISTS `remote`; CREATE TABLE `remote` ( `id` int(11) NOT NULL AUTO_INCREMENT, `record` int(11) NOT NULL, @@ -119,7 +116,6 @@ CREATE TABLE `remote` ( -- Table structure for table `supermasters` -- -DROP TABLE IF EXISTS `supermasters`; CREATE TABLE `supermasters` ( `ip` varchar(64) NOT NULL, `nameserver` varchar(255) NOT NULL, @@ -133,7 +129,6 @@ CREATE TABLE `supermasters` ( -- Table structure for table `tsigkeys` -- -DROP TABLE IF EXISTS `tsigkeys`; CREATE TABLE `tsigkeys` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, @@ -148,7 +143,6 @@ CREATE TABLE `tsigkeys` ( -- Table structure for table `users` -- -DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, @@ -160,6 +154,25 @@ CREATE TABLE `users` ( -- -------------------------------------------------------- +-- +-- Table structure for table `options` +-- + +CREATE TABLE `options` ( + `name` varchar(255) NOT NULL, + `value` varchar(2000) DEFAULT NULL, + PRIMARY KEY (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `options` +-- + +INSERT INTO `options` (`name`, `value`) VALUES +('schema_version', '5'); + +-- -------------------------------------------------------- + -- -- Indexes for dumped tables -- @@ -197,3 +210,22 @@ ALTER TABLE `records` -- ALTER TABLE `tsigkeys` ADD UNIQUE KEY `namealgoindex` (`name`,`algorithm`); + +-- +-- Constraints for table `permissions` +-- +ALTER TABLE `permissions` + ADD CONSTRAINT `permissions_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE, + ADD CONSTRAINT `permissions_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE; + +-- +-- Constraints for table `records` +-- +ALTER TABLE `records` + ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`) ON DELETE CASCADE; + +-- +-- Constraints for table `remote` +-- +ALTER TABLE `remote` + ADD CONSTRAINT `remote_ibfk_1` FOREIGN KEY (`record`) REFERENCES `records` (`id`) ON DELETE CASCADE; \ No newline at end of file diff --git a/backend/test/db.sql b/backend/test/db.sql index 390a8d2..3019934 100644 --- a/backend/test/db.sql +++ b/backend/test/db.sql @@ -200,6 +200,25 @@ CREATE TABLE `tsigkeys` ( -- -------------------------------------------------------- +-- +-- Table structure for table `options` +-- + +DROP TABLE IF EXISTS `options`; +CREATE TABLE `options` ( + `name` varchar(255) NOT NULL, + `value` varchar(2000) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `options` +-- + +INSERT INTO `options` (`name`, `value`) VALUES +('schema_version', '5'); + +-- -------------------------------------------------------- + -- -- Table structure for table `users` --