Skip to content

Commit

Permalink
* [FIX] Closes #706. Fixed sysPass XML export/import. Account tags we…
Browse files Browse the repository at this point in the history
…ren't exported/imported. Thanks to @joerg for the feedback!
  • Loading branch information
nuxsmin committed Aug 31, 2017
1 parent a2858ed commit 40da8d0
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 57 deletions.
23 changes: 23 additions & 0 deletions inc/SP/Account/AccountTags.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ public static function getTags(AccountData $accountData)
return DB::getResultsArray($Data);
}

/**
* Devolver las etiquetas de una cuenta por id
*
* @param int $id Id de la cuenta
* @return array
*/
public static function getTagsForId($id)
{
$query = /** @lang SQL */
'SELECT tag_id, tag_name
FROM accTags
JOIN tags ON tag_id = acctag_tagId
WHERE acctag_accountId = ?
ORDER BY tag_name';

$Data = new QueryData();
$Data->setQuery($query);
$Data->setUseKeyPair(true);
$Data->addParam($id);

return DB::getResultsArray($Data);
}

/**
* Actualizar las etiquetas de una cuenta
*
Expand Down
112 changes: 61 additions & 51 deletions inc/SP/Core/XmlExport.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
namespace SP\Core;

use Defuse\Crypto\Exception\CryptoException;
use SP\Account\AccountTags;
use SP\Account\AccountUtil;
use SP\Config\Config;
use SP\Core\Crypt\Crypt;
Expand Down Expand Up @@ -120,6 +121,35 @@ public function setEncrypted($encrypted)
$this->encrypted = $encrypted;
}

/**
* @param string $exportDir
*/
public function setExportDir($exportDir)
{
$this->exportDir = $exportDir;
}

/**
* Genera el nombre del archivo usado para la exportación.
*/
private function setExportFile()
{
// Generar hash unico para evitar descargas no permitidas
$exportUniqueHash = sha1(uniqid('sysPassExport', true));
Config::getConfig()->setExportHash($exportUniqueHash);
Config::saveConfig();

$this->exportFile = $this->exportDir . DIRECTORY_SEPARATOR . Util::getAppInfo('appname') . '-' . $exportUniqueHash . '.xml';
}

/**
* Eliminar los archivos de exportación anteriores
*/
private function deleteOldExports()
{
array_map('unlink', glob($this->exportDir . DIRECTORY_SEPARATOR . '*.xml'));
}

/**
* Crear el documento XML y guardarlo
*
Expand Down Expand Up @@ -160,6 +190,27 @@ public function makeXML()
return true;
}

/**
* Comprobar y crear el directorio de exportación.
*
* @throws SPException
* @return bool
*/
private function checkExportDir()
{
if (@mkdir($this->exportDir, 0750) === false && is_dir($this->exportDir) === false) {
throw new SPException(SPException::SP_CRITICAL, sprintf(__('No es posible crear el directorio de backups ("%s")'), $this->exportDir));
}

clearstatcache(true, $this->exportDir);

if (!is_writable($this->exportDir)) {
throw new SPException(SPException::SP_CRITICAL, __('Compruebe los permisos del directorio de backups', false));
}

return true;
}

/**
* Crear el nodo raíz
*
Expand Down Expand Up @@ -358,7 +409,7 @@ private function createTags()

try {
// Crear el nodo de etiquetas
$nodeTags= $this->xml->createElement('Tags');
$nodeTags = $this->xml->createElement('Tags');

foreach ($Tags as $TagData) {
$tagName = $this->xml->createElement('name', $this->escapeChars($TagData->getTagName()));
Expand Down Expand Up @@ -404,6 +455,14 @@ private function createAccounts()
$accountNotes = $this->xml->createElement('notes', $this->escapeChars($account->account_notes));
$accountPass = $this->xml->createElement('pass', $this->escapeChars($account->account_pass));
$accountIV = $this->xml->createElement('key', $this->escapeChars($account->account_key));
$tags = $this->xml->createElement('tags');

foreach (AccountTags::getTagsForId($account->account_id) as $id => $name) {
$tag = $this->xml->createElement('tag');
$tag->setAttribute('id', $id);

$tags->appendChild($tag);
}

// Crear el nodo de cuenta
$nodeAccount = $this->xml->createElement('Account');
Expand All @@ -416,6 +475,7 @@ private function createAccounts()
$nodeAccount->appendChild($accountNotes);
$nodeAccount->appendChild($accountPass);
$nodeAccount->appendChild($accountIV);
$nodeAccount->appendChild($tags);

// Añadir cuenta al nodo de cuentas
$nodeAccounts->appendChild($nodeAccount);
Expand Down Expand Up @@ -486,54 +546,4 @@ private function writeXML()
throw new SPException(SPException::SP_WARNING, $e->getMessage(), __FUNCTION__);
}
}

/**
* Genera el nombre del archivo usado para la exportación.
*/
private function setExportFile()
{
// Generar hash unico para evitar descargas no permitidas
$exportUniqueHash = sha1(uniqid('sysPassExport', true));
Config::getConfig()->setExportHash($exportUniqueHash);
Config::saveConfig();

$this->exportFile = $this->exportDir . DIRECTORY_SEPARATOR . Util::getAppInfo('appname') . '-' . $exportUniqueHash . '.xml';
}

/**
* @param string $exportDir
*/
public function setExportDir($exportDir)
{
$this->exportDir = $exportDir;
}

