schema: Add user_is_temp column to the user table

This allows temporary users to be identified from applications
external to MediaWiki, by the user table alone (without referring
to the $AutoCreateTempUser['matchPattern'] config).

Bug: T333223
Change-Id: I83c5ff42654164590fb0361c84e65a5315ddbda8
This commit is contained in:
Thalia 2023-05-10 14:22:45 +01:00
parent 32222c9bc7
commit f283c0e990
11 changed files with 266 additions and 1 deletions

View file

@ -142,6 +142,9 @@ class MysqlUpdater extends DatabaseUpdater {
// 1.40
[ 'addField', 'externallinks', 'el_to_path', 'patch-externallinks-el_to_path.sql' ],
// 1.41
[ 'addField', 'user', 'user_is_temp', 'patch-user-user_is_temp.sql' ],
];
}

View file

@ -447,6 +447,9 @@ class PostgresUpdater extends DatabaseUpdater {
// 1.40
[ 'addField', 'externallinks', 'el_to_path', 'patch-externallinks-el_to_path.sql' ],
// 1.41
[ 'addField', 'user', 'user_is_temp', 'patch-user-user_is_temp.sql' ],
];
}

View file

@ -123,6 +123,9 @@ class SqliteUpdater extends DatabaseUpdater {
// 1.40
[ 'addField', 'externallinks', 'el_to_path', 'patch-externallinks-el_to_path.sql' ],
// 1.41
[ 'addField', 'user', 'user_is_temp', 'patch-user-user_is_temp.sql' ],
];
}

View file

