From 0c19bb3e59881bf6fe15df30736dbc2697654d9b Mon Sep 17 00:00:00 2001 From: Tim van Dijen <tvdijen@gmail.com> Date: Tue, 1 Mar 2022 17:04:09 +0100 Subject: [PATCH] Rewrite MetaDataStorageHandlerSerialize using symfony/filesystem --- .../MetaDataStorageHandlerSerialize.php | 148 ++++++++---------- 1 file changed, 66 insertions(+), 82 deletions(-) diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php index 8a3ac88ae..07499485d 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSerialize.php @@ -8,6 +8,18 @@ use SimpleSAML\Assert\Assert; use SimpleSAML\Configuration; use SimpleSAML\Logger; use SimpleSAML\Utils; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Path; +use Symfony\Component\Finder\Finder; +use Symfony\Component\HttpFoundation\File\File; + +use function array_key_exists; +use function rawurlencode; +use function serialize; +use function strlen; +use function substr; +use function unserialize; +use function var_export; /** * Class for handling metadata files in serialized format. @@ -45,7 +57,6 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource parent::__construct(); $globalConfig = Configuration::getInstance(); - $cfgHelp = Configuration::loadFromArray($config, 'serialize metadata source'); $this->directory = $cfgHelp->getString('directory'); @@ -80,35 +91,22 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource { $ret = []; - $dh = @opendir($this->directory); - if ($dh === false) { + $loc = new File($this->directory, false); + if (!$this->fileSystem->exists($this->directory) || !$loc->isReadable()) { Logger::warning( 'Serialize metadata handler: Unable to open directory: ' . var_export($this->directory, true) ); return $ret; } - while (($entry = readdir($dh)) !== false) { - if ($entry[0] === '.') { - // skip '..', '.' and hidden files - continue; - } - - $path = $this->directory . '/' . $entry; + $finder = new Finder(); + $finder->directories()->name(sprintf('/%s$/' . self::EXTENSION))->in($this->directory); - if (!is_dir($path)) { - Logger::warning( - 'Serialize metadata handler: Metadata directory contained a file where only directories should ' . - 'exist: ' . var_export($path, true) - ); - continue; - } - - $ret[] = rawurldecode($entry); + $ret = []; + foreach ($finder as $file) { + $ret[] = rawurlencode($file->getPathName()); } - closedir($dh); - return $ret; } @@ -124,32 +122,23 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource { $ret = []; - $dir = $this->directory . '/' . rawurlencode($set); - if (!is_dir($dir)) { - // probably some code asked for a metadata set which wasn't available - return $ret; - } - - $dh = @opendir($dir); - if ($dh === false) { - Logger::warning( - 'Serialize metadata handler: Unable to open directory: ' . var_export($dir, true) - ); + $loc = new File(Path::canonicalize($this->directory . '/' . rawurlencode($set)), false); + if (!$this->fileSystem->exists($loc) || !$loc->isReadable()) { + Logger::warning(sprintf( + 'Serialize metadata handler: Unable to open directory: %s', + var_export($loc->getPathName(), true), + )); return $ret; } $extLen = strlen(self::EXTENSION); - while (($file = readdir($dh)) !== false) { - if (strlen($file) <= $extLen) { - continue; - } + $finder = new Finder(); + $finder->directories()->name(sprintf('/%s/$', self::EXTENSION))->in($this->directory); - if (substr($file, -$extLen) !== self::EXTENSION) { - continue; - } - - $entityId = substr($file, 0, -$extLen); + $ret = []; + foreach ($finder as $file) { + $entityId = substr($file->getPathName(), 0, -$extLen); $entityId = rawurldecode($entityId); $md = $this->getMetaData($entityId, $set); @@ -158,8 +147,6 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource } } - closedir($dh); - return $ret; } @@ -177,17 +164,15 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource { $filePath = $this->getMetadataPath($entityId, $set); - if (!file_exists($filePath)) { + if (!$this->fileSystem->exists($filePath)) { return null; } - $data = @file_get_contents($filePath); - if ($data === false) { - /** @var array $error */ - $error = error_get_last(); - Logger::warning( - 'Error reading file ' . $filePath . ': ' . $error['message'] - ); + $file = new File($filePath); + try { + $data = $file->getContent(); + } catch (IOException $e) { + Logger::warning('Error reading file ' . $filePath . ': ' . $e->getMessage()); return null; } @@ -216,38 +201,37 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource */ public function saveMetadata(string $entityId, string $set, array $metadata): bool { - $filePath = $this->getMetadataPath($entityId, $set); - $newPath = $filePath . '.new'; - - $dir = dirname($filePath); - if (!is_dir($dir)) { - Logger::info('Creating directory: ' . $dir); - $res = @mkdir($dir, 0777, true); - if ($res === false) { - /** @var array $error */ - $error = error_get_last(); - Logger::error('Failed to create directory ' . $dir . ': ' . $error['message']); + $old = new File($this->getMetadataPath($entityId, $set), false); + $new = new File($old->getPathName() . '.new', false); + + $loc = new File($old->getPath(), false); + if (!$loc->isDir()) { + Logger::info('Creating directory: ' . $loc); + try { + $this->fileSystem->mkdir($loc, 0777); + } catch (IOException $e) { + Logger::error('Failed to create directory ' . $loc . ': ' . $e->getMessage()); return false; } } $data = serialize($metadata); - Logger::debug('Writing: ' . $newPath); + Logger::debug('Writing: ' . $new->getPathName()); - $res = file_put_contents($newPath, $data); - if ($res === false) { - /** @var array $error */ - $error = error_get_last(); - Logger::error('Error saving file ' . $newPath . ': ' . $error['message']); + try { + $this->fileSystem->appendToFile($new->getPathName(), $data); + } catch (IOException $e) { + Logger::error('Error saving file ' . $new->getPathName() . ': ' . $e->getMessage()); return false; } - $res = rename($newPath, $filePath); - if ($res === false) { - /** @var array $error */ - $error = error_get_last(); - Logger::error('Error renaming ' . $newPath . ' to ' . $filePath . ': ' . $error['message']); + try { + $this->fileSystem->rename($new->getPathName(), $old->getPathName(), true); + } catch (IOException $e) { + Logger::error( + sprintf('Error renaming %s to %s: %s', $new->getPathName(), $old->getPathName(), $e->getMessage()) + ); return false; } @@ -265,7 +249,7 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource { $filePath = $this->getMetadataPath($entityId, $set); - if (!file_exists($filePath)) { + if (!$this->fileSystem->exists($filePath)) { Logger::warning( 'Attempted to erase nonexistent metadata entry ' . var_export($entityId, true) . ' in set ' . var_export($set, true) . '.' @@ -273,14 +257,14 @@ class MetaDataStorageHandlerSerialize extends MetaDataStorageSource return; } - $res = unlink($filePath); - if ($res === false) { - /** @var array $error */ - $error = error_get_last(); - Logger::error( - 'Failed to delete file ' . $filePath . - ': ' . $error['message'] - ); + try { + $this->fileSystem->remove($filePath); + } catch (IOException $e) { + Logger::error(sprintf( + 'Failed to delete file %s: %s', + $filePath, + $e->getMessage(), + )); } } -- GitLab