mirror of
https://github.com/getgrav/grav.git
synced 2026-07-13 06:42:35 +02:00
Fixed save error when editing accounts that have been created with capital letters in their username [#3211]
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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}
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user