@ -0,0 +1,225 @@
{
"comment": "Add user_is_temp to user table",
"before": {
"name": "user",
"comment": "The user table contains basic account information, authentication keys, etc. Some multi-wiki sites may share a single central user table between separate wikis using the $wgSharedDB setting. Note that even when an external authentication plugin is in use, user table entries still need to be created to store preferences and to key tracking information in the other tables",
"columns": [
{
"name": "user_id",
"type": "integer",
"options": { "unsigned": true, "notnull": true, "autoincrement": true }
},
{
"name": "user_name",
"comment": "Usernames must be unique, must not be in the form of an IP address. They should not allow slashes or case conflicts. Spaces are allowed, and are not converted to underscores like in page titles.",
"type": "binary",
"options": { "notnull": true, "length": 255, "default": "" }
},
{
"name": "user_real_name",
"comment": "Optional 'real name' to be displayed in credit listings",
"type": "binary",
"options": { "notnull": true, "length": 255, "default": "" }
},
{
"name": "user_password",
"comment": "Password hashes",
"type": "blob",
"options": { "notnull": true, "length": 255 }
},
{
"name": "user_newpassword",
"comment": "When using 'mail me a new password', a random password is generated and the hash stored here. The previous password is left in place until someone actually logs in with the new password, at which point the hash is moved to user_password and the old password is invalidated.",
"type": "blob",
"options": { "notnull": true, "length": 255 }
},
{
"name": "user_newpass_time",
"comment": "Timestamp of the last time when a new password was sent, for throttling and expiring purposes. Emailed passwords will expire $wgNewPasswordExpiry (a week) after being set. If user_newpass_time is NULL (eg. created by mail) it doesn't expire.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_email",
"comment": "User email. Non public info.",
"type": "text",
"options": { "notnull": true, "length": 255 }
},
{
"name": "user_touched",
"comment": "If the browser sends an If-Modified-Since header, a 304 response is suppressed if the value in this field for the current user is later than the value in the IMS header. That is, this field is an invalidation timestamp for the browser cache of logged-in users. Among other things, it is used to prevent pages generated for a previously logged in user from being displayed after a session expiry followed by a fresh login.",
"type": "mwtimestamp",
"options": { "notnull": true }
},
{
"name": "user_token",
"comment": "A pseudorandomly generated value that is stored in a cookie when the 'remember password' feature is used (previously, a hash of the password was used, but this was vulnerable to cookie-stealing attacks)",
"type": "binary",
"options": { "notnull": true, "default": "", "length": 32, "fixed": true }
},
{
"name": "user_email_authenticated",
"comment": "Initially NULL; when a user's e-mail address has been validated by returning with a mailed token, this is set to the current timestamp.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_email_token",
"comment": "Randomly generated token created when the e-mail address is set and a confirmation test mail sent.",
"type": "binary",
"options": { "notnull": false, "length": 32, "fixed": true }
},
{
"name": "user_email_token_expires",
"comment": "Expiration date for the user_email_token.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_registration",
"comment": "Timestamp of account registration. Accounts predating this schema addition may contain NULL.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_editcount",
"comment": "Count of edits and edit-like actions. Not intended to be an accurate copy of 'COUNT(*) WHERE rev_actor refers to a user's actor_id'. May contain NULL for old accounts if batch-update scripts haven't been run, as well as listing deleted edits and other myriad ways it could be out of sync. Meant primarily for heuristic checks to give an impression of whether the account has been used much.",
"type": "integer",
"options": { "notnull": false, "unsigned": true }
},
{
"name": "user_password_expires",
"comment": "Expiration date for user password.",
"type": "mwtimestamp",
"options": {
"notnull": false,
"CustomSchemaOptions": {
"allowInfinite": true
}
}
}
],
"indexes": [
{ "name": "user_name", "columns": [ "user_name" ], "unique": true },
{ "name": "user_email_token", "columns": [ "user_email_token" ], "unique": false },
{ "name": "user_email", "columns": [ "user_email" ], "unique": false, "options": { "lengths": [ 50, null, null ] } }
],
"pk": [ "user_id" ]
},
"after": {
"name": "user",
"comment": "The user table contains basic account information, authentication keys, etc. Some multi-wiki sites may share a single central user table between separate wikis using the $wgSharedDB setting. Note that even when an external authentication plugin is in use, user table entries still need to be created to store preferences and to key tracking information in the other tables",
"columns": [
{
"name": "user_id",
"type": "integer",
"options": { "unsigned": true, "notnull": true, "autoincrement": true }
},
{
"name": "user_name",
"comment": "Usernames must be unique, must not be in the form of an IP address. They should not allow slashes or case conflicts. Spaces are allowed, and are not converted to underscores like in page titles.",
"type": "binary",
"options": { "notnull": true, "length": 255, "default": "" }
},
{
"name": "user_real_name",
"comment": "Optional 'real name' to be displayed in credit listings",
"type": "binary",
"options": { "notnull": true, "length": 255, "default": "" }
},
{
"name": "user_password",
"comment": "Password hashes",
"type": "blob",
"options": { "notnull": true, "length": 255 }
},
{
"name": "user_newpassword",
"comment": "When using 'mail me a new password', a random password is generated and the hash stored here. The previous password is left in place until someone actually logs in with the new password, at which point the hash is moved to user_password and the old password is invalidated.",
"type": "blob",
"options": { "notnull": true, "length": 255 }
},
{
"name": "user_newpass_time",
"comment": "Timestamp of the last time when a new password was sent, for throttling and expiring purposes. Emailed passwords will expire $wgNewPasswordExpiry (a week) after being set. If user_newpass_time is NULL (eg. created by mail) it doesn't expire.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_email",
"comment": "User email. Non public info.",
"type": "text",
"options": { "notnull": true, "length": 255 }
},
{
"name": "user_touched",
"comment": "If the browser sends an If-Modified-Since header, a 304 response is suppressed if the value in this field for the current user is later than the value in the IMS header. That is, this field is an invalidation timestamp for the browser cache of logged-in users. Among other things, it is used to prevent pages generated for a previously logged in user from being displayed after a session expiry followed by a fresh login.",
"type": "mwtimestamp",
"options": { "notnull": true }
},
{
"name": "user_token",
"comment": "A pseudorandomly generated value that is stored in a cookie when the 'remember password' feature is used (previously, a hash of the password was used, but this was vulnerable to cookie-stealing attacks)",
"type": "binary",
"options": { "notnull": true, "default": "", "length": 32, "fixed": true }
},
{
"name": "user_email_authenticated",
"comment": "Initially NULL; when a user's e-mail address has been validated by returning with a mailed token, this is set to the current timestamp.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_email_token",
"comment": "Randomly generated token created when the e-mail address is set and a confirmation test mail sent.",
"type": "binary",
"options": { "notnull": false, "length": 32, "fixed": true }
},
{
"name": "user_email_token_expires",
"comment": "Expiration date for the user_email_token.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_registration",
"comment": "Timestamp of account registration. Accounts predating this schema addition may contain NULL.",
"type": "mwtimestamp",
"options": { "notnull": false }
},
{
"name": "user_editcount",
"comment": "Count of edits and edit-like actions. Not intended to be an accurate copy of 'COUNT(*) WHERE rev_actor refers to a user's actor_id'. May contain NULL for old accounts if batch-update scripts haven't been run, as well as listing deleted edits and other myriad ways it could be out of sync. Meant primarily for heuristic checks to give an impression of whether the account has been used much.",
"type": "integer",
"options": { "notnull": false, "unsigned": true }
},
{
"name": "user_password_expires",
"comment": "Expiration date for user password.",
"type": "mwtimestamp",
"options": {
"notnull": false,
"CustomSchemaOptions": {
"allowInfinite": true
}
}
},
{
"name": "user_is_temp",
"comment": "A boolean value representing whether the user is a temporary user. False if any type of user other than a temporary user. This exists to allow temporary users to be identified from the database only, by external applications.",
"type": "mwtinyint",
"options": {
"notnull": true,
"length": 1,
"default": 0
}
}
],
"indexes": [
{ "name": "user_name", "columns": [ "user_name" ], "unique": true },
{ "name": "user_email_token", "columns": [ "user_email_token" ], "unique": false },
{ "name": "user_email", "columns": [ "user_email" ], "unique": false, "options": { "lengths": [ 50, null, null ] } }
],
"pk": [ "user_id" ]
}
}