/**
* Comprobar y crear el directorio de exportación.
*
* @throws SPException
* @return bool
*/
private function checkExportDir()
{
if (@mkdir($this->exportDir, 0750) === false && is_dir($this->exportDir) === false) {
throw new SPException(SPException::SP_CRITICAL, sprintf(__('No es posible crear el directorio de backups ("%s")'), $this->exportDir));
}

clearstatcache(true, $this->exportDir);

if (!is_writable($this->exportDir)) {
throw new SPException(SPException::SP_CRITICAL, __('Compruebe los permisos del directorio de backups', false));
}

return true;
}

/**
* Eliminar los archivos de exportación anteriores
*/
private function deleteOldExports()
{
array_map('unlink', glob($this->exportDir . DIRECTORY_SEPARATOR . '*.xml'));
}
}
28 changes: 25 additions & 3 deletions inc/SP/Import/ImportBase.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
namespace SP\Import;

use SP\Account\Account;
use SP\Account\AccountTags;
use SP\Core\Crypt\Crypt;
use SP\Core\OldCrypt;
use SP\Core\Exceptions\SPException;
Expand Down Expand Up @@ -75,9 +76,9 @@ abstract class ImportBase implements ImportInterface
/**
* ImportBase constructor.
*
* @param FileImport $File
* @param FileImport $File
* @param ImportParams $ImportParams
* @param LogMessage $LogMessage
* @param LogMessage $LogMessage
*/
public function __construct(FileImport $File = null, ImportParams $ImportParams = null, LogMessage $LogMessage = null)
{
Expand Down Expand Up @@ -129,7 +130,9 @@ protected function addAccount(AccountExtData $AccountData)
if ($AccountData->getAccountCategoryId() === 0) {
Log::writeNewLog(__FUNCTION__, __('Id de categoría no definido. No es posible importar cuenta.', false), Log::INFO);
return false;
} elseif ($AccountData->getAccountCustomerId() === 0) {
}

if ($AccountData->getAccountCustomerId() === 0) {
Log::writeNewLog(__FUNCTION__, __('Id de cliente no definido. No es posible importar cuenta.', false), Log::INFO);
return false;
}
Expand Down Expand Up @@ -233,4 +236,23 @@ protected function addTag(TagData $TagData)

return null;
}

/**
* Añadir las etiquetas de la cuenta
*
* @param AccountExtData $accountExtData
* @param array $tags
*/
protected function addAccountTags(AccountExtData $accountExtData, array $tags)
{
try {
$accountExtData->setTags($tags);

$AccountTags = new AccountTags();
$AccountTags->addTags($accountExtData);
} catch (SPException $e) {
$this->LogMessage->addDetails($e->getMessage(), $accountExtData->getAccountName());
$this->LogMessage->addDetails(__('Error', false), $e->getHint());
}
}
}
33 changes: 32 additions & 1 deletion inc/SP/Import/SyspassImport.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
namespace SP\Import;

use DOMXPath;
use SP\Account\AccountTags;
use SP\Config\ConfigDB;
use SP\Core\Crypt\Crypt;
use SP\Core\OldCrypt;
use SP\Core\Crypt\Hash;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountData;
use SP\DataModel\AccountExtData;
use SP\DataModel\CategoryData;
use SP\DataModel\CustomerData;
Expand Down Expand Up @@ -71,7 +73,7 @@ class SyspassImport extends ImportBase
public function doImport()
{
try {
if ($this->ImportParams->getImportMasterPwd() !== ''){
if ($this->ImportParams->getImportMasterPwd() !== '') {
$this->mPassValidHash = Hash::checkHashKey($this->ImportParams->getImportMasterPwd(), ConfigDB::getValue('masterPwd'));
}

Expand Down Expand Up @@ -272,6 +274,7 @@ protected function processAccounts(\DOMElement $Account = null)

$AccountData = new AccountExtData();

/** @var \DOMElement $accountNode */
foreach ($Account->childNodes as $accountNode) {
if (isset($accountNode->tagName)) {
switch ($accountNode->tagName) {
Expand Down Expand Up @@ -299,10 +302,38 @@ protected function processAccounts(\DOMElement $Account = null)
case 'notes';
$AccountData->setAccountNotes($accountNode->nodeValue);
break;
case 'tags':
$tags = $this->processAccountTags($accountNode->childNodes);
}
}
}

$this->addAccount($AccountData);

if (isset($tags) && count($tags)) {
$this->addAccountTags($AccountData, $tags);
}
}

/**
* Procesar las etiquetas de la cuenta
*
* @param \DOMNodeList $nodes
* @return array
*/
protected function processAccountTags(\DOMNodeList $nodes)
{
$tags = [];

if ($nodes->length > 0) {
/** @var \DOMElement $accountTagNode */
foreach ($nodes as $accountTagNode) {
if (isset($accountTagNode->tagName)) {
$tags[] = $accountTagNode->getAttribute('id');
}
}
}

return $tags;
}
}
4 changes: 3 additions & 1 deletion inc/SP/Import/XmlImportTrait.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ protected function getNodesData($nodeName, $childNodeName, $callback, $required
}

return;
} elseif (!is_callable([$this, $callback])) {
}

if (!is_callable([$this, $callback])) {
throw new SPException(SPException::SP_WARNING, __('Método inválido', false));
}

Expand Down
2 changes: 1 addition & 1 deletion inc/SP/Util/Util.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ public static function getAppInfo($index = null)
*/
public static function getVersion($retBuild = false, $normalized = false)
{
$build = 17081804;
$build = 17083101;
$version = [2, 1, 13];

if ($normalized === true) {
Expand Down

0 comments on commit 40da8d0

Please sign in to comment.