Fixed save error when editing accounts that have been created with capital letters in their username [#3211]

This commit is contained in:
Matias Griese
2021-02-08 16:46:30 +02:00
parent 96aac79eb2
commit e520cf949a
8 changed files with 110 additions and 67 deletions

View File

@@ -16,6 +16,7 @@
* Fixed error on `bin/gpm plugin uninstall` [#3207](https://github.com/getgrav/grav/issues/3207)
* Fixed lowering uppercase characters in usernames when saving from frontend [#2565](https://github.com/getgrav/grav/pull/2565)
* Fixed broken min/max validation for field `type: int`
* Fixed save error when editing accounts that have been created with capital letters in their username [#3211](https://github.com/getgrav/grav/issues/3211)
# v1.7.5
## 02/01/2021

View File

@@ -19,22 +19,6 @@ use Grav\Framework\Flex\Storage\FileStorage;
*/
class UserFileStorage extends FileStorage
{
/** @var bool */
public $caseSensitive;
/**
* @param string $key
* @return string
*/
public function normalizeKey(string $key): string
{
if ($this->caseSensitive === true) {
return $key;
}
return mb_strtolower($key);
}
/**
* {@inheritdoc}
* @see FlexStorageInterface::getMediaPath()
@@ -60,15 +44,4 @@ class UserFileStorage extends FileStorage
$row['access'] = $access;
}
}
/**
* @param array $options
* @return void
*/
protected function initOptions(array $options): void
{
parent::initOptions($options);
$this->caseSensitive = $options['case_sensitive'] ?? false;
}
}

View File

@@ -19,22 +19,6 @@ use Grav\Framework\Flex\Storage\FolderStorage;
*/
class UserFolderStorage extends FolderStorage
{
/** @var bool */
public $caseSensitive;
/**
* @param string $key
* @return string
*/
public function normalizeKey(string $key): string
{
if ($this->caseSensitive === true) {
return $key;
}
return mb_strtolower($key);
}
/**
* Prepares the row for saving and returns the storage key for the record.
*
@@ -50,15 +34,4 @@ class UserFolderStorage extends FolderStorage
$row['access'] = $access;
}
}
/**
* @param array $options
* @return void
*/
protected function initOptions(array $options): void
{
parent::initOptions($options);
$this->caseSensitive = $options['case_sensitive'] ?? false;
}
}

View File

@@ -146,11 +146,7 @@ class UserIndex extends FlexIndex
*/
protected static function filterUsername(string $key, FlexStorageInterface $storage): string
{
if (method_exists($storage, 'normalizeKey')) {
return $storage->normalizeKey($key);
}
return mb_strtolower($key);
return $storage->normalizeKey($key);
}
/**

View File

@@ -120,11 +120,22 @@ class UserObject extends FlexObject implements UserInterface, Countable
// User can only be authenticated via login.
unset($elements['authenticated'], $elements['authorized']);
parent::__construct($elements, $key, $directory, $validate);
// Define username if it's not set.
if (!isset($elements['username'])) {
$storageKey = $elements['__META']['storage_key'] ?? null;
if (null !== $storageKey && $key === $directory->getStorage()->normalizeKey($storageKey)) {
$elements['username'] = $storageKey;
} else {
$elements['username'] = $key;
}
}
// Define username and state if they aren't set.
$this->defProperty('username', $key);
$this->defProperty('state', 'enabled');
// Define state if it isn't set.
if (!isset($elements['state'])) {
$elements['state'] = 'enabled';
}
parent::__construct($elements, $key, $directory, $validate);
}
/**

View File

@@ -20,7 +20,6 @@ use Grav\Framework\File\Formatter\MarkdownFormatter;
use Grav\Framework\File\Formatter\YamlFormatter;
use Grav\Framework\File\Interfaces\FileFormatterInterface;
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
use RocketTheme\Toolbox\File\File;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use RuntimeException;
use function is_array;
@@ -37,6 +36,8 @@ abstract class AbstractFilesystemStorage implements FlexStorageInterface
protected $keyField = 'storage_key';
/** @var int */
protected $keyLen = 32;
/** @var bool */
protected $caseSensitive = true;
/**
* @return bool
@@ -98,7 +99,7 @@ abstract class AbstractFilesystemStorage implements FlexStorageInterface
public function extractKeysFromRow(array $row): array
{
return [
'key' => $row[$this->keyField] ?? ''
'key' => $this->normalizeKey($row[$this->keyField] ?? '')
];
}
@@ -201,6 +202,19 @@ abstract class AbstractFilesystemStorage implements FlexStorageInterface
return substr(hash('sha256', random_bytes($this->keyLen)), 0, $this->keyLen);
}
/**
* @param string $key
* @return string
*/
public function normalizeKey(string $key): string
{
if ($this->caseSensitive === true) {
return $key;
}
return mb_strtolower($key);
}
/**
* Checks if a key is valid.
*

View File

@@ -13,6 +13,7 @@ namespace Grav\Framework\Flex\Storage;
use FilesystemIterator;
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
use RuntimeException;
use SplFileInfo;
/**
@@ -50,6 +51,73 @@ class FileStorage extends FolderStorage
return $key ? "{$path}/{$key}" : $path;
}
/**
* @param string $src
* @param string $dst
* @return bool
*/
public function copyRow(string $src, string $dst): bool
{
if ($this->hasKey($dst)) {
throw new RuntimeException("Cannot copy object: key '{$dst}' is already taken");
}
if (!$this->hasKey($src)) {
return false;
}
return true;
}
/**
* {@inheritdoc}
* @see FlexStorageInterface::renameRow()
*/
public function renameRow(string $src, string $dst): bool
{
if (!$this->hasKey($src)) {
return false;
}
// Remove old file.
$path = $this->getPathFromKey($src);
$file = $this->getFile($path);
$file->delete();
return true;
}
/**
* @param string $src
* @param string $dst
* @return bool
*/
protected function copyFolder(string $src, string $dst): bool
{
// Nothing to copy.
return true;
}
/**
* @param string $src
* @param string $dst
* @return bool
*/
protected function moveFolder(string $src, string $dst): bool
{
// Nothing to move.
return true;
}
/**
* @param string $key
* @return bool
*/
protected function canDeleteFolder(string $key): bool
{
return false;
}
/**
* {@inheritdoc}
*/

View File

@@ -242,7 +242,6 @@ class FolderStorage extends AbstractFilesystemStorage
return $this->copyFolder($srcPath, $dstPath);
}
/**
* {@inheritdoc}
* @see FlexStorageInterface::renameRow()
@@ -360,7 +359,12 @@ class FolderStorage extends AbstractFilesystemStorage
*/
protected function prepareRow(array &$row): void
{
unset($row[$this->keyField]);
if (array_key_exists($this->keyField, $row)) {
$key = $row[$this->keyField];
if ($key === $this->normalizeKey($key)) {
unset($row[$this->keyField]);
}
}
}
/**
@@ -401,6 +405,8 @@ class FolderStorage extends AbstractFilesystemStorage
$key = $this->getNewKey();
}
$key = $this->normalizeKey($key);
// Check if the row already exists and if the key has been changed.
$oldKey = $row['__META']['storage_key'] ?? null;
if (is_string($oldKey) && $oldKey !== $key) {
@@ -679,6 +685,7 @@ class FolderStorage extends AbstractFilesystemStorage
$this->indexed = (bool)($options['indexed'] ?? false);
$this->keyField = $options['key'] ?? 'storage_key';
$this->keyLen = (int)($options['key_len'] ?? 32);
$this->caseSensitive = (bool)($options['case_sensitive'] ?? true);
$variables = ['FOLDER' => '%1$s', 'KEY' => '%2$s', 'KEY:2' => '%3$s', 'FILE' => '%4$s', 'EXT' => '%5$s'];
$pattern = Utils::simpleTemplate($pattern, $variables);