View file

@ -0,0 +1,6 @@
-- This file is automatically generated using maintenance/generateSchemaChangeSql.php.
-- Source: maintenance/abstractSchemaChanges/patch-user-user_is_temp.json
-- Do not modify this file directly.
-- See https://www.mediawiki.org/wiki/Manual:Schema_changes
ALTER TABLE /*_*/user
ADD user_is_temp TINYINT(1) DEFAULT 0 NOT NULL;

View file

@ -0,0 +1,6 @@
-- This file is automatically generated using maintenance/generateSchemaChangeSql.php.
-- Source: maintenance/abstractSchemaChanges/patch-user-user_is_temp.json
-- Do not modify this file directly.
-- See https://www.mediawiki.org/wiki/Manual:Schema_changes
ALTER TABLE "user"
ADD user_is_temp SMALLINT DEFAULT 0 NOT NULL;

View file

@ -903,6 +903,7 @@ CREATE TABLE "user" (
user_registration TIMESTAMPTZ DEFAULT NULL,
user_editcount INT DEFAULT NULL,
user_password_expires TIMESTAMPTZ DEFAULT NULL,
user_is_temp SMALLINT DEFAULT 0 NOT NULL,
PRIMARY KEY(user_id)
);

View file

@ -0,0 +1,6 @@
-- This file is automatically generated using maintenance/generateSchemaChangeSql.php.
-- Source: maintenance/abstractSchemaChanges/patch-user-user_is_temp.json
-- Do not modify this file directly.
-- See https://www.mediawiki.org/wiki/Manual:Schema_changes
ALTER TABLE /*_*/user
ADD COLUMN user_is_temp SMALLINT DEFAULT 0 NOT NULL;

View file

@ -838,7 +838,8 @@ CREATE TABLE /*_*/user (
user_email_token_expires BLOB DEFAULT NULL,
user_registration BLOB DEFAULT NULL,
user_editcount INTEGER UNSIGNED DEFAULT NULL,
user_password_expires BLOB DEFAULT NULL
user_password_expires BLOB DEFAULT NULL,
user_is_temp SMALLINT DEFAULT 0 NOT NULL
);
CREATE UNIQUE INDEX user_name ON /*_*/user (user_name);

View file

@ -839,6 +839,7 @@ CREATE TABLE /*_*/user (
user_registration BINARY(14) DEFAULT NULL,
user_editcount INT UNSIGNED DEFAULT NULL,
user_password_expires VARBINARY(14) DEFAULT NULL,
user_is_temp TINYINT(1) DEFAULT 0 NOT NULL,
UNIQUE INDEX user_name (user_name),
INDEX user_email_token (user_email_token),
INDEX user_email (

View file

@ -3508,6 +3508,16 @@
"allowInfinite": true
}
}
},
{
"name": "user_is_temp",
"comment": "A boolean value representing whether the user is a temporary user. Zero if any type of user other than a temporary user. This exists to allow temporary users to be identified from the database only, by external applications.",
"type": "mwtinyint",
"options": {
"notnull": true,
"length": 1,
"default": 0
}
}
],
"indexes": [