Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix(user-prefs): adding sensitive and indexed as flags
Signed-off-by: Maxence Lange <[email protected]>
  • Loading branch information
ArtificialOwl committed Nov 18, 2024
commit e73513bdd1f42da656b79bf78d8d3763386d26b1
19 changes: 17 additions & 2 deletions core/Migrations/Version31000Date20240814184402.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use OCP\Migration\Attributes\AddColumn;
use OCP\Migration\Attributes\AddIndex;
use OCP\Migration\Attributes\ColumnType;
use OCP\Migration\Attributes\DropIndex;
use OCP\Migration\Attributes\IndexType;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
Expand All @@ -23,16 +24,30 @@
*/
#[AddColumn(table: 'preferences', name: 'lazy', type: ColumnType::SMALLINT, description: 'lazy loading to user preferences')]
#[AddColumn(table: 'preferences', name: 'type', type: ColumnType::SMALLINT, description: 'typed values to user preferences')]
#[AddIndex(table: 'preferences', type: IndexType::INDEX, description: 'new index including lazy flag')]
#[AddColumn(table: 'preferences', name: 'flag', type: ColumnType::INTEGER, description: 'bitflag about the value')]
#[AddColumn(table: 'preferences', name: 'indexed', type: ColumnType::INTEGER, description: 'non-array value can be set as indexed')]
#[DropIndex(table: 'preferences', type: IndexType::INDEX, description: 'remove previous app/key index', notes: ['will be re-created to include \'indexed\' field'])]
#[AddIndex(table: 'preferences', type: IndexType::INDEX, description: 'new index including user+lazy')]
#[AddIndex(table: 'preferences', type: IndexType::INDEX, description: 'new index including app/key and indexed')]
class Version31000Date20240814184402 extends SimpleMigrationStep {
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();

$table = $schema->getTable('preferences');
$table->addColumn('lazy', Types::SMALLINT, ['notnull' => true, 'default' => 0, 'length' => 1, 'unsigned' => true]);
$table->addColumn('type', Types::INTEGER, ['notnull' => true, 'default' => 2, 'unsigned' => true]);
$table->addColumn('type', Types::SMALLINT, ['notnull' => true, 'default' => 0, 'unsigned' => true]);
$table->addColumn('flags', Types::INTEGER, ['notnull' => true, 'default' => 0, 'unsigned' => true]);
$table->addColumn('indexed', Types::STRING, ['notnull' => true, 'default' => '', 'length' => 64]);

// removing this index from Version13000Date20170718121200
// $table->addIndex(['appid', 'configkey'], 'preferences_app_key');
if ($table->hasIndex('preferences_app_key')) {
$table->dropIndex('preferences_app_key');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for my dev instance running mariadb this DROP did not happen, so I now have redundant indexes:

image

The migration code seems correct, but something seems to prevent the DROP. @ArtificialOwl could you check the upgrade path?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #49638

The index is dropped... But next repair step run adds it again

}

$table->addIndex(['userid', 'lazy'], 'prefs_uid_lazy_i');
$table->addIndex(['appid', 'configkey', 'indexed', 'flags'], 'prefs_app_key_ind_fl_i');

return $schema;
}
Expand Down
48 changes: 30 additions & 18 deletions lib/private/AllConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,17 +226,23 @@ public function deleteAppValues($appName) {
* @param string $key the key under which the value is being stored
* @param string|float|int $value the value that you want to store
* @param string $preCondition only update if the config value was previously the value passed as $preCondition
*
* @throws \OCP\PreConditionNotMetException if a precondition is specified and is not met
* @throws \UnexpectedValueException when trying to store an unexpected value
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @see IUserPreferences::getValueString
* @see IUserPreferences::getValueInt
* @see IUserPreferences::getValueFloat
* @see IUserPreferences::getValueArray
* @see IUserPreferences::getValueBool
*/
public function setUserValue($userId, $appName, $key, $value, $preCondition = null) {
if (!is_int($value) && !is_float($value) && !is_string($value)) {
throw new \UnexpectedValueException('Only integers, floats and strings are allowed as value');
}

/** @var UserPreferences $userPreferences */
$userPreferences = \OC::$server->get(IUserPreferences::class);
$userPreferences = \OCP\Server::get(IUserPreferences::class);
if ($preCondition !== null) {
try {
if ($userPreferences->getValueMixed($userId, $appName, $key) !== (string)$preCondition) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a behaviour change, previously the precondition did not fail, when the value is not set in the database.

Expand All @@ -256,15 +262,21 @@ public function setUserValue($userId, $appName, $key, $value, $preCondition = nu
* @param string $appName the appName that we stored the value under
* @param string $key the key under which the value is being stored
* @param mixed $default the default value to be returned if the value isn't set
*
* @return string
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @see IUserPreferences::getValueString
* @see IUserPreferences::getValueInt
* @see IUserPreferences::getValueFloat
* @see IUserPreferences::getValueArray
* @see IUserPreferences::getValueBool
*/
public function getUserValue($userId, $appName, $key, $default = '') {
if ($userId === null || $userId === '') {
return $default;
}
/** @var UserPreferences $userPreferences */
$userPreferences = \OC::$server->get(IUserPreferences::class);
$userPreferences = \OCP\Server::get(IUserPreferences::class);
// because $default can be null ...
if (!$userPreferences->hasKey($userId, $appName, $key)) {
return $default;
Expand All @@ -278,10 +290,10 @@ public function getUserValue($userId, $appName, $key, $default = '') {
* @param string $userId the userId of the user that we want to store the value under
* @param string $appName the appName that we stored the value under
* @return string[]
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::getKeys} directly
*/
public function getUserKeys($userId, $appName) {
return \OC::$server->get(IUserPreferences::class)->getKeys($userId, $appName);
return \OCP\Server::get(IUserPreferences::class)->getKeys($userId, $appName);
}

/**
Expand All @@ -290,33 +302,33 @@ public function getUserKeys($userId, $appName) {
* @param string $userId the userId of the user that we want to store the value under
* @param string $appName the appName that we stored the value under
* @param string $key the key under which the value is being stored
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::deletePreference} directly
*/
public function deleteUserValue($userId, $appName, $key) {
\OC::$server->get(IUserPreferences::class)->deletePreference($userId, $appName, $key);
\OCP\Server::get(IUserPreferences::class)->deletePreference($userId, $appName, $key);
}

/**
* Delete all user values
*
* @param string $userId the userId of the user that we want to remove all values from
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::deleteAllPreferences} directly
*/
public function deleteAllUserValues($userId) {
if ($userId === null) {
return;
}
\OC::$server->get(IUserPreferences::class)->deleteAllPreferences($userId);
\OCP\Server::get(IUserPreferences::class)->deleteAllPreferences($userId);
}

/**
* Delete all user related values of one app
*
* @param string $appName the appName of the app that we want to remove all values from
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::deleteApp} directly
*/
public function deleteAppFromAllUsers($appName) {
\OC::$server->get(IUserPreferences::class)->deleteApp($appName);
\OCP\Server::get(IUserPreferences::class)->deleteApp($appName);
}

/**
Expand All @@ -328,14 +340,14 @@ public function deleteAppFromAllUsers($appName) {
* [ $appId =>
* [ $key => $value ]
* ]
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::getAllValues} directly
*/
public function getAllUserValues(?string $userId): array {
if ($userId === null || $userId === '') {
return [];
}

$values = \OC::$server->get(IUserPreferences::class)->getAllValues($userId);
$values = \OCP\Server::get(IUserPreferences::class)->getAllValues($userId);
$result = [];
foreach ($values as $app => $list) {
foreach ($list as $key => $value) {
Expand All @@ -352,10 +364,10 @@ public function getAllUserValues(?string $userId): array {
* @param string $key the key to get the value for
* @param array $userIds the user IDs to fetch the values for
* @return array Mapped values: userId => value
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::getValuesByUsers} directly
*/
public function getUserValueForUsers($appName, $key, $userIds) {
return \OC::$server->get(IUserPreferences::class)->searchValuesByUsers($appName, $key, ValueType::MIXED, $userIds);
return \OCP\Server::get(IUserPreferences::class)->getValuesByUsers($appName, $key, ValueType::MIXED, $userIds);
}

/**
Expand All @@ -365,10 +377,10 @@ public function getUserValueForUsers($appName, $key, $userIds) {
* @param string $key the key to get the user for
* @param string $value the value to get the user for
* @return list<string> of user IDs
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::searchUsersByValueString} directly
*/
public function getUsersForUserValue($appName, $key, $value) {
return \OC::$server->get(IUserPreferences::class)->searchUsersByValueString($appName, $key, $value);
return \OCP\Server::get(IUserPreferences::class)->searchUsersByValueDeprecated($appName, $key, $value);
}

/**
Expand All @@ -378,14 +390,14 @@ public function getUsersForUserValue($appName, $key, $value) {
* @param string $key the key to get the user for
* @param string $value the value to get the user for
* @return list<string> of user IDs
* @deprecated 31.0.0 - use {@see IUserPreferences} directly
* @deprecated 31.0.0 - use {@see IUserPreferences::searchUsersByValueString} directly
*/
public function getUsersForUserValueCaseInsensitive($appName, $key, $value) {
if ($appName === 'settings' && $key === 'email') {
return $this->getUsersForUserValue($appName, $key, strtolower($value));
}

return \OC::$server->get(IUserPreferences::class)->searchUsersByValueString($appName, $key, $value, true);
return \OCP\Server::get(IUserPreferences::class)->searchUsersByValueDeprecated($appName, $key, $value, true);
}

public function getSystemConfig() {
Expand Down
Loading