diff --git a/lib/Database.php b/lib/Database.php index 52d315c7..6c038ab5 100644 --- a/lib/Database.php +++ b/lib/Database.php @@ -35,7 +35,7 @@ use JKingWeb\Arsse\Misc\URL; * deletes a user from the database, and labelArticlesSet() changes a label's * associations with articles. There has been an effort to keep public method * names consistent throughout, but protected methods, having different - * concerns, will typicsally follow different conventions. + * concerns, will typically follow different conventions. */ class Database { /** The version number of the latest schema the interface is aware of */ @@ -256,7 +256,7 @@ class Database { throw new User\Exception("alreadyExists", ["action" => __FUNCTION__, "user" => $user]); } $hash = (strlen($password) > 0) ? password_hash($password, \PASSWORD_DEFAULT) : ""; - $this->db->prepare("INSERT INTO arsse_users(id,password) values(?,?)", "str", "str")->runArray([$user,$hash]); + $this->db->prepare("INSERT INTO arsse_users(id,password,num) values(?, ?, coalesce((select max(num) from arsse_users), 0) + 1)", "str", "str")->runArray([$user,$hash]); return true; } diff --git a/sql/SQLite3/6.sql b/sql/SQLite3/6.sql index 7f74ee29..142fada0 100644 --- a/sql/SQLite3/6.sql +++ b/sql/SQLite3/6.sql @@ -2,6 +2,30 @@ -- Copyright 2017 J. King, Dustin Wilson et al. -- See LICENSE and AUTHORS files for details +-- Add multiple columns to the users table +-- In particular this adds a numeric identifier for each user, which Miniflux requires +create table arsse_users_new( +-- users + id text primary key not null collate nocase, -- user id + password text, -- password, salted and hashed; if using external authentication this would be blank + num integer unique not null, -- numeric identfier used by Miniflux + admin boolean not null default 0, -- Whether the user is an administrator + lang text, -- The user's chosen language code e.g. 'en', 'fr-ca'; null uses the system default + tz text not null default 'Etc/UTC', -- The user's chosen time zone, in zoneinfo format + sort_asc boolean not null default 0 -- Whether the user prefers to sort articles in ascending order +) without rowid; +create temp table arsse_users_existing( + id text not null, + num integer primary key +); +insert into arsse_users_existing(id) select id from arsse_users; +insert into arsse_users_new(id, password, num) + select id, password, num + from arsse_users + join arsse_users_existing using(id); +drop table arsse_users; +drop table arsse_users_existing; +alter table arsse_users_new rename to arsse_users; -- set version marker pragma user_version = 7; diff --git a/tests/cases/Database/SeriesArticle.php b/tests/cases/Database/SeriesArticle.php index 2f78e9c1..a9354c71 100644 --- a/tests/cases/Database/SeriesArticle.php +++ b/tests/cases/Database/SeriesArticle.php @@ -19,12 +19,13 @@ trait SeriesArticle { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], - ["john.doe@example.org", ""], - ["john.doe@example.net", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], + ["john.doe@example.org", "",3], + ["john.doe@example.net", "",4], ], ], 'arsse_feeds' => [ diff --git a/tests/cases/Database/SeriesCleanup.php b/tests/cases/Database/SeriesCleanup.php index ad40dcb3..b31f87c7 100644 --- a/tests/cases/Database/SeriesCleanup.php +++ b/tests/cases/Database/SeriesCleanup.php @@ -30,10 +30,11 @@ trait SeriesCleanup { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], ], ], 'arsse_sessions' => [ diff --git a/tests/cases/Database/SeriesFeed.php b/tests/cases/Database/SeriesFeed.php index d4a75213..1eb23bb0 100644 --- a/tests/cases/Database/SeriesFeed.php +++ b/tests/cases/Database/SeriesFeed.php @@ -19,10 +19,11 @@ trait SeriesFeed { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], ], ], 'arsse_feeds' => [ diff --git a/tests/cases/Database/SeriesFolder.php b/tests/cases/Database/SeriesFolder.php index 6d69f64a..98d12d7b 100644 --- a/tests/cases/Database/SeriesFolder.php +++ b/tests/cases/Database/SeriesFolder.php @@ -15,10 +15,11 @@ trait SeriesFolder { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], ], ], 'arsse_folders' => [ diff --git a/tests/cases/Database/SeriesLabel.php b/tests/cases/Database/SeriesLabel.php index db9c4989..d66dcdb0 100644 --- a/tests/cases/Database/SeriesLabel.php +++ b/tests/cases/Database/SeriesLabel.php @@ -17,12 +17,13 @@ trait SeriesLabel { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], - ["john.doe@example.org", ""], - ["john.doe@example.net", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], + ["john.doe@example.org", "",3], + ["john.doe@example.net", "",4], ], ], 'arsse_folders' => [ diff --git a/tests/cases/Database/SeriesSession.php b/tests/cases/Database/SeriesSession.php index 9a354f66..163d8bf8 100644 --- a/tests/cases/Database/SeriesSession.php +++ b/tests/cases/Database/SeriesSession.php @@ -26,10 +26,11 @@ trait SeriesSession { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], ], ], 'arsse_sessions' => [ diff --git a/tests/cases/Database/SeriesSubscription.php b/tests/cases/Database/SeriesSubscription.php index d8614e24..c0a88f4a 100644 --- a/tests/cases/Database/SeriesSubscription.php +++ b/tests/cases/Database/SeriesSubscription.php @@ -18,10 +18,11 @@ trait SeriesSubscription { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], ], ], 'arsse_folders' => [ diff --git a/tests/cases/Database/SeriesTag.php b/tests/cases/Database/SeriesTag.php index f6a3f4ea..3c4b4ac8 100644 --- a/tests/cases/Database/SeriesTag.php +++ b/tests/cases/Database/SeriesTag.php @@ -16,12 +16,13 @@ trait SeriesTag { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], - ["john.doe@example.org", ""], - ["john.doe@example.net", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], + ["john.doe@example.org", "",3], + ["john.doe@example.net", "",4], ], ], 'arsse_feeds' => [ diff --git a/tests/cases/Database/SeriesToken.php b/tests/cases/Database/SeriesToken.php index aad4a875..267be38e 100644 --- a/tests/cases/Database/SeriesToken.php +++ b/tests/cases/Database/SeriesToken.php @@ -20,10 +20,11 @@ trait SeriesToken { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["jane.doe@example.com", "",1], + ["john.doe@example.com", "",2], ], ], 'arsse_tokens' => [ diff --git a/tests/cases/Database/SeriesUser.php b/tests/cases/Database/SeriesUser.php index 54376600..9b97fd80 100644 --- a/tests/cases/Database/SeriesUser.php +++ b/tests/cases/Database/SeriesUser.php @@ -15,11 +15,12 @@ trait SeriesUser { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["admin@example.net", '$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW'], // password is hash of "secret" - ["jane.doe@example.com", ""], - ["john.doe@example.com", ""], + ["admin@example.net", '$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW',1], // password is hash of "secret" + ["jane.doe@example.com", "",2], + ["john.doe@example.com", "",3], ], ], ]; diff --git a/tests/cases/Db/BaseUpdate.php b/tests/cases/Db/BaseUpdate.php index d5415134..b25e4723 100644 --- a/tests/cases/Db/BaseUpdate.php +++ b/tests/cases/Db/BaseUpdate.php @@ -134,4 +134,22 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest { $this->drv->schemaUpdate(Database::SCHEMA_VERSION); $this->assertTrue($this->drv->maintenance()); } + + public function testUpdateTo7(): void { + $this->drv->schemaUpdate(6); + $this->drv->exec(<<drv->schemaUpdate(7); + $exp = [ + ['id' => "a", 'password' => "xyz", 'num' => 1], + ['id' => "b", 'password' => "abc", 'num' => 2], + ]; + $this->assertEquals($exp, $this->drv->query("SELECT id, password, num from arsse_users")->getAll()); + $this->assertSame(2, (int) $this->drv->query("SELECT count(*) from arsse_folders")->getValue()); + } } diff --git a/tests/cases/ImportExport/TestImportExport.php b/tests/cases/ImportExport/TestImportExport.php index 4d3fef30..af0b0fe0 100644 --- a/tests/cases/ImportExport/TestImportExport.php +++ b/tests/cases/ImportExport/TestImportExport.php @@ -46,10 +46,11 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest { 'columns' => [ 'id' => 'str', 'password' => 'str', + 'num' => 'int', ], 'rows' => [ - ["john.doe@example.com", ""], - ["jane.doe@example.com", ""], + ["john.doe@example.com", "", 1], + ["jane.doe@example.com", "", 2], ], ], 'arsse_folders' => [