Skip to content

Commit

Permalink
safer private key upload
Browse files Browse the repository at this point in the history
remove leftover cert when reverting setting to default
  • Loading branch information
artyom-jaksov-tl committed Oct 24, 2024
1 parent 0d213c7 commit 9c0a24c
Showing 1 changed file with 61 additions and 19 deletions.
80 changes: 61 additions & 19 deletions Model/System/Config/Backend/PrivateKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
class PrivateKey extends Value
{
public const FILENAME = 'private-key.pem';
/**
* @var File
*/
Expand Down Expand Up @@ -76,40 +77,59 @@ public function beforeSave(): self
{
$value = (array)$this->getValue();
$sandbox = $this->getPath() === ConnectionInterface::XML_PATH_SANDBOX_PRIVATE_KEY;
$directory = $this->getDirectory($sandbox);

if (!empty($value['delete']) && !empty($value['value'])) {
$this->deleteCertificateAndReset($value['value']);
if (!empty($value['delete'])) {
$this->deleteCertificateAndReset($this->isObjectNew() ? '' : $this->getOldValue());
return $this;
}

if (!empty($value['value'])) {
$this->setValue($value['value']);
}

if (empty($value['tmp_name'])) {
$tmpName = $this->getTmpName($sandbox);
$isUploading = (is_string($tmpName) && !empty($tmpName) && $this->tmpDirectory->isExist($tmpName));

if (!$isUploading) {
$this->setValue($this->isObjectNew() ? '' : $this->getOldValue());
return $this;
}

$tmpPath = $this->tmpDirectory->getAbsolutePath($value['tmp_name']);
if ($tmpPath && $this->tmpDirectory->isExist($tmpPath)) {
if ($isUploading) {
$tmpPath = $this->tmpDirectory->getAbsolutePath($tmpName);
if (!$this->tmpDirectory->stat($tmpPath)['size']) {
throw new LocalizedException(__('The TrueLayer certificate file is empty.'));
}

$filePath = $this->getFilePath($sandbox);
$destinationPath = $this->varDirectory->getAbsolutePath('truelayer/' . $filePath);
$destinationPath = $this->varDirectory->getAbsolutePath('truelayer/' . $directory);

$filePath = $directory . self::FILENAME;
$this->file->checkAndCreateFolder($destinationPath);
$this->file->mv(
$tmpPath,
$this->varDirectory->getAbsolutePath('truelayer/' . $filePath . $value['name'])
$this->varDirectory->getAbsolutePath('truelayer/' . $filePath)
);
$this->setValue($filePath . $value['name']);
$this->setValue($filePath);
}

return $this;
}

/**
* Delete the cert file from disk when deleting the setting.
*
* @return $this
*/
public function beforeDelete()
{
$returnValue = parent::beforeDelete();
$filePath = $this->isObjectNew() ? '' : $this->getOldValue();
if ($filePath) {
$absolutePath = $this->varDirectory->getAbsolutePath('truelayer/' . $filePath);
if ($this->file->fileExists($absolutePath)) {
$this->file->rm($absolutePath);
}
}
return $returnValue;
}

/**
* Delete the cert file and unset the config value.
*
Expand All @@ -118,25 +138,47 @@ public function beforeSave(): self
*/
private function deleteCertificateAndReset(string $filePath): void
{
$absolutePath = $this->varDirectory->getAbsolutePath('truelayer/' . $filePath);
if ($this->file->fileExists($absolutePath)) {
$this->file->rm($absolutePath);
if (!empty($filePath)) {
$absolutePath = $this->varDirectory->getAbsolutePath('truelayer/' . $filePath);
if ($this->file->fileExists($absolutePath)) {
$this->file->rm($absolutePath);
}
}

$this->setValue('');
}

/**
* Returns the filepath based on set scope.
* Returns the directory based on set scope.
*
* @param bool $sandbox
* @return string
*/
private function getFilePath(bool $sandbox): string
private function getDirectory(bool $sandbox): string
{
$mode = $sandbox ? 'sandbox' : 'production';
return $this->getScope() !== 'default'
? sprintf('%s/%s/%s/', $mode, $this->getScope(), $this->getScopeId())
: sprintf('%s/default/', $mode);
}

/**
* Returns the path to the uploaded tmp_file based on set scope.
*
* @param bool $sandbox
* @return string
*/
private function getTmpName(bool $sandbox): ?string
{
$files = $_FILES;
if (empty($files)) {
return null;
}
try {
$tmpName = $files['groups']['tmp_name']['general']['fields'][$sandbox ? 'sandbox_private_key' : 'production_private_key']['value'];
return empty($tmpName) ? null : $tmpName;
} catch (\Exception $e) {
return null;
}
}
}

0 comments on commit 9c0a24c

Please sign in to comment.