* [FIX] Fixed wrong behavior when downloading PDF file from file management

* [MOD] Improved backup and export management. They are now stored in compressed file format, can be downloaded without direct access through the web browser and it keeps tracking when downloaded.
* [MOD] Updated translations
* [ADD] Unit tests

Signed-off-by: nuxsmin <nuxsmin@syspass.org>
This commit is contained in:
nuxsmin
2018-10-28 22:37:57 +01:00
parent 40e7195525
commit 09520d3cc7
83 changed files with 49149 additions and 58627 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -161,6 +161,8 @@ final class AccountFileController extends ControllerBase implements CrudControll
$response->send(true);
} catch (\Exception $e) {
processException($e);
$this->eventDispatcher->notifyEvent('exception', new Event($e));
}
return '';

View File

@@ -34,6 +34,7 @@ use SP\Modules\Web\Controllers\Traits\ConfigTrait;
use SP\Services\Backup\FileBackupService;
use SP\Services\Export\XmlExportService;
use SP\Services\Export\XmlVerifyService;
use SP\Storage\File\FileHandler;
/**
* Class ConfigBackupController
@@ -127,6 +128,9 @@ final class ConfigBackupController extends SimpleControllerBase
)
);
// Create the XML archive after verifying the export integrity
$export->createArchive();
return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Proceso de exportación finalizado'));
} catch (\Exception $e) {
processException($e);
@@ -139,6 +143,132 @@ final class ConfigBackupController extends SimpleControllerBase
/**
* @return bool
* @throws \SP\Core\Exceptions\SPException
*/
public function downloadExportAction()
{
$this->checkSecurityToken($this->previousSk, $this->request);
try {
SessionContext::close();
$filePath = XmlExportService::getExportFilename(BACKUP_PATH, $this->configData->getExportHash(), true);
$file = new FileHandler($filePath);
$file->checkFileExists();
$this->eventDispatcher->notifyEvent('download.exportFile',
new Event($this, EventMessage::factory()
->addDescription(__u('Archivo descargado'))
->addDetail(__u('Archivo'), $file->getFile()))
);
$response = $this->router->response();
$response->header('Cache-Control', 'max-age=60, must-revalidate');
$response->header('Content-length', $file->getFileSize());
$response->header('Content-type', $file->getFileType());
$response->header('Content-Description', ' sysPass file');
$response->header('Content-transfer-encoding', 'chunked');
$response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"');
$response->header('Set-Cookie', 'fileDownload=true; path=/');
$response->send();
$file->readChunked();
} catch (\Exception $e) {
processException($e);
$this->eventDispatcher->notifyEvent('exception', new Event($e));
}
return '';
}
/**
* @return bool
* @throws \SP\Core\Exceptions\SPException
*/
public function downloadBackupAppAction()
{
$this->checkSecurityToken($this->previousSk, $this->request);
try {
SessionContext::close();
$filePath = FileBackupService::getAppBackupFilename(BACKUP_PATH, $this->configData->getBackupHash(), true);
$file = new FileHandler($filePath);
$file->checkFileExists();
$this->eventDispatcher->notifyEvent('download.backupAppFile',
new Event($this, EventMessage::factory()
->addDescription(__u('Archivo descargado'))
->addDetail(__u('Archivo'), $file->getFile()))
);
$response = $this->router->response();
$response->header('Cache-Control', 'max-age=60, must-revalidate');
$response->header('Content-length', $file->getFileSize());
$response->header('Content-type', $file->getFileType());
$response->header('Content-Description', ' sysPass file');
$response->header('Content-transfer-encoding', 'chunked');
$response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"');
$response->header('Set-Cookie', 'fileDownload=true; path=/');
$response->send();
$file->readChunked();
} catch (\Exception $e) {
processException($e);
$this->eventDispatcher->notifyEvent('exception', new Event($e));
}
return '';
}
/**
* @return bool
* @throws \SP\Core\Exceptions\SPException
*/
public function downloadBackupDbAction()
{
$this->checkSecurityToken($this->previousSk, $this->request);
try {
SessionContext::close();
$filePath = FileBackupService::getDbBackupFilename(BACKUP_PATH, $this->configData->getBackupHash(), true);
$file = new FileHandler($filePath);
$file->checkFileExists();
$this->eventDispatcher->notifyEvent('download.backupDbFile',
new Event($this, EventMessage::factory()
->addDescription(__u('Archivo descargado'))
->addDetail(__u('Archivo'), $file->getFile()))
);
$response = $this->router->response();
$response->header('Cache-Control', 'max-age=60, must-revalidate');
$response->header('Content-length', $file->getFileSize());
$response->header('Content-type', $file->getFileType());
$response->header('Content-Description', ' sysPass file');
$response->header('Content-transfer-encoding', 'chunked');
$response->header('Content-Disposition', 'attachment; filename="' . basename($file->getFile()) . '"');
$response->header('Set-Cookie', 'fileDownload=true; path=/');
$response->send();
$file->readChunked();
} catch (\Exception $e) {
processException($e);
$this->eventDispatcher->notifyEvent('exception', new Event($e));
}
return '';
}
/**
* initialize
*/
protected function initialize()
{
@@ -148,7 +278,7 @@ final class ConfigBackupController extends SimpleControllerBase
} catch (UnauthorizedPageException $e) {
$this->eventDispatcher->notifyEvent('exception', new Event($e));
return $this->returnJsonResponseException($e);
$this->returnJsonResponseException($e);
}
}
}

View File

@@ -24,7 +24,6 @@
namespace SP\Modules\Web\Controllers;
use SP\Bootstrap;
use SP\Core\Acl\Acl;
use SP\Core\AppInfoInterface;
use SP\Core\Crypt\CryptSessionHandler;
@@ -37,14 +36,19 @@ use SP\Plugin\PluginManager;
use SP\Providers\Log\LogInterface;
use SP\Providers\Mail\MailHandler;
use SP\Services\Account\AccountService;
use SP\Services\Backup\FileBackupService;
use SP\Services\Config\ConfigService;
use SP\Services\Crypt\TemporaryMasterPassService;
use SP\Services\Export\XmlExportService;
use SP\Services\Task\Task;
use SP\Services\User\UserService;
use SP\Services\UserGroup\UserGroupService;
use SP\Services\UserProfile\UserProfileService;
use SP\Storage\Database\DatabaseUtil;
use SP\Storage\Database\DBStorageInterface;
use SP\Storage\File\FileException;
use SP\Storage\File\FileHandler;
use SP\Util\Util;
/**
* Class ConfigManagerController
@@ -233,6 +237,8 @@ final class ConfigManagerController extends ControllerBase
/**
* @return DataTab
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
* @throws \SP\Repositories\NoSuchItemException
@@ -280,44 +286,31 @@ final class ConfigManagerController extends ControllerBase
$template->assign('pharIsAvailable', $this->extensionChecker->checkPharAvailable());
$template->assign('siteName', AppInfoInterface::APP_NAME);
$template->assign('backupDir', BACKUP_PATH);
$template->assign('backupPath', Bootstrap::$WEBROOT . '/backup');
$backupHash = $this->configData->getBackupHash();
$exportHash = $this->configData->getExportHash();
$backupAppFile = new FileHandler(FileBackupService::getAppBackupFilename(BACKUP_PATH, $this->configData->getBackupHash(), true));
$backupDbFile = new FileHandler(FileBackupService::getDbBackupFilename(BACKUP_PATH, $this->configData->getBackupHash(), true));
$exportFile = new FileHandler(XmlExportService::getExportFilename(BACKUP_PATH, $this->configData->getExportHash(), true));
$backupFile = $template->siteName . '-' . $backupHash . '.tar.gz';
try {
$backupAppFile->checkFileExists();
$backupDbFile->checkFileExists();
$template->assign('backupFile', [
'absolute' => BACKUP_PATH . DIRECTORY_SEPARATOR . $backupFile,
'relative' => $template->backupPath . '/' . $backupFile,
'filename' => $backupFile
]);
$template->assign('hasBackup', true);
$template->assign('lastBackupTime', date('r', $backupAppFile->getFileTime()));
} catch (FileException $e) {
$template->assign('hasBackup', false);
$template->assign('lastBackupTime', __('No se encontraron backups'));
}
$backupDbFile = $template->siteName . '_db-' . $backupHash . '.sql';
try {
$exportFile->checkFileExists();
$template->assign('backupDbFile', [
'absolute' => BACKUP_PATH . DIRECTORY_SEPARATOR . $backupDbFile,
'relative' => $template->backupPath . '/' . $backupDbFile,
'filename' => $backupDbFile
]);
clearstatcache(true, $template->backupFile['absolute']);
clearstatcache(true, $template->backupDbFile['absolute']);
$template->assign('lastBackupTime', file_exists($template->backupFile['absolute']) ? __('Último backup') . ': ' . date('r', filemtime($template->backupFile['absolute'])) : __('No se encontraron backups'));
$exportFile = $template->siteName . '-' . $exportHash . '.xml';
$template->assign('exportFile', [
'absolute' => BACKUP_PATH . DIRECTORY_SEPARATOR . $exportFile,
'relative' => $template->backupPath . '/' . $exportFile,
'filename' => $exportFile
]);
clearstatcache(true, $template->exportFile['absolute']);
$template->assign('lastExportTime', file_exists($template->exportFile['absolute']) ? __('Última exportación') . ': ' . date('r', filemtime($template->exportFile['absolute'])) : __('No se encontró archivo de exportación'));
$template->assign('hasExport', true);
$template->assign('lastExportTime', date('r', $exportFile->getFileTime()));
} catch (FileException $e) {
$template->assign('hasExport', false);
$template->assign('lastExportTime', __('No se encontró archivo de exportación'));
}
return new DataTab(__('Copia de Seguridad'), $template);
}
@@ -341,6 +334,8 @@ final class ConfigManagerController extends ControllerBase
/**
* @return DataTab
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
* @throws \SP\Repositories\NoSuchItemException
* @throws \SP\Services\ServiceException
*/
@@ -357,6 +352,7 @@ final class ConfigManagerController extends ControllerBase
$template->assign('locale', Language::$localeStatus ?: sprintf('%s (%s)', $this->configData->getSiteLang(), __('No instalado')));
$template->assign('securedSession', CryptSessionHandler::$isSecured);
$template->assign('missingExtensions', $this->extensionChecker->getMissing());
$template->assign('downloadRate', round(Util::getMaxDownloadChunk() / 1024 / 1024));
return new DataTab(__('Información'), $template);
}

View File

@@ -124,29 +124,28 @@ final class EventlogGrid extends GridBase
$gridData->addDataRowSource('login');
$gridData->addDataRowSource('ipAddress', false,
function ($value) use ($isDemoMode) {
return $isDemoMode ? preg_replace('#\d+#', '*', $value) : $value;
return $isDemoMode ? '*.*.*.*' : $value;
});
$gridData->addDataRowSource('description', false,
function ($value) use ($isDemoMode) {
if ($isDemoMode) {
$value = preg_replace('/\\d+\\.\\d+\\.\\d+\\.\\d+/', "*.*.*.*", $value);
$value = preg_replace('/\d+\.\d+\.\d+\.\d+/', '*.*.*.*', $value);
}
$text = str_replace(';;', PHP_EOL, $value);
if (preg_match('/^SQL.*/m', $text)) {
$text = preg_replace([
if (preg_match('/^SQL.*/m', $value)) {
$value = preg_replace([
'/([a-zA-Z_]+),/m',
'/(UPDATE|DELETE|TRUNCATE|INSERT|SELECT|WHERE|LEFT|ORDER|LIMIT|FROM)/m'],
['\\1,<br>', '<br>\\1'],
$text);
$value);
}
// if (strlen($text) >= 100) {
// $text = wordwrap($text, 100, PHP_EOL, true);
// }
return str_replace(PHP_EOL, '<br>', $text);
return wordwrap(
str_replace([';;', PHP_EOL], '<br>', $value),
100,
'<br>',
true
);
}, false);
$gridData->setData($this->queryResult);

View File

@@ -162,6 +162,7 @@ final class FileGrid extends GridBase
$gridAction->setIcon($this->icons->getIconView());
$gridAction->setOnClickFunction('file/view');
$gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_VIEW));
$gridAction->setFilterRowSource('type', 'application/pdf');
return $gridAction;
}
@@ -179,6 +180,9 @@ final class FileGrid extends GridBase
$gridAction->setIcon($this->icons->getIconDownload());
$gridAction->setOnClickFunction('file/download');
$gridAction->addData('action-route', Acl::getActionRoute(ActionsInterface::ACCOUNT_FILE_DOWNLOAD));
$gridAction->setRuntimeData(function ($dataItem) use ($gridAction) {
return ['item-type' => $dataItem->type];
});
return $gridAction;
}

View File

@@ -37,7 +37,7 @@ use SP\Html\DataGrid\Action\DataGridAction;
use SP\Http\Uri;
use SP\Plugin\PluginManager;
use SP\Services\Install\Installer;
use SP\Util\Version;
use SP\Util\VersionUtil;
/**
* Class LayoutHelper
@@ -134,7 +134,7 @@ final class LayoutHelper extends HelperBase
*/
protected function getResourcesLinks()
{
$version = Version::getVersionStringNormalized();
$version = VersionUtil::getVersionStringNormalized();
$jsUri = new Uri(Bootstrap::$WEBURI . '/index.php');
$jsUri->addParam('_r', 'resource/js');

View File

@@ -40,7 +40,7 @@ use SP\Mvc\Controller\CrudControllerInterface;
use SP\Mvc\View\Components\SelectItemAdapter;
use SP\Services\Account\AccountService;
use SP\Services\PublicLink\PublicLinkService;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class PublicLinkController
@@ -314,7 +314,7 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
$publicLinkData->setTypeId(PublicLinkService::TYPE_ACCOUNT);
$publicLinkData->setItemId($accountId);
$publicLinkData->setNotify((bool)$notify);
$publicLinkData->setHash(Util::generateRandomBytes());
$publicLinkData->setHash(PasswordUtil::generateRandomBytes());
$this->publicLinkService->create($publicLinkData);

View File

@@ -30,7 +30,7 @@ use SP\Core\AppInfoInterface;
use SP\Core\Exceptions\CheckException;
use SP\Http\JsonResponse;
use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Util\Version;
use SP\Util\VersionUtil;
/**
* Class StatusController
@@ -73,7 +73,7 @@ final class StatusController extends SimpleControllerBase
if (preg_match('/v?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.(?P<build>\d+)(?P<pre_release>\-[a-z0-9\.]+)?$/', $requestData->tag_name, $matches)) {
$pubVersion = $matches['major'] . $matches['minor'] . $matches['patch'] . '.' . $matches['build'];
if (Version::checkVersion(Version::getVersionStringNormalized(), $pubVersion)) {
if (VersionUtil::checkVersion(VersionUtil::getVersionStringNormalized(), $pubVersion)) {
return $this->returnJsonResponseData([
'version' => $requestData->tag_name,
'url' => $requestData->html_url,

View File

@@ -35,10 +35,7 @@
<?php echo $_getvar('lastBackupTime'); ?>
</td>
</tr>
<?php if ($_getvar('ctx_userIsAdminApp')):
$backupFile = $_getvar('backupFile');
$backupDbFile = $_getvar('backupDbFile');
?>
<?php if ($_getvar('ctx_userIsAdminApp')): ?>
<tr>
<td class="descField">
<?php echo __('Descargar Actual'); ?>
@@ -46,21 +43,22 @@
<td class="valField">
<div class="lowres-title"><?php echo __('Descargar Actual'); ?></div>
<?php if (file_exists($backupFile['absolute']) && file_exists($backupDbFile['absolute'])): ?>
<a href="<?php echo $backupDbFile['relative']; ?>"
download="<?php echo $backupDbFile['filename']; ?>" class="download">
<?php if ($_getvar('hasBackup')): ?>
<a href="<?php echo $_getRoute('configBackup/downloadBackupDb'); ?>"
class="download" target="_blank">
<button type="button" class="mdl-button mdl-js-button">
<?php echo __('Copia BBDD'); ?>
</button>
</a>
<a href="<?php echo $backupFile['relative']; ?>"
download="<?php echo $backupFile['filename']; ?>" class="download">
<a href="<?php echo $_getRoute('configBackup/downloadBackupApp'); ?>"
class="download" target="_blank">
<button type="button" class="mdl-button mdl-js-button">
<?php echo __('Copia sysPass'); ?>
</button>
</a>
<?php else: echo __('No hay backups para descargar'); ?>
<?php else: echo __('No se encontraron backups'); ?>
<?php endif; ?>
</td>
</tr>
@@ -116,9 +114,7 @@
<?php echo $_getvar('lastExportTime'); ?>
</td>
</tr>
<?php if ($_getvar('ctx_userIsAdminApp')):
$exportFile = $_getvar('exportFile');
?>
<?php if ($_getvar('ctx_userIsAdminApp')): ?>
<tr>
<td class="descField">
<?php echo __('Descargar Actual'); ?>
@@ -126,15 +122,14 @@
<td class="valField">
<div class="lowres-title"><?php echo __('Descargar Actual'); ?></div>
<?php if (file_exists($exportFile['absolute'])): ?>
<a href="<?php echo $exportFile['relative']; ?>"
download="<?php echo $exportFile['filename']; ?>"
class="download">
<?php if ($_getvar('hasExport')): ?>
<a href="<?php echo $_getRoute('configBackup/downloadExport'); ?>"
class="download" target="_blank">
<button type="button" class="mdl-button mdl-js-button">
XML <?php echo $_getvar('siteName'); ?>
</button>
</a>
<?php else: echo __('No hay archivos XML para descargar'); ?>
<?php else: echo __('No se encontró archivo de exportación'); ?>
<?php endif; ?>
</td>
</tr>

View File

@@ -9,7 +9,7 @@
<div id="title" class="titleNormal">
<i class="material-icons">info</i>
<?php use SP\Util\Version;
<?php use SP\Util\VersionUtil;
echo __('Información de la Aplicación'); ?>
</div>
@@ -22,7 +22,7 @@
<td class="valField">
<div class="lowres-title"><?php echo __('Versión sysPass'); ?></div>
<?php printf('%s (%s)', \SP\Services\Install\Installer::VERSION_TEXT, \SP\Html\Html::strongText(Version::getVersionStringNormalized())); ?>
<?php printf('%s (%s)', \SP\Services\Install\Installer::VERSION_TEXT, \SP\Html\Html::strongText(VersionUtil::getVersionStringNormalized())); ?>
</td>
</tr>
<tr>
@@ -59,6 +59,8 @@
<?php printf('%s: %d KB', \SP\Html\Html::strongText(__('Memoria Usada')), (memory_get_usage(true) / 1024)); ?>
<br>
<?php printf('%s: %s', \SP\Html\Html::strongText(__('Usuario')), (!$_getvar('isDemo')) ? get_current_user() : '***'); ?>
<br>
<?php printf('%s: %d MB/s', \SP\Html\Html::strongText(__('Tasa de descarga')), $_getvar('downloadRate')); ?>
<?php if (function_exists('opcache_get_status') && version_compare(PHP_VERSION, '5.6.0', '>=')): ?>
<br>
<?php echo \SP\Html\Html::strongText(__('OP Cache')); ?>

View File

@@ -15,20 +15,28 @@ if (!isset($data)) {
<!-- Rows -->
<?php if ($data->getData()->getDataCount() > 0):
$numFields = count($data->getData()->getDataRowSources());
foreach ($data->getData()->getData() as $dataIndex => $dataItem): ?>
<tr data-item-id="<?php echo $dataItem->{$data->getData()->getDataRowSourceId()}; ?>">
foreach ($data->getData()->getData() as $dataIndex => $dataItem):
$itemId = $dataItem->{$data->getData()->getDataRowSourceId()};
?>
<tr data-item-id="<?php echo $itemId; ?>">
<?php foreach ($data->getData()->getDataRowSources() as $rowSrc): ?>
<?php
if ($rowSrc['isMethod'] === true && method_exists($dataItem, $rowSrc['name'])):
if ($rowSrc['isMethod'] === true
&& method_exists($dataItem, $rowSrc['name'])
):
$value = $dataItem->{$rowSrc['name']}();
else:
$value = $dataItem->{$rowSrc['name']};
endif;
$value = $rowSrc['filter'] !== null ? $rowSrc['filter']($value) : $value;
if ($rowSrc['filter'] !== null):
$value = $rowSrc['filter']($value);
endif;
if ($value !== ''):
$value = $rowSrc['truncate'] === true ? Html::truncate($value, 150 / $numFields) : $value;
if ($rowSrc['truncate'] === true):
$value = Html::truncate($value, 150 / $numFields);
endif;
else:
$value = '&nbsp;';
endif;
@@ -36,9 +44,12 @@ if (!isset($data)) {
<td class="cell-data"><?php echo $value; ?></td>
<?php endforeach; ?>
<?php if (count($data->getData()->getDataRowSourcesWithIcon()) > 0): ?>
<?php
$rowIcons = $data->getData()->getDataRowSourcesWithIcon();
if (count($rowIcons) > 0): ?>
<td class="cell-nodata">
<?php foreach ($data->getData()->getDataRowSourcesWithIcon() as $rowSrcIcon): ?>
<?php foreach ($rowIcons as $rowSrcIcon): ?>
<?php if ($dataItem->{$rowSrcIcon['field']} == $rowSrcIcon['value']): ?>
<i class="material-icons <?php echo $rowSrcIcon['icon']->getClass(); ?>"
title="<?php echo $rowSrcIcon['icon']->getTitle(); ?>"><?php echo $rowSrcIcon['icon']->getIcon(); ?></i>
@@ -52,25 +63,33 @@ if (!isset($data)) {
<div>
<?php foreach ($data->getDataActions() as $action):
if (!$action->isSkip()):
$actionUid = uniqid('btn-action-', true);
$filter = $action->getFilterRowSource();
if ($filter !== null) {
if ($filter !== null):
/** @var array $filter */
foreach ($filter as $f) {
if ($dataItem->{$f['field']} == $f['value']) {
foreach ($filter as $f):
if ($dataItem->{$f['field']} == $f['value']):
continue 2;
}
}
}
endif;
endforeach;
endif;
if ($action->getRuntimeData() !== null) :
$nodeData = array_merge($action->getData(), $action->getRuntimeData()($dataItem));
else:
$nodeData = $action->getData();
endif;
?>
<i id="btn-action-<?php echo $dataItem->{$data->getData()->getDataRowSourceId()}, '-', $action->getId(); ?>"
<i id="<?php echo $actionUid; ?>"
class="btn-action material-icons <?php echo $action->getIcon()->getClass(); ?>"
data-item-id="<?php echo $dataItem->{$data->getData()->getDataRowSourceId()}; ?>"
data-item-id="<?php echo $itemId; ?>"
data-onclick="<?php echo $action->getOnClick(); ?>"
<?php foreach ($action->getData() as $dataName => $dataValue): echo 'data-', $dataName, '=', '"', $dataValue, '"'; endforeach; ?>
><?php echo $action->getIcon()->getIcon(); ?></i>
<?php foreach ($nodeData as $dataName => $dataValue):
echo 'data-', $dataName, '=', '"', $dataValue, '"';
endforeach; ?>><?php echo $action->getIcon()->getIcon(); ?></i>
<span
for="btn-action-<?php echo $dataItem->{$data->getData()->getDataRowSourceId()}, '-', $action->getId(); ?>"
for="<?php echo $actionUid; ?>"
class="mdl-tooltip mdl-tooltip--top"><?php echo $action->getTitle(); ?></span>
<?php endif; ?>
<?php endforeach; ?>

View File

@@ -9,7 +9,7 @@
<main class="mdl-layout__content">
<div id="actions" class="upgrade">
<div id="page-title">
<h1><?php use SP\Util\Version;
<h1><?php use SP\Util\VersionUtil;
printf(__('Actualización %s'), $_getvar('upgradeVersion')); ?></h1>
</div>
@@ -37,7 +37,7 @@
<?php echo __('Este código se encuentra en el archivo de configuración de sysPass con la etiqueta "upgradeKey"'); ?>
</div>
<?php if (Version::checkVersion($_getvar('version'), '130.16011001')
<?php if (VersionUtil::checkVersion($_getvar('version'), '130.16011001')
&& count($_getvar('constraints')) > 0):
?>
<div>
@@ -120,7 +120,7 @@
<?php endif; ?>
<?php endif; ?>
<?php if (Version::checkVersion($_getvar('version'), '210.17022601')): ?>
<?php if (VersionUtil::checkVersion($_getvar('version'), '210.17022601')): ?>
<div>
<ul class="errors">
<li class="msg-warning">

View File

@@ -33,7 +33,8 @@
"ext-dom": "*",
"ext-gd": "*",
"ext-json": "*",
"ext-gettext": "*"
"ext-gettext": "*",
"ext-fileinfo": "*"
},
"require-dev": {
"phpunit/phpunit": "^6",

View File

@@ -47,7 +47,7 @@ use SP\Services\Upgrade\UpgradeConfigService;
use SP\Services\Upgrade\UpgradeUtil;
use SP\Util\Checks;
use SP\Util\Filter;
use SP\Util\Version;
use SP\Util\VersionUtil;
use Symfony\Component\Debug\Debug;
defined('APP_ROOT') || die();
@@ -408,7 +408,7 @@ final class Bootstrap
{
if (file_exists(OLD_CONFIG_FILE)) {
$upgradeConfigService = self::$container->get(UpgradeConfigService::class);
$upgradeConfigService->upgradeOldConfigFile(Version::getVersionStringNormalized());
$upgradeConfigService->upgradeOldConfigFile(VersionUtil::getVersionStringNormalized());
}
$configVersion = UpgradeUtil::fixVersionNumber($this->configData->getConfigVersion());

View File

@@ -32,7 +32,7 @@ use SP\Core\Exceptions\ConfigException;
use SP\Services\Config\ConfigBackupService;
use SP\Storage\File\FileException;
use SP\Storage\File\XmlFileStorageInterface;
use SP\Util\Util;
use SP\Util\PasswordUtil;
defined('APP_ROOT') || die();
@@ -244,7 +244,7 @@ final class Config
if (empty($this->configData->getUpgradeKey())) {
logger('Generating upgrade key');
return $this->saveConfig($this->configData->setUpgradeKey(Util::generateRandomBytes(16)), false);
return $this->saveConfig($this->configData->setUpgradeKey(PasswordUtil::generateRandomBytes(16)), false);
}
return $this;

View File

@@ -36,88 +36,98 @@ defined('APP_ROOT') || die();
abstract class DataGridActionBase implements DataGridActionInterface
{
/**
* El objeto reflexivo que determina si se muestra la acción
* The runtime function that determines if the action should be displayed
*
* @var callable
*/
protected $runtimeFilter;
/**
* El nombre de la acción
* The runtime function to pass in the row dato to the action
*
* @var callable
*/
protected $runtimeData;
/**
* Action's name
*
* @var string
*/
protected $name = '';
/**
* El título de la acción
* Action's title
*
* @var string
*/
protected $title = '';
/**
* El id de la acción
* Action's title ID
*
* @var int
*/
protected $id = 0;
/**
* La función javascript del evento OnClick
* The JavaScript function to be triggered on OnClick event
*
* @var string
*/
protected $onClickFunction = '';
/**
* Los argumentos de la función OnClick
* The OnClick event arguments
*
* @var array
*/
protected $onClickArgs;
/**
* El icono de la acción
* Action's icon
*
* @var IconInterface
*/
protected $icon;
/**
* Si se debe de omitir para los elementos del listado
* Sets whether this action should be skipped from listing in rows
*
* @var bool
*/
protected $isSkip = false;
/**
* La columna de origen de datos que condiciona esta acción
* The row name which determines whether the action is displayed
*
* @var array
*/
protected $filterRowSource;
/**
* Si es una acción de ayuda
* Sets as a help action
*
* @var bool
*/
protected $isHelper;
/**
* El tipo de acción
* Action's type
*
* @var int
*/
protected $type = 0;
/**
* Atributos de datos adicionales
* Data attributes (ie. data-*)
*
* @var array
*/
protected $data;
/**
* Atributos adicionales
* Additional attributes (ie. name=*)
*
* @var array
*/
protected $attributes;
/**
* CSS classes
*
* @var array
*/
protected $classes;
/**
* Sets as a selection action, that is, to be displayed on a selection menu
*
* @var bool
*/
protected $isSelection = false;
@@ -531,4 +541,26 @@ abstract class DataGridActionBase implements DataGridActionInterface
return $this;
}
/**
* @return callable
*/
public function getRuntimeData()
{
return $this->runtimeData;
}
/**
* Sets the runtime data function
*
* @param callable $function
*
* @return $this
*/
public function setRuntimeData(callable $function)
{
$this->runtimeData = $function;
return $this;
}
}

View File

@@ -228,4 +228,11 @@ interface DataGridActionInterface
* @return bool
*/
public function isSelection(): bool;
/**
* Returns the runtime function to pass in the row dato to the action
*
* @return callable
*/
public function getRuntimeData();
}

View File

@@ -87,8 +87,6 @@ interface DataGridDataInterface
* @param $source string
* @param $icon IconInterface
* @param mixed $value Valor para mostrar el icono
*
* @return
*/
public function addDataRowSourceWithIcon($source, IconInterface $icon, $value = 1);

View File

@@ -26,6 +26,7 @@ namespace SP\Mvc\View;
defined('APP_ROOT') || die();
use SP\Bootstrap;
use SP\Core\Exceptions\FileNotFoundException;
use SP\Core\UI\Theme;
use SP\Core\UI\ThemeInterface;
@@ -368,6 +369,10 @@ final class Template
return $this->vars->get($key, $default);
};
$_getRoute = function ($path) use ($sk) {
return Bootstrap::$WEBURI . '/index.php?r=' . $path . '&sk=' . $sk;
};
ob_start();
// Añadimos las plantillas

View File

@@ -51,7 +51,7 @@ use SP\Services\User\UserPassService;
use SP\Services\User\UserService;
use SP\Services\UserPassRecover\UserPassRecoverService;
use SP\Services\UserProfile\UserProfileService;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class LoginService
@@ -238,7 +238,7 @@ final class LoginService extends Service
->addDetail(__u('Usuario'), $userLoginResponse->getLogin()))
);
$hash = Util::generateRandomBytes(16);
$hash = PasswordUtil::generateRandomBytes(16);
$this->dic->get(UserPassRecoverService::class)->add($userLoginResponse->getId(), $hash);

View File

@@ -37,7 +37,7 @@ use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Services\ServiceItemTrait;
use SP\Storage\Database\QueryResult;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class AuthTokenService
@@ -216,7 +216,7 @@ final class AuthTokenService extends Service
*/
private function generateToken()
{
return Util::generateRandomBytes(32);
return PasswordUtil::generateRandomBytes(32);
}
/**

View File

@@ -35,6 +35,7 @@ use SP\Services\ServiceException;
use SP\Storage\Database\Database;
use SP\Storage\Database\DatabaseUtil;
use SP\Storage\Database\QueryData;
use SP\Storage\File\ArchiveHandler;
use SP\Storage\File\FileHandler;
use SP\Util\Checks;
@@ -65,7 +66,10 @@ final class FileBackupService extends Service
* @var PhpExtensionChecker
*/
private $extensionChecker;
/**
* @var string
*/
private $hash;
/**
* Realizar backup de la BBDD y aplicación.
@@ -81,10 +85,10 @@ final class FileBackupService extends Service
$this->checkBackupDir();
// Generar hash unico para evitar descargas no permitidas
$backupUniqueHash = sha1(uniqid('sysPassBackup', true));
$this->hash = sha1(uniqid('sysPassBackup', true));
$this->backupFileApp = $this->path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '-' . $backupUniqueHash . '.tar';
$this->backupFileDb = $this->path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_db-' . $backupUniqueHash . '.sql';
$this->backupFileApp = self::getAppBackupFilename($path, $this->hash);
$this->backupFileDb = self::getDbBackupFilename($path, $this->hash);
try {
$this->deleteOldBackups();
@@ -93,15 +97,15 @@ final class FileBackupService extends Service
new Event($this,
EventMessage::factory()->addDescription(__u('Realizar Backup'))));
$this->backupTables('*', new FileHandler($this->backupFileDb));
$this->backupTables(new FileHandler($this->backupFileDb), '*');
if (!$this->backupApp($this->backupFileApp)
&& !$this->backupAppLegacyLinux($this->backupFileApp)
if (!$this->backupApp()
&& !$this->backupAppLegacyLinux()
) {
throw new ServiceException(__u('Error al realizar backup en modo compatibilidad'));
}
$this->configData->setBackupHash($backupUniqueHash);
$this->configData->setBackupHash($this->hash);
$this->config->saveConfig($this->configData);
} catch (ServiceException $e) {
throw $e;
@@ -141,12 +145,48 @@ final class FileBackupService extends Service
return true;
}
/**
* @param string $path
* @param string $hash
* @param bool $compressed
*
* @return string
*/
public static function getAppBackupFilename(string $path, string $hash, bool $compressed = false)
{
$file = $path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_app-' . $hash;
if ($compressed) {
return $file . ArchiveHandler::COMPRESS_EXTENSION;
}
return $file;
}
/**
* @param string $path
* @param string $hash
* @param bool $compressed
*
* @return string
*/
public static function getDbBackupFilename(string $path, string $hash, bool $compressed = false)
{
$file = $path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_db-' . $hash;
if ($compressed) {
return $file . ArchiveHandler::COMPRESS_EXTENSION;
}
return $file . '.sql';
}
/**
* Eliminar las copias de seguridad anteriores
*/
private function deleteOldBackups()
{
array_map('unlink', glob($this->path . DIRECTORY_SEPARATOR . '*.tar.gz'));
array_map('unlink', glob($this->path . DIRECTORY_SEPARATOR . '*' . ArchiveHandler::COMPRESS_EXTENSION));
array_map('unlink', glob($this->path . DIRECTORY_SEPARATOR . '*.sql'));
}
@@ -154,13 +194,15 @@ final class FileBackupService extends Service
* Backup de las tablas de la BBDD.
* Utilizar '*' para toda la BBDD o 'table1 table2 table3...'
*
* @param string|array $tables
* @param \SP\Storage\File\FileHandler $fileHandler
* @param string|array $tables
*
* @throws \Exception
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
* @throws \SP\Storage\File\FileException
* @throws \SP\Core\Exceptions\CheckException
*/
private function backupTables($tables = '*', FileHandler $fileHandler)
private function backupTables(FileHandler $fileHandler, $tables = '*')
{
$this->eventDispatcher->notifyEvent('run.backup.process',
new Event($this,
@@ -277,56 +319,40 @@ final class FileBackupService extends Service
$fileHandler->write($sqlOut);
$fileHandler->close();
$archive = new ArchiveHandler($fileHandler->getFile(), $this->extensionChecker);
$archive->compressFile($fileHandler->getFile());
$fileHandler->delete();
}
/**
* Realizar un backup de la aplicación y comprimirlo.
*
* @param string $backupFile nombre del archivo de backup
*
* @return bool
* @throws \SP\Core\Exceptions\CheckException
* @throws \SP\Storage\File\FileException
*/
private function backupApp($backupFile)
private function backupApp()
{
if (!$this->extensionChecker->checkPharAvailable()) {
$this->eventDispatcher->notifyEvent('error',
new Event($this, EventMessage::factory()
->addDescription(sprintf(__('La extensión \'%s\' no está disponible'), 'phar')))
);
return false;
}
$this->eventDispatcher->notifyEvent('run.backup.process',
new Event($this, EventMessage::factory()
->addDescription(__u('Copiando aplicación')))
);
$compressedFile = $backupFile . '.gz';
$archive = new ArchiveHandler($this->backupFileApp, $this->extensionChecker);
$archive->compressDirectory(APP_ROOT, '#^(?!(.*backup))(.*)$#i');
if (file_exists($compressedFile)) {
unlink($compressedFile);
}
$archive = new \PharData($backupFile);
$archive->buildFromDirectory(APP_ROOT, '/^(?!backup).*$/i');
$archive->compress(\Phar::GZ);
unlink($backupFile);
return file_exists($compressedFile);
return true;
}
/**
* Realizar un backup de la aplicación y comprimirlo usando aplicaciones del SO Linux.
*
* @param string $backupFile nombre del archivo de backup
*
* @return int Con el código de salida del comando ejecutado
* @throws ServiceException
*/
private function backupAppLegacyLinux($backupFile)
private function backupAppLegacyLinux()
{
if (Checks::checkIsWindows()) {
throw new ServiceException(
@@ -338,9 +364,7 @@ final class FileBackupService extends Service
->addDescription(__u('Copiando aplicación')))
);
$compressedFile = $backupFile . '.gz';
$command = 'tar czf ' . $compressedFile . ' ' . BASE_PATH . ' --exclude "' . $this->path . '" 2>&1';
$command = 'tar czf ' . $this->backupFileApp . ArchiveHandler::COMPRESS_EXTENSION . ' ' . BASE_PATH . ' --exclude "' . $this->path . '" 2>&1';
exec($command, $resOut, $resBakApp);
return $resBakApp;
@@ -349,17 +373,9 @@ final class FileBackupService extends Service
/**
* @return string
*/
public function getBackupFileApp(): string
public function getHash(): string
{
return $this->backupFileApp;
}
/**
* @return string
*/
public function getBackupFileDb(): string
{
return $this->backupFileDb;
return $this->hash;
}
/**

View File

@@ -37,7 +37,7 @@ use SP\Services\Mail\MailService;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Services\User\UserService;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class TemporaryMasterPassService
@@ -82,7 +82,7 @@ final class TemporaryMasterPassService extends Service
$this->maxTime = time() + $maxTime;
// Encriptar la clave maestra con hash aleatorio generado
$randomKey = Util::generateRandomBytes(32);
$randomKey = PasswordUtil::generateRandomBytes(32);
$secureKey = Crypt::makeSecuredKey($randomKey);
$configRequest = new ConfigRequest();

View File

@@ -33,6 +33,7 @@ use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Hash;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Core\PhpExtensionChecker;
use SP\DataModel\CategoryData;
use SP\Services\Account\AccountService;
use SP\Services\Account\AccountToTagService;
@@ -41,7 +42,9 @@ use SP\Services\Client\ClientService;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Services\Tag\TagService;
use SP\Util\Version;
use SP\Storage\File\ArchiveHandler;
use SP\Storage\File\FileHandler;
use SP\Util\VersionUtil;
defined('APP_ROOT') || die();
@@ -55,7 +58,11 @@ final class XmlExportService extends Service
/**
* @var ConfigData
*/
protected $configData;
private $configData;
/**
* @var
*/
private $extensionChecker;
/**
* @var \DOMDocument
*/
@@ -110,7 +117,9 @@ final class XmlExportService extends Service
*/
private function setExportPath(string $exportPath)
{
if (!is_dir($exportPath) && @mkdir($exportPath, 0700, true) === false) {
if (!is_dir($exportPath)
&& @mkdir($exportPath, 0700, true) === false
) {
throw new ServiceException(sprintf(__('No es posible crear el directorio (%s)'), $exportPath));
}
@@ -125,11 +134,29 @@ final class XmlExportService extends Service
private function generateExportFilename(): string
{
// Generar hash unico para evitar descargas no permitidas
$exportUniqueHash = sha1(uniqid('sysPassExport', true));
$this->configData->setExportHash($exportUniqueHash);
$hash = sha1(uniqid('sysPassExport', true));
$this->configData->setExportHash($hash);
$this->config->saveConfig($this->configData);
return $this->exportPath . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '-' . $exportUniqueHash . '.xml';
return self::getExportFilename($this->exportPath, $hash);
}
/**
* @param string $path
* @param string $hash
* @param bool $compressed
*
* @return string
*/
public static function getExportFilename(string $path, string $hash, bool $compressed = false)
{
$file = $path . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME . '_export-' . $hash;
if ($compressed) {
return $file . ArchiveHandler::COMPRESS_EXTENSION;
}
return $file . '.xml';
}
/**
@@ -137,7 +164,11 @@ final class XmlExportService extends Service
*/
private function deleteOldExports()
{
array_map('unlink', glob($this->exportPath . DIRECTORY_SEPARATOR . '*.xml'));
$path = $this->exportPath . DIRECTORY_SEPARATOR . AppInfoInterface::APP_NAME;
array_map(function ($file) {
return @unlink($file);
}, array_merge(glob($path . '_export-*'), glob($path . '*.xml')));
}
/**
@@ -198,7 +229,7 @@ final class XmlExportService extends Service
$nodeMeta = $this->xml->createElement('Meta');
$metaGenerator = $this->xml->createElement('Generator', 'sysPass');
$metaVersion = $this->xml->createElement('Version', Version::getVersionStringNormalized());
$metaVersion = $this->xml->createElement('Version', VersionUtil::getVersionStringNormalized());
$metaTime = $this->xml->createElement('Time', time());
$metaUser = $this->xml->createElement('User', $userData->getLogin());
$metaUser->setAttribute('id', $userData->getId());
@@ -549,6 +580,19 @@ final class XmlExportService extends Service
}
}
/**
* @throws \SP\Core\Exceptions\CheckException
* @throws \SP\Storage\File\FileException
*/
public function createArchive()
{
$archive = new ArchiveHandler($this->exportFile, $this->extensionChecker);
$archive->compressFile($this->exportFile);
$file = new FileHandler($this->exportFile);
$file->delete();
}
/**
* @return string
*/
@@ -571,6 +615,7 @@ final class XmlExportService extends Service
*/
protected function initialize()
{
$this->extensionChecker = $this->dic->get(PhpExtensionChecker::class);
$this->configData = $this->config->getConfigData();
$this->xml = new \DOMDocument('1.0', 'UTF-8');
}

View File

@@ -42,8 +42,8 @@ use SP\Services\UserGroup\UserGroupService;
use SP\Services\UserProfile\UserProfileService;
use SP\Storage\Database\Database;
use SP\Storage\Database\DBStorageInterface;
use SP\Util\Util;
use SP\Util\Version;
use SP\Util\PasswordUtil;
use SP\Util\VersionUtil;
defined('APP_ROOT') || die();
@@ -57,7 +57,7 @@ final class Installer extends Service
*/
const VERSION = [3, 0, 0];
const VERSION_TEXT = '3.0-beta';
const BUILD = 18102401;
const BUILD = 18102801;
/**
* @var DatabaseSetupInterface
@@ -185,7 +185,7 @@ final class Installer extends Service
$this->saveMasterPassword();
$this->createAdminAccount();
$version = Version::getVersionStringNormalized();
$version = VersionUtil::getVersionStringNormalized();
$this->dic->get(ConfigService::class)
->create(new \SP\DataModel\ConfigData('version', $version));
@@ -235,11 +235,11 @@ final class Installer extends Service
private function setupConfig()
{
// Generate a random salt that is used to salt the local user passwords
$this->configData->setPasswordSalt(Util::generateRandomBytes(30));
$this->configData->setPasswordSalt(PasswordUtil::generateRandomBytes(30));
// Sets version and remove upgrade key
$this->configData->setConfigVersion(Version::getVersionStringNormalized());
$this->configData->setDatabaseVersion(Version::getVersionStringNormalized());
$this->configData->setConfigVersion(VersionUtil::getVersionStringNormalized());
$this->configData->setDatabaseVersion(VersionUtil::getVersionStringNormalized());
$this->configData->setUpgradeKey(null);
// Set DB connection info

View File

@@ -34,7 +34,7 @@ use SP\Storage\Database\MySQLFileParser;
use SP\Storage\Database\MySQLHandler;
use SP\Storage\File\FileException;
use SP\Storage\File\FileHandler;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class MySQL
@@ -111,7 +111,7 @@ final class MySQL implements DatabaseSetupInterface
public function setupDbUser()
{
$user = substr(uniqid('sp_'), 0, 16);
$pass = Util::randomPassword();
$pass = PasswordUtil::randomPassword();
try {
// Comprobar si el usuario proporcionado existe

View File

@@ -24,7 +24,7 @@
namespace SP\Services\PublicLink;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class PublicLinkKey
@@ -55,7 +55,7 @@ final class PublicLinkKey
$this->salt = $salt;
if ($hash === null) {
$this->hash = Util::generateRandomBytes();
$this->hash = PasswordUtil::generateRandomBytes();
} else {
$this->hash = $hash;
}

View File

@@ -28,7 +28,7 @@ use SP\Config\ConfigData;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Services\Service;
use SP\Util\Version;
use SP\Util\VersionUtil;
/**
* Class UpgradeAppService
@@ -46,7 +46,7 @@ final class UpgradeAppService extends Service implements UpgradeInterface
*/
public static function needsUpgrade($version)
{
return Version::checkVersion($version, self::UPGRADES);
return VersionUtil::checkVersion($version, self::UPGRADES);
}
/**
@@ -64,7 +64,7 @@ final class UpgradeAppService extends Service implements UpgradeInterface
);
foreach (self::UPGRADES as $appVersion) {
if (Version::checkVersion($version, $appVersion)) {
if (VersionUtil::checkVersion($version, $appVersion)) {
if ($this->applyUpgrade($appVersion) === false) {
throw new UpgradeException(
__u('Error al aplicar la actualización de la aplicación'),

View File

@@ -28,7 +28,7 @@ use SP\Config\ConfigData;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Services\Service;
use SP\Util\Version;
use SP\Util\VersionUtil;
/**
* Class UpgradeService
@@ -53,7 +53,7 @@ final class UpgradeConfigService extends Service implements UpgradeInterface
*/
public static function needsUpgrade($version)
{
return Version::checkVersion(Version::checkVersion($version, Version::getVersionArrayNormalized()), self::UPGRADES);
return VersionUtil::checkVersion(VersionUtil::checkVersion($version, VersionUtil::getVersionArrayNormalized()), self::UPGRADES);
}
/**
@@ -203,7 +203,7 @@ final class UpgradeConfigService extends Service implements UpgradeInterface
$this->eventDispatcher->notifyEvent('upgrade.config.start', new Event($this, $message));
foreach (self::UPGRADES as $upgradeVersion) {
if (Version::checkVersion($version, $upgradeVersion)) {
if (VersionUtil::checkVersion($version, $upgradeVersion)) {
$this->applyUpgrade($upgradeVersion);
}
}

View File

@@ -32,7 +32,7 @@ use SP\Storage\Database\Database;
use SP\Storage\Database\MySQLFileParser;
use SP\Storage\File\FileException;
use SP\Storage\File\FileHandler;
use SP\Util\Version;
use SP\Util\VersionUtil;
/**
* Class UpgradeDatabaseService
@@ -69,7 +69,7 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface
*/
public static function needsUpgrade($version)
{
return empty($version) || Version::checkVersion($version, self::UPGRADES);
return empty($version) || VersionUtil::checkVersion($version, self::UPGRADES);
}
/**
@@ -90,7 +90,7 @@ final class UpgradeDatabaseService extends Service implements UpgradeInterface
);
foreach (self::UPGRADES as $upgradeVersion) {
if (Version::checkVersion($version, $upgradeVersion)) {
if (VersionUtil::checkVersion($version, $upgradeVersion)) {
if ($this->applyPreUpgrade($upgradeVersion) === false) {
throw new UpgradeException(
__u('Error al aplicar la actualización auxiliar'),

View File

@@ -25,8 +25,8 @@
namespace SP\Services\Upgrade;
use SP\Config\Config;
use SP\Util\Util;
use SP\Util\Version;
use SP\Util\PasswordUtil;
use SP\Util\VersionUtil;
/**
* Class UpgradeUtil
@@ -63,12 +63,12 @@ final class UpgradeUtil
*/
public function checkDbVersion()
{
$appVersion = Version::getVersionStringNormalized();
$appVersion = VersionUtil::getVersionStringNormalized();
$databaseVersion = UserUpgrade::fixVersionNumber(ConfigDB::getValue('version'));
if (Version::checkVersion($databaseVersion, $appVersion)
if (VersionUtil::checkVersion($databaseVersion, $appVersion)
&& Request::analyze('nodbupgrade', 0) === 0
&& Version::checkVersion($databaseVersion, self::$dbUpgrade)
&& VersionUtil::checkVersion($databaseVersion, self::$dbUpgrade)
&& !$this->configData->isMaintenance()
) {
$this->setUpgradeKey('db');
@@ -91,7 +91,7 @@ final class UpgradeUtil
$upgradeKey = $configData->getUpgradeKey();
if (empty($upgradeKey)) {
$configData->setUpgradeKey(Util::generateRandomBytes(32));
$configData->setUpgradeKey(PasswordUtil::generateRandomBytes(32));
}
$configData->setMaintenance(true);
@@ -112,7 +112,7 @@ final class UpgradeUtil
{
$appVersion = UserUpgrade::fixVersionNumber($this->configData->getConfigVersion());
if (Version::checkVersion($appVersion, self::$appUpgrade) && !$this->configData->isMaintenance()) {
if (VersionUtil::checkVersion($appVersion, self::$appUpgrade) && !$this->configData->isMaintenance()) {
$this->setUpgradeKey('app');
// FIXME: send link for upgrading

View File

@@ -29,7 +29,7 @@ use SP\Core\Messages\MailMessage;
use SP\Html\Html;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class UserPassRecoverService
@@ -103,7 +103,7 @@ final class UserPassRecoverService extends Service
throw new ServiceException(__u('Intentos excedidos'), ServiceException::WARNING);
}
$hash = Util::generateRandomBytes(16);
$hash = PasswordUtil::generateRandomBytes(16);
$this->add($id, $hash);

View File

@@ -0,0 +1,117 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Storage\File;
use SP\Core\Exceptions\CheckException;
use SP\Core\PhpExtensionChecker;
/**
* Class ArchiveHandler
*
* @package SP\Storage\File
*/
final class ArchiveHandler
{
const COMPRESS_EXTENSION = '.tar.gz';
/**
* @var PhpExtensionChecker
*/
private $extensionChecker;
/**
* @var FileHandler
*/
private $archive;
/**
* ArchiveHandler constructor.
*
* @param string $archive
* @param PhpExtensionChecker $extensionChecker
*/
public function __construct(string $archive, PhpExtensionChecker $extensionChecker)
{
$this->extensionChecker = $extensionChecker;
$this->archive = new FileHandler($archive . self::getArchiveExtension());
}
/**
* @return bool|string
*/
private static function getArchiveExtension()
{
return substr(self::COMPRESS_EXTENSION, 0, strrpos(self::COMPRESS_EXTENSION, '.'));
}
/**
* Realizar un backup de la aplicación y comprimirlo.
*
* @param string $directory
* @param string|null $regex
*
* @throws CheckException
* @throws FileException
*/
public function compressDirectory(string $directory, string $regex = null)
{
$this->extensionChecker->checkPharAvailable(true);
$archive = new \PharData($this->archive->getFile());
$archive->buildFromDirectory($directory, $regex);
$archive->compress(\Phar::GZ);
// Delete the non-compressed archive
$this->archive->delete();
}
/**
* Realizar un backup de la aplicación y comprimirlo.
*
* @param string $file
*
* @throws CheckException
* @throws FileException
*/
public function compressFile(string $file)
{
$this->extensionChecker->checkPharAvailable(true);
$archive = new \PharData($this->archive->getFile());
$archive->addFile($file, basename($file));
$archive->compress(\Phar::GZ);
// Delete the non-compressed archive
$this->archive->delete();
}
/**
* @return FileHandler
*/
public function getArchive(): FileHandler
{
return $this->archive;
}
}

View File

@@ -24,6 +24,8 @@
namespace SP\Storage\File;
use SP\Util\Util;
/**
* Class FileHandler
*
@@ -32,6 +34,7 @@ namespace SP\Storage\File;
final class FileHandler
{
const CHUNK_LENGTH = 8192;
const CHUNK_FACTOR = 3;
/**
* @var string
*/
@@ -173,6 +176,37 @@ final class FileHandler
return $this;
}
/**
* @param callable $chunker
* @param float $rate
*
* @throws FileException
*/
public function readChunked(callable $chunker = null, float $rate = null)
{
$maxRate = Util::getMaxDownloadChunk() / self::CHUNK_FACTOR;
if ($rate === null || $rate > $maxRate) {
$rate = $maxRate;
}
if (!is_resource($this->handle)) {
$this->open('rb');
}
while (!feof($this->handle)) {
if ($chunker !== null) {
$chunker(fread($this->handle, round($rate)));
} else {
print fread($this->handle, round($rate));
ob_flush();
flush();
}
}
$this->close();
}
/**
* Checks if the file is writable
*

View File

@@ -0,0 +1,141 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Util;
use Defuse\Crypto\Core;
use Defuse\Crypto\Encoding;
/**
* Class PasswordUtil
*
* @package SP\Util
*/
final class PasswordUtil
{
const CHARS = 'abcdefghijklmnopqrstuwxyz';
const CHARS_SPECIAL = '@$%&/()!_:.;{}^-';
const CHARS_NUMBER = '0123456789';
const FLAG_PASSWORD_NUMBER = 2;
const FLAG_PASSWORD_SPECIAL = 4;
const FLAG_PASSWORD_STRENGTH = 8;
/**
* Generate a ramdom password
*
* @param int $length Password length
* @param int $flags Password chars included and checking strength flags
*
* @return string
*/
public static function randomPassword($length = 16, int $flags = null)
{
if ($flags === null) {
$flags = self::FLAG_PASSWORD_SPECIAL | self::FLAG_PASSWORD_NUMBER | self::FLAG_PASSWORD_STRENGTH;
}
$useSpecial = ($flags & self::FLAG_PASSWORD_SPECIAL) > 0;
$useNumbers = ($flags & self::FLAG_PASSWORD_NUMBER) > 0;
$alphabet = self::CHARS . strtoupper(self::CHARS);
if ($useSpecial) {
$alphabet .= self::CHARS_SPECIAL;
}
if ($useNumbers) {
$alphabet .= self::CHARS_NUMBER;
}
/**
* @return array
*/
$passGen = function () use ($alphabet, $length) {
$pass = [];
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < $length; $i++) {
$n = mt_rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
return $pass;
};
if ($flags & self::FLAG_PASSWORD_STRENGTH) {
do {
$pass = $passGen();
$strength = self::checkStrength($pass);
$res = $strength['lower'] > 0 && $strength['upper'] > 0;
if ($useSpecial === true) {
$res = $res && $strength['special'] > 0;
}
if ($useNumbers === true) {
$res = $res && $strength['number'] > 0;
}
} while ($res === false);
return implode('', $pass);
}
return implode($passGen());
}
/**
* @param array $pass
*
* @return array
*/
public static function checkStrength(array $pass)
{
$charsUpper = strtoupper(self::CHARS);
$strength = ['lower' => 0, 'upper' => 0, 'special' => 0, 'number' => 0];
foreach ($pass as $char) {
$strength['lower'] += substr_count(self::CHARS, $char);
$strength['upper'] += substr_count($charsUpper, $char);
$strength['special'] += substr_count(self::CHARS_SPECIAL, $char);
$strength['number'] += substr_count(self::CHARS_NUMBER, $char);
}
return $strength;
}
/**
* Generar una cadena aleatoria usuando criptografía.
*
* @param int $length opcional, con la longitud de la cadena
*
* @return string
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
*/
public static function generateRandomBytes($length = 30)
{
return Encoding::binToHex(Core::secureRandom($length));
}
}

View File

@@ -24,8 +24,7 @@
namespace SP\Util;
use Defuse\Crypto\Core;
use Defuse\Crypto\Encoding;
use SP\Storage\File\FileHandler;
defined('APP_ROOT') || die();
@@ -34,92 +33,6 @@ defined('APP_ROOT') || die();
*/
final class Util
{
/**
* Generar una clave aleatoria
*
* @param int $length Longitud de la clave
* @param bool $useNumbers Usar números
* @param bool $useSpecial Usar carácteres especiales
* @param bool $checKStrength
*
* @return string
*/
public static function randomPassword($length = 16, $useNumbers = true, $useSpecial = true, $checKStrength = true)
{
$charsLower = 'abcdefghijklmnopqrstuwxyz';
$charsUpper = 'ABCDEFGHIJKLMNOPQRSTUWXYZ';
$alphabet = $charsLower . $charsUpper;
if ($useSpecial === true) {
$charsSpecial = '@$%&/()!_:.;{}^';
$alphabet .= $charsSpecial;
}
if ($useNumbers === true) {
$charsNumbers = '0123456789';
$alphabet .= $charsNumbers;
}
/**
* @return array
*/
$passGen = function () use ($alphabet, $length) {
$pass = [];
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < $length; $i++) {
$n = mt_rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
return $pass;
};
if ($checKStrength === true) {
do {
$pass = $passGen();
$strength = ['lower' => 0, 'upper' => 0, 'special' => 0, 'number' => 0];
foreach ($pass as $char) {
if (strpos($charsLower, $char) !== false) {
$strength['lower']++;
} elseif (strpos($charsUpper, $char) !== false) {
$strength['upper']++;
} elseif ($useSpecial === true && strpos($charsSpecial, $char) !== false) {
$strength['special']++;
} elseif ($useNumbers === true && strpos($charsNumbers, $char) !== false) {
$strength['number']++;
}
}
if ($useSpecial === false) {
unset($strength['special']);
}
if ($useNumbers === false) {
unset($strength['number']);
}
} while (in_array(0, $strength, true));
return implode($pass);
}
return implode($passGen());
}
/**
* Generar una cadena aleatoria usuando criptografía.
*
* @param int $length opcional, con la longitud de la cadena
*
* @return string
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
*/
public static function generateRandomBytes($length = 30)
{
return Encoding::binToHex(Core::secureRandom($length));
}
/**
* Comprueba y devuelve un directorio temporal válido
@@ -166,13 +79,32 @@ final class Util
/**
* Obtener el tamaño máximo de subida de PHP.
*/
public static function getMaxUpload()
public static function getMaxUpload(): int
{
$max_upload = (int)ini_get('upload_max_filesize');
$max_post = (int)ini_get('post_max_size');
$memory_limit = (int)ini_get('memory_limit');
return min(self::convertShortUnit(ini_get('upload_max_filesize')),
self::convertShortUnit(ini_get('post_max_size')),
self::convertShortUnit(ini_get('memory_limit')));
}
return min($max_upload, $max_post, $memory_limit);
/**
* @param $value
*
* @return int
*/
public static function convertShortUnit($value): int
{
if (preg_match('/(\d+)(\w+)/', $value, $match)) {
switch (strtoupper($match[2])) {
case 'K':
return (int)$match[1] * 1024;
case 'M':
return (int)$match[1] * pow(1024, 2);
case 'G':
return (int)$match[1] * pow(1024, 3);
}
}
return (int)$value;
}
/**
@@ -193,11 +125,15 @@ final class Util
$in = is_string($in) ? strtolower($in) : $in;
// if not strict, we only have to check if something is false
if (in_array($in, ['false', 'no', 'n', '0', 'off', false, 0], true) || !$in) {
if (in_array($in, ['false', 'no', 'n', '0', 'off', false, 0], true)
|| !$in
) {
return false;
}
if ($strict && in_array($in, ['true', 'yes', 'y', '1', 'on', true, 1], true)) {
if ($strict
&& in_array($in, ['true', 'yes', 'y', '1', 'on', true, 1], true)
) {
return true;
}
@@ -348,4 +284,12 @@ final class Util
return intval($value);
}, explode($delimiter, $itemsId));
}
/**
* @return int
*/
public static function getMaxDownloadChunk(): int
{
return self::convertShortUnit(ini_get('memory_limit')) / FileHandler::CHUNK_FACTOR;
}
}

View File

@@ -27,11 +27,11 @@ namespace SP\Util;
use SP\Services\Install\Installer;
/**
* Class Version
* Class VersionUtil
*
* @package SP\Util
*/
final class Version
final class VersionUtil
{
/**
* Devolver versión normalizada en cadena

View File

@@ -934,7 +934,7 @@ sysPass.Actions = function (log) {
sk: sysPassApp.sk.get()
});
if (fileType === 'PDF') {
if (fileType === 'PDF' || fileType === 'application/pdf') {
window.open(url, '_blank');
return;
}

View File

@@ -35,23 +35,24 @@ d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getU
return a&&($(a).find(".is-selected").each(function(){b.push($(this).data("item-id"))}),0===b.length)?!1:b}},v=function(a){var b=$("#taskStatus");b.empty().html(sysPassApp.config.LANG[62]);var d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:["task/runTask",a]});return sysPassApp.requests.getActionEvent(d,function(a){a=a.task+" - "+a.message+" - "+a.time+" - "+a.progress+"%";a+="<br>"+sysPassApp.config.LANG[62];b.empty().html(a)})};return{getContent:f,
showFloatingBox:h,closeFloatingBox:q,appMgmt:u,account:m,accountManager:{restore:function(a){c.info("accountManager:restore");g.state.update(a);var b=a.data("item-id"),d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(d,function(d){sysPassApp.msg.out(d);0===d.status&&((d=a.data("action-next"))?f({r:[d,b]}):f({r:g.state.tab.route,tabIndex:g.state.tab.index}))})}},
file:{view:function(a){c.info("file:view");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(b){if(0!==b.status)return sysPassApp.msg.out(b);p(a,b.data.html)})},download:function(a){c.info("file:download");var b=a.data("item-type");a=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});
"PDF"===b?window.open(a,"_blank"):$.fileDownload(a,{httpMethod:"GET",successCallback:function(a){sysPassApp.msg.ok(sysPassApp.config.LANG[72])}})},delete:function(a){c.info("file:delete");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[15]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=sysPassApp.requests.getRequestOpts();
b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&m.listFiles($("#list-account-files"))})}}})}},checks:{wiki:function(a){c.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(sysPassApp.sk.get());var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);
0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){c.info("config:save");g.save(a)},masterpass:function(a){var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[59]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(b){b.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){var d;(b=a.find("input[name='taskId']").val())&&
(d=v(b));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.useFullLoading=!!b;c.data=a.serialize();sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);a.find(":input[type=password]").val("");void 0!==d&&d.close()})}}})},backup:function(a){c.info("config:backup");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.useFullLoading=!0;b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,
function(a){sysPassApp.msg.out(a);0===a.status&&f({r:g.state.tab.route,tabIndex:g.state.tab.index})})},export:function(a){c.info("config:export");g.save(a)},import:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},refreshMpass:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();
b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},mailCheck:function(a){c.info("config:mailCheck");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a)})}},main:w,user:{showSettings:function(a){c.info("user:showSettings");
f({r:a.data("action-route")},"userSettings")},saveSettings:function(a){c.info("user:saveSettings");g.save(a)},password:function(a){c.info("user:password");var b=sysPassApp.requests.getRequestOpts();b.type="html";b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){0===a.length?w.logout():h(a)})},passreset:function(a){c.info("user:passreset");var b=sysPassApp.requests.getRequestOpts();
b.url=e.entrypoint+"/?r="+a.data("action-route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})}},link:{save:function(a){c.info("link:save");var b=function(b){var d=a.data("account-id"),c=sysPassApp.requests.getRequestOpts();c.method="get";d?c.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),d,b],sk:sysPassApp.sk.get(),isAjax:1}):(c.url=sysPassApp.util.getUrl(e.entrypoint,
{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1}),c.data=a.serialize());sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),d]})})},d='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[48]+"</p></div>";mdlDialog().show({text:d,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();b(0)}},positive:{title:sysPassApp.config.LANG[43],onClick:function(a){a.preventDefault();b(1)}}})},delete:function(a){c.info("link:delete");
var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[12]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,
function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),a.data("account-id")]})})}}})},refresh:function(a){c.info("link:refresh");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&((b=a.data("action-next"))?f({r:[b,a.data("account-id")]}):f({r:g.state.tab.route,
tabIndex:g.state.tab.index}))})}},eventlog:{clear:function(a){var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[20]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}},ajaxUrl:e,plugin:{toggle:function(a){c.info("plugin:enable");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();
b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},reset:function(a){c.info("plugin:reset");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[58]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();
sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})},search:function(a){c.info("plugin:search");l.search(a)},show:function(a){c.info("plugin:show");u.show(a)},save:function(a){c.info("plugin:save");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&
(f({r:a.data("action-next")}),$.magnificPopup.close())})},nav:function(a){c.info("plugin:nav");l.nav(a)}},notification:r,wiki:{show:function(a){c.info("wiki:show");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),pageName:a.data("pagename"),actionId:a.data("action-id"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){0!==a.status?sysPassApp.msg.out(a):h(a.data.html)})}},items:{get:function(a){c.info("items:get");
var b=a[0].selectize;b.clearOptions();b.load(function(c){var d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(d,function(d){c(d.data);b.setValue(a.data("selected-id"),!0);sysPassApp.triggers.updateFormHash()})})},update:function(a){c.info("items:update");var b=$("#"+a.data("item-dst"))[0].selectize,d=b.getValue();b.clearOptions();b.load(function(c){var f=
sysPassApp.requests.getRequestOpts();f.method="get";f.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("item-route"),sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(f,function(a){c(a);b.setValue(d,!0)})})}},ldap:{check:function(a){c.info("ldap:check");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a);0===a.status&&
void 0!==a.data.template&&void 0!==a.data.items&&h(a.data.template,{open:function(){var b=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){b.append(sysPassApp.theme.html.getList(a.items,a.icon))})}})})},import:function(a){c.info("ldap:import");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[57]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},
positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=$(a.data("src"));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a)})}}})}},track:{unlock:function(a){c.info("track:unlock");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),
isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);g.refresh(a)})},clear:function(a){c.info("track:clear");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[71]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}}}};
"PDF"===b||"application/pdf"===b?window.open(a,"_blank"):$.fileDownload(a,{httpMethod:"GET",successCallback:function(a){sysPassApp.msg.ok(sysPassApp.config.LANG[72])}})},delete:function(a){c.info("file:delete");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[15]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=
sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&m.listFiles($("#list-account-files"))})}}})}},checks:{wiki:function(a){c.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(sysPassApp.sk.get());var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.data=a.serialize();sysPassApp.requests.getActionCall(b,
function(a){sysPassApp.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){c.info("config:save");g.save(a)},masterpass:function(a){var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[59]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(b){b.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){var d;
(b=a.find("input[name='taskId']").val())&&(d=v(b));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.useFullLoading=!!b;c.data=a.serialize();sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);a.find(":input[type=password]").val("");void 0!==d&&d.close()})}}})},backup:function(a){c.info("config:backup");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.useFullLoading=!0;b.data=a.serialize()+"&sk="+sysPassApp.sk.get();
sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&f({r:g.state.tab.route,tabIndex:g.state.tab.index})})},export:function(a){c.info("config:export");g.save(a)},import:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},refreshMpass:function(a){c.info("config:import");var b=
sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},mailCheck:function(a){c.info("config:mailCheck");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a)})}},
main:w,user:{showSettings:function(a){c.info("user:showSettings");f({r:a.data("action-route")},"userSettings")},saveSettings:function(a){c.info("user:saveSettings");g.save(a)},password:function(a){c.info("user:password");var b=sysPassApp.requests.getRequestOpts();b.type="html";b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){0===a.length?w.logout():h(a)})},passreset:function(a){c.info("user:passreset");
var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"/?r="+a.data("action-route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})}},link:{save:function(a){c.info("link:save");var b=function(b){var d=a.data("account-id"),c=sysPassApp.requests.getRequestOpts();c.method="get";d?c.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),d,b],sk:sysPassApp.sk.get(),
isAjax:1}):(c.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1}),c.data=a.serialize());sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),d]})})},d='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[48]+"</p></div>";mdlDialog().show({text:d,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();b(0)}},positive:{title:sysPassApp.config.LANG[43],onClick:function(a){a.preventDefault();
b(1)}}})},delete:function(a){c.info("link:delete");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[12]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],
sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),a.data("account-id")]})})}}})},refresh:function(a){c.info("link:refresh");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&
((b=a.data("action-next"))?f({r:[b,a.data("account-id")]}):f({r:g.state.tab.route,tabIndex:g.state.tab.index}))})}},eventlog:{clear:function(a){var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[20]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})}},ajaxUrl:e,plugin:{toggle:function(a){c.info("plugin:enable");
g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},reset:function(a){c.info("plugin:reset");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[58]+"</p></div>";mdlDialog().show({text:b,
negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})},search:function(a){c.info("plugin:search");l.search(a)},show:function(a){c.info("plugin:show");u.show(a)},save:function(a){c.info("plugin:save");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();
sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},nav:function(a){c.info("plugin:nav");l.nav(a)}},notification:r,wiki:{show:function(a){c.info("wiki:show");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),pageName:a.data("pagename"),actionId:a.data("action-id"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,
function(a){0!==a.status?sysPassApp.msg.out(a):h(a.data.html)})}},items:{get:function(a){c.info("items:get");var b=a[0].selectize;b.clearOptions();b.load(function(c){var d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(d,function(d){c(d.data);b.setValue(a.data("selected-id"),!0);sysPassApp.triggers.updateFormHash()})})},update:function(a){c.info("items:update");
var b=$("#"+a.data("item-dst"))[0].selectize,d=b.getValue();b.clearOptions();b.load(function(c){var f=sysPassApp.requests.getRequestOpts();f.method="get";f.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("item-route"),sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(f,function(a){c(a);b.setValue(d,!0)})})}},ldap:{check:function(a){c.info("ldap:check");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+
sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&h(a.data.template,{open:function(){var b=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){b.append(sysPassApp.theme.html.getList(a.items,a.icon))})}})})},import:function(a){c.info("ldap:import");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[57]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],
onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=$(a.data("src"));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a)})}}})}},track:{unlock:function(a){c.info("track:unlock");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=
sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);g.refresh(a)})},clear:function(a){c.info("track:clear");var b='<div id="alert"><p id="alert-text">'+sysPassApp.config.LANG[71]+"</p></div>";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],
onClick:function(b){b.preventDefault();g.save(a)}}})}}}};

View File

@@ -27,7 +27,7 @@ namespace SP\Tests\SP\Core\Crypt;
use phpseclib\Crypt\RSA;
use PHPUnit\Framework\TestCase;
use SP\Core\Crypt\CryptPKI;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class CryptPKITest
@@ -49,7 +49,7 @@ class CryptPKITest extends TestCase
{
$length = (CryptPKI::KEY_SIZE / 8) - 11;
$random = Util::generateRandomBytes($length);
$random = PasswordUtil::generateRandomBytes($length);
$data = $this->cryptPki->encryptRSA($random);
@@ -67,7 +67,7 @@ class CryptPKITest extends TestCase
{
$length = (CryptPKI::KEY_SIZE / 8) - 11;
$random = Util::randomPassword($length);
$random = PasswordUtil::randomPassword($length);
$data = $this->cryptPki->encryptRSA($random);
@@ -84,7 +84,7 @@ class CryptPKITest extends TestCase
{
$length = ((CryptPKI::KEY_SIZE / 8) - 11) + 1;
$random = Util::generateRandomBytes($length);
$random = PasswordUtil::generateRandomBytes($length);
$data = $this->cryptPki->encryptRSA($random);
@@ -123,7 +123,7 @@ class CryptPKITest extends TestCase
{
$length = (CryptPKI::KEY_SIZE / 8) - 11;
$random = Util::generateRandomBytes($length);
$random = PasswordUtil::generateRandomBytes($length);
$data = $this->cryptPki->encryptRSA($random);
@@ -132,7 +132,7 @@ class CryptPKITest extends TestCase
$this->assertEquals($random, $this->cryptPki->decryptRSA($data));
// Encrypt a long message
$random = Util::generateRandomBytes(128);
$random = PasswordUtil::generateRandomBytes(128);
$data = $this->cryptPki->encryptRSA($random);

View File

@@ -27,7 +27,7 @@ namespace SP\Tests\SP\Core\Crypt;
use Faker\Factory;
use PHPUnit\Framework\TestCase;
use SP\Core\Crypt\Hash;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class HashTest
@@ -42,7 +42,7 @@ class HashTest extends TestCase
public function testHashKey()
{
for ($i = 2; $i <= 128; $i *= 2) {
$key = Util::generateRandomBytes($i);
$key = PasswordUtil::generateRandomBytes($i);
$hash = Hash::hashKey($key);
$this->assertNotEmpty($hash);
@@ -60,7 +60,7 @@ class HashTest extends TestCase
for ($i = 2; $i <= 128; $i *= 2) {
$text = $faker->text;
$key = Util::generateRandomBytes($i);
$key = PasswordUtil::generateRandomBytes($i);
$hash = Hash::signMessage($text, $key);
$this->assertNotEmpty($hash);

View File

@@ -26,7 +26,7 @@ namespace SP\Tests\Core\Crypt;
use PHPUnit\Framework\TestCase;
use SP\Core\Crypt\Vault;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class VaultTest
@@ -48,7 +48,7 @@ class VaultTest extends TestCase
*/
protected function setUp()
{
$this->key = Util::generateRandomBytes();
$this->key = PasswordUtil::generateRandomBytes();
}
/**
@@ -60,7 +60,7 @@ class VaultTest extends TestCase
$vault->saveData('prueba', $this->key);
$this->assertEquals('prueba', $vault->getData($this->key));
$randomData = Util::generateRandomBytes();
$randomData = PasswordUtil::generateRandomBytes();
$vault = new Vault();
$vault->saveData($randomData, $this->key);

View File

@@ -31,7 +31,7 @@ use SP\Repositories\Account\AccountHistoryRepository;
use SP\Services\Account\AccountPasswordRequest;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -144,13 +144,13 @@ class AccountHistoryRepositoryTest extends DatabaseTestCase
*/
public function testCreate()
{
$result = self::$repository->create(new AccountHistoryCreateDto(2, true, false, Util::generateRandomBytes()));
$result = self::$repository->create(new AccountHistoryCreateDto(2, true, false, PasswordUtil::generateRandomBytes()));
$this->assertEquals(8, $result);
$result = self::$repository->create(new AccountHistoryCreateDto(2, true, true, Util::generateRandomBytes()));
$result = self::$repository->create(new AccountHistoryCreateDto(2, true, true, PasswordUtil::generateRandomBytes()));
$this->assertEquals(9, $result);
$result = self::$repository->create(new AccountHistoryCreateDto(10, true, false, Util::generateRandomBytes()));
$result = self::$repository->create(new AccountHistoryCreateDto(10, true, false, PasswordUtil::generateRandomBytes()));
$this->assertEquals(0, $result);
$this->assertEquals(7, $this->conn->getRowCount('AccountHistory'));
@@ -222,9 +222,9 @@ class AccountHistoryRepositoryTest extends DatabaseTestCase
{
$request = new AccountPasswordRequest();
$request->id = 3;
$request->pass = Util::generateRandomBytes();
$request->key = Util::generateRandomBytes();
$request->hash = Util::generateRandomBytes();
$request->pass = PasswordUtil::generateRandomBytes();
$request->key = PasswordUtil::generateRandomBytes();
$request->hash = PasswordUtil::generateRandomBytes();
$this->assertEquals(1, self::$repository->updatePassword($request));

View File

@@ -35,6 +35,7 @@ use SP\Repositories\AuthToken\AuthTokenRepository;
use SP\Repositories\DuplicatedItemException;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\PasswordUtil;
use SP\Util\Util;
use function SP\Tests\setupContext;
@@ -173,7 +174,7 @@ class AuthTokenRepositoryTest extends DatabaseTestCase
*/
public function testRefreshTokenByUserId()
{
$token = Util::generateRandomBytes();
$token = PasswordUtil::generateRandomBytes();
// Comprobar actualización con usuario que existe
$this->assertEquals(2, self::$repository->refreshTokenByUserId(1, $token));
@@ -193,7 +194,7 @@ class AuthTokenRepositoryTest extends DatabaseTestCase
*/
public function testUpdate()
{
$token = Util::generateRandomBytes();
$token = PasswordUtil::generateRandomBytes();
$hash = Hash::hashKey('prueba123');
$vault = Vault::getInstance()->saveData('prueba', 'prueba123');
@@ -305,7 +306,7 @@ class AuthTokenRepositoryTest extends DatabaseTestCase
*/
public function testCreate()
{
$token = Util::generateRandomBytes();
$token = PasswordUtil::generateRandomBytes();
$hash = Hash::hashKey('prueba123');
$vault = Vault::getInstance()->saveData('prueba', 'prueba123');

View File

@@ -443,4 +443,104 @@ class NotificationRepositoryTest extends DatabaseTestCase
$this->assertEquals(0, self::$repository->getAllActiveForUserId(2)->getNumRows());
$this->assertEquals(0, self::$repository->getAllActiveForUserId(3)->getNumRows());
}
/**
* @throws ConstraintException
* @throws QueryException
*/
public function testGetAllActiveForAdmin()
{
$result = self::$repository->getAllActiveForAdmin(1);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
$result = self::$repository->getAllActiveForAdmin(2);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(3, $result->getNumRows());
$this->assertCount(3, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
$this->assertEquals(1, $data[2]->getId());
$result = self::$repository->getAllActiveForAdmin(3);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
}
/**
* @throws ConstraintException
* @throws QueryException
*/
public function testSearchForAdmin()
{
$itemSearchData = new ItemSearchData();
$itemSearchData->setLimitCount(10);
$itemSearchData->setSeachString('Test');
$result = self::$repository->searchForAdmin($itemSearchData, 1);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
$itemSearchData->setSeachString('Accounts');
$result = self::$repository->searchForAdmin($itemSearchData, 2);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(3, $result->getNumRows());
$this->assertCount(3, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
$this->assertEquals(1, $data[2]->getId());
$itemSearchData->setSeachString('Admins');
$result = self::$repository->searchForAdmin($itemSearchData, 2);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(1, $result->getNumRows());
$this->assertCount(1, $data);
$this->assertEquals(3, $data[0]->getId());
$itemSearchData->setSeachString('Global');
$result = self::$repository->searchForAdmin($itemSearchData, 2);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(1, $result->getNumRows());
$this->assertCount(1, $data);
$this->assertEquals(2, $data[0]->getId());
$itemSearchData->setSeachString('');
$result = self::$repository->searchForAdmin($itemSearchData, 2);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(3, $result->getNumRows());
$this->assertCount(3, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
$this->assertEquals(1, $data[2]->getId());
}
}

View File

@@ -33,7 +33,7 @@ use SP\Repositories\DuplicatedItemException;
use SP\Repositories\PublicLink\PublicLinkRepository;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -162,7 +162,7 @@ class PublicLinkRepositoryTest extends DatabaseTestCase
$data = new PublicLinkData();
$data->setItemId(1);
$data->setHash(Util::generateRandomBytes());
$data->setHash(PasswordUtil::generateRandomBytes());
$data->setData('data');
$data->setUserId(1);
$data->setTypeId(1);
@@ -314,7 +314,7 @@ class PublicLinkRepositoryTest extends DatabaseTestCase
public function testRefresh()
{
$data = new PublicLinkData();
$data->setHash(Util::generateRandomBytes());
$data->setHash(PasswordUtil::generateRandomBytes());
$data->setDateExpire(time() + 3600);
$data->setMaxCountViews(6);
$data->setData('data_new');
@@ -439,7 +439,7 @@ class PublicLinkRepositoryTest extends DatabaseTestCase
$data = new PublicLinkData();
$data->setId(1);
$data->setItemId(2);
$data->setHash(Util::generateRandomBytes());
$data->setHash(PasswordUtil::generateRandomBytes());
$data->setData('data');
$data->setUserId(2);
$data->setTypeId(1);

View File

@@ -29,7 +29,7 @@ use SP\Core\Exceptions\ConstraintException;
use SP\Repositories\User\UserPassRecoverRepository;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -69,11 +69,11 @@ class UserPassRecoverRepositoryTest extends DatabaseTestCase
*/
public function testAdd()
{
$this->assertEquals(3, self::$repository->add(2, Util::generateRandomBytes()));
$this->assertEquals(3, self::$repository->add(2, PasswordUtil::generateRandomBytes()));
$this->expectException(ConstraintException::class);
self::$repository->add(10, Util::generateRandomBytes());
self::$repository->add(10, PasswordUtil::generateRandomBytes());
}
/**
@@ -101,7 +101,7 @@ class UserPassRecoverRepositoryTest extends DatabaseTestCase
$this->assertEquals(1, $result->getNumRows());
$this->assertEquals(2, $result->getData()->userId);
$result = self::$repository->getUserIdForHash(Util::generateRandomBytes(), 1529275206);
$result = self::$repository->getUserIdForHash(PasswordUtil::generateRandomBytes(), 1529275206);
$this->assertEquals(0, $result->getNumRows());
}

View File

@@ -170,7 +170,7 @@ class AccountAclServiceTest extends DatabaseTestCase
$this->checkAllowAll($this->setUpAccountEnvironment(1, 1, 1, 1));
$this->checkAllowAll($this->setUpAccountEnvironment(2, 1, 1, 1));
$accountAcl = new \SP\Services\Account\AccountAcl(0);
$accountAcl = new AccountAcl(0);
$accountAcl->setCompiledAccountAccess(true);
$accountAcl->setCompiledShowAccess(true);
$accountAcl->setResultView(true);
@@ -258,7 +258,7 @@ class AccountAclServiceTest extends DatabaseTestCase
$accountAcl = $service->getAcl($action, $accountAclDto);
$this->assertInstanceOf(\SP\Services\Account\AccountAcl::class, $accountAcl);
$this->assertInstanceOf(AccountAcl::class, $accountAcl);
$this->assertTrue($accountAcl->isCompiledAccountAccess());
$this->assertTrue($accountAcl->isCompiledShowAccess());
@@ -750,7 +750,7 @@ class AccountAclServiceTest extends DatabaseTestCase
->reset()
->setAccFiles($profile);
$accountAcl = (new \SP\Services\Account\AccountAcl(0))
$accountAcl = (new AccountAcl(0))
->setCompiledAccountAccess(true)
->setCompiledShowAccess(true)
->setResultView($should['view'])

View File

@@ -33,7 +33,7 @@ use SP\Services\Account\AccountPasswordRequest;
use SP\Services\ServiceException;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -89,13 +89,13 @@ class AccountHistoryServiceTest extends DatabaseTestCase
*/
public function testCreate()
{
$result = self::$service->create(new AccountHistoryCreateDto(2, true, false, Util::generateRandomBytes()));
$result = self::$service->create(new AccountHistoryCreateDto(2, true, false, PasswordUtil::generateRandomBytes()));
$this->assertEquals(8, $result);
$result = self::$service->create(new AccountHistoryCreateDto(2, true, true, Util::generateRandomBytes()));
$result = self::$service->create(new AccountHistoryCreateDto(2, true, true, PasswordUtil::generateRandomBytes()));
$this->assertEquals(9, $result);
$result = self::$service->create(new AccountHistoryCreateDto(10, true, false, Util::generateRandomBytes()));
$result = self::$service->create(new AccountHistoryCreateDto(10, true, false, PasswordUtil::generateRandomBytes()));
$this->assertEquals(0, $result);
$this->assertEquals(7, $this->conn->getRowCount('AccountHistory'));
@@ -205,9 +205,9 @@ class AccountHistoryServiceTest extends DatabaseTestCase
{
$request = new AccountPasswordRequest();
$request->id = 3;
$request->pass = Util::generateRandomBytes();
$request->key = Util::generateRandomBytes();
$request->hash = Util::generateRandomBytes();
$request->pass = PasswordUtil::generateRandomBytes();
$request->key = PasswordUtil::generateRandomBytes();
$request->hash = PasswordUtil::generateRandomBytes();
self::$service->updatePasswordMasterPass($request);

View File

@@ -40,7 +40,7 @@ use SP\Services\Account\AccountService;
use SP\Services\ServiceException;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -285,7 +285,7 @@ class AccountServiceTest extends DatabaseTestCase
$this->assertEquals('123abc', Crypt::decrypt($data['pass'], $data['key'], self::SECURE_KEY_PASSWORD));
$randomKeyPass = Util::generateRandomBytes();
$randomKeyPass = PasswordUtil::generateRandomBytes();
$data = self::$service->getPasswordEncrypted('123abc', $randomKeyPass);

View File

@@ -47,7 +47,7 @@ class FileBackupServiceTest extends TestCase
$service = $dic->get(FileBackupService::class);
$service->doBackup(RESOURCE_DIR);
$this->assertFileExists($service->getBackupFileApp() . '.gz');
$this->assertFileExists($service->getBackupFileDb());
$this->assertFileExists(FileBackupService::getAppBackupFilename(RESOURCE_DIR, $service->getHash(), true));
$this->assertFileExists(FileBackupService::getDbBackupFilename(RESOURCE_DIR, $service->getHash(), true));
}
}

View File

@@ -30,7 +30,7 @@ use SP\Services\Export\XmlVerifyService;
use SP\Services\ServiceException;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -129,7 +129,7 @@ class XmlExportServiceTest extends DatabaseTestCase
$dic = setupContext();
$service = $dic->get(XmlExportService::class);
$password = Util::randomPassword();
$password = PasswordUtil::randomPassword();
$service->doExport(TMP_DIR, $password);

View File

@@ -33,7 +33,7 @@ use SP\Services\Install\InstallData;
use SP\Services\Install\Installer;
use SP\Storage\Database\DBStorageInterface;
use SP\Tests\DatabaseUtil;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\getResource;
use function SP\Tests\saveResource;
use function SP\Tests\setupContext;
@@ -258,7 +258,7 @@ class InstallerTest extends TestCase
*/
public function testHostingMode()
{
$pass = Util::randomPassword();
$pass = PasswordUtil::randomPassword();
$host = getenv('DB_SERVER');
DatabaseUtil::dropDatabase(self::DB_NAME);

View File

@@ -30,7 +30,7 @@ use SP\Services\Install\InstallData;
use SP\Services\Install\MySQL;
use SP\Storage\Database\MySQLHandler;
use SP\Tests\DatabaseUtil;
use SP\Util\Util;
use SP\Util\PasswordUtil;
/**
* Class MySQLTest
@@ -161,7 +161,7 @@ class MySQLTest extends TestCase
public function testCreateDBUser()
{
$mysql = new MySQL($this->getParams(), new ConfigData());
$mysql->createDBUser('test', Util::randomPassword());
$mysql->createDBUser('test', PasswordUtil::randomPassword());
$num = (int)$mysql->getDbHandler()
->getConnectionSimple()

View File

@@ -24,6 +24,7 @@
namespace SP\Tests\Services\Notification;
use SP\Core\Context\ContextInterface;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Messages\NotificationMessage;
use SP\DataModel\ItemSearchData;
@@ -31,6 +32,7 @@ use SP\DataModel\NotificationData;
use SP\Repositories\NoSuchItemException;
use SP\Services\Notification\NotificationService;
use SP\Services\ServiceException;
use SP\Services\User\UserLoginResponse;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use function SP\Tests\setupContext;
@@ -42,6 +44,10 @@ use function SP\Tests\setupContext;
*/
class NotificationServiceTest extends DatabaseTestCase
{
/**
* @var ContextInterface
*/
private static $context;
/**
* @var NotificationService
*/
@@ -61,6 +67,8 @@ class NotificationServiceTest extends DatabaseTestCase
// Datos de conexión a la BBDD
self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class);
self::$context = $dic->get(ContextInterface::class);
// Inicializar el servicio
self::$service = $dic->get(NotificationService::class);
}
@@ -141,8 +149,14 @@ class NotificationServiceTest extends DatabaseTestCase
* @throws \SP\Core\Exceptions\QueryException
* @throws NoSuchItemException
*/
public function testGetAllActiveForUserId()
public function testGetAllActiveForNonAdmin()
{
$userData = new UserLoginResponse();
$userData->setId(2);
$userData->setIsAdminApp(false);
self::$context->setUserData($userData);
$data = self::$service->getAllActiveForUserId(2);
$this->assertCount(2, $data);
@@ -167,6 +181,43 @@ class NotificationServiceTest extends DatabaseTestCase
$this->assertCount(0, self::$service->getAllActiveForUserId(3));
}
/**
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
* @throws NoSuchItemException
*/
public function testGetAllActiveForAdmin()
{
$userData = new UserLoginResponse();
$userData->setId(1);
$userData->setIsAdminApp(true);
self::$context->setUserData($userData);
$data = self::$service->getAllActiveForUserId(1);
$this->assertCount(2, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
$data = self::$service->getAllActiveForUserId(3);
$this->assertCount(2, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals(2, $data[1]->getId());
self::$service->setCheckedById(2);
$data = self::$service->getAllActiveForUserId(1);
$this->assertCount(1, $data);
$this->assertEquals(3, $data[0]->getId());
self::$service->setCheckedById(3);
$this->assertCount(0, self::$service->getAllActiveForUserId(1));
}
/**
* @throws ConstraintException
* @throws NoSuchItemException
@@ -262,8 +313,76 @@ class NotificationServiceTest extends DatabaseTestCase
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
public function testSearch()
public function testSearchNonAdmin()
{
$userData = new UserLoginResponse();
$userData->setId(2);
$userData->setIsAdminApp(false);
self::$context->setUserData($userData);
$itemSearchData = new ItemSearchData();
$itemSearchData->setLimitCount(10);
$itemSearchData->setSeachString('Test');
$result = self::$service->search($itemSearchData);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(1, $result->getNumRows());
$this->assertCount(1, $data);
$this->assertInstanceOf(NotificationData::class, $data[0]);
$this->assertEquals(2, $data[0]->getId());
$this->assertEquals('test', $data[0]->getDescription());
$itemSearchData->setSeachString('Global');
$result = self::$service->search($itemSearchData);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(1, $result->getNumRows());
$this->assertCount(1, $data);
$this->assertInstanceOf(NotificationData::class, $data[0]);
$this->assertEquals(2, $data[0]->getId());
$this->assertEquals('Global', $data[0]->getType());
$itemSearchData->setSeachString('');
$result = self::$service->search($itemSearchData);
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $result->getDataAsArray());
$itemSearchData->setSeachString('Accounts');
$result = self::$service->search($itemSearchData);
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $data);
$this->assertEquals(2, $data[0]->getId());
$this->assertEquals('Accounts', $data[0]->getComponent());
$this->assertEquals(1, $data[1]->getId());
$this->assertEquals('Accounts', $data[1]->getComponent());
}
/**
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
*/
public function testSearchAdmin()
{
$userData = new UserLoginResponse();
$userData->setId(1);
$userData->setIsAdminApp(true);
self::$context->setUserData($userData);
$itemSearchData = new ItemSearchData();
$itemSearchData->setLimitCount(10);
$itemSearchData->setSeachString('Test');
@@ -288,8 +407,8 @@ class NotificationServiceTest extends DatabaseTestCase
$result = self::$service->search($itemSearchData);
$this->assertEquals(3, $result->getNumRows());
$this->assertCount(3, $result->getDataAsArray());
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $result->getDataAsArray());
$itemSearchData->setSeachString('Accounts');
@@ -297,14 +416,12 @@ class NotificationServiceTest extends DatabaseTestCase
/** @var NotificationData[] $data */
$data = $result->getDataAsArray();
$this->assertEquals(3, $result->getNumRows());
$this->assertCount(3, $data);
$this->assertEquals(1529145313, $data[0]->getDate());
$this->assertEquals(2, $result->getNumRows());
$this->assertCount(2, $data);
$this->assertEquals(3, $data[0]->getId());
$this->assertEquals('Accounts', $data[0]->getComponent());
$this->assertEquals(1529145296, $data[1]->getDate());
$this->assertEquals(2, $data[1]->getId());
$this->assertEquals('Accounts', $data[1]->getComponent());
$this->assertEquals(1529145158, $data[2]->getDate());
$this->assertEquals('Accounts', $data[2]->getComponent());
}
/**

View File

@@ -37,6 +37,7 @@ use SP\Services\PublicLink\PublicLinkService;
use SP\Services\ServiceException;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\PasswordUtil;
use SP\Util\Util;
use function SP\Tests\setupContext;
@@ -218,7 +219,7 @@ class PublicLinkServiceTest extends DatabaseTestCase
$data = new PublicLinkData();
$data->setItemId(1);
$data->setHash(Util::generateRandomBytes());
$data->setHash(PasswordUtil::generateRandomBytes());
$data->setUserId(1);
$data->setTypeId(1);
$data->setNotify(1);
@@ -277,7 +278,7 @@ class PublicLinkServiceTest extends DatabaseTestCase
{
$data = new PublicLinkData();
$data->setItemId(2);
$data->setHash(Util::generateRandomBytes());
$data->setHash(PasswordUtil::generateRandomBytes());
$data->setData('data');
$data->setUserId(1);
$data->setTypeId(1);
@@ -393,7 +394,7 @@ class PublicLinkServiceTest extends DatabaseTestCase
$data = new PublicLinkData();
$data->setId(3);
$data->setItemId(2);
$data->setHash(Util::generateRandomBytes());
$data->setHash(PasswordUtil::generateRandomBytes());
$data->setData('data');
$data->setUserId(2);
$data->setTypeId(1);

View File

@@ -29,7 +29,7 @@ use SP\Services\ServiceException;
use SP\Services\UserPassRecover\UserPassRecoverService;
use SP\Storage\Database\DatabaseConnectionData;
use SP\Tests\DatabaseTestCase;
use SP\Util\Util;
use SP\Util\PasswordUtil;
use function SP\Tests\setupContext;
/**
@@ -76,7 +76,7 @@ class UserPassRecoverServiceTest extends DatabaseTestCase
$this->expectException(ServiceException::class);
self::$service->toggleUsedByHash(Util::generateRandomBytes());
self::$service->toggleUsedByHash(PasswordUtil::generateRandomBytes());
}
/**
@@ -97,11 +97,11 @@ class UserPassRecoverServiceTest extends DatabaseTestCase
*/
public function testAdd()
{
$this->assertEquals(3, self::$service->add(2, Util::generateRandomBytes()));
$this->assertEquals(3, self::$service->add(2, PasswordUtil::generateRandomBytes()));
$this->expectException(ConstraintException::class);
self::$service->add(10, Util::generateRandomBytes());
self::$service->add(10, PasswordUtil::generateRandomBytes());
}
/**
@@ -156,6 +156,6 @@ class UserPassRecoverServiceTest extends DatabaseTestCase
$this->expectException(ServiceException::class);
self::$service->getUserIdForHash(Util::generateRandomBytes());
self::$service->getUserIdForHash(PasswordUtil::generateRandomBytes());
}
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Tests\Util;
use PHPUnit\Framework\TestCase;
use SP\Util\PasswordUtil;
/**
* Class PasswordUtilTest
*
* @package SP\Tests\Util
*/
class PasswordUtilTest extends TestCase
{
public function testCheckStrength()
{
$passwordLower = str_split('artpwerlm');
$passwordUpper = str_split('AFGUYOHQEM');
$passwordSpecial = str_split('%._-$&/()');
$passwordNumber = str_split('18675249');
$this->assertEquals(count($passwordLower), PasswordUtil::checkStrength($passwordLower)['lower']);
$this->assertEquals(count($passwordUpper), PasswordUtil::checkStrength($passwordUpper)['upper']);
$this->assertEquals(count($passwordSpecial), PasswordUtil::checkStrength($passwordSpecial)['special']);
$this->assertEquals(count($passwordNumber), PasswordUtil::checkStrength($passwordNumber)['number']);
$passwordMixed = array_merge($passwordLower, $passwordUpper, $passwordSpecial, $passwordNumber);
shuffle($passwordMixed);
foreach (PasswordUtil::checkStrength($passwordMixed) as $count) {
$this->assertGreaterThan(0, $count);
}
}
public function testRandomPassword()
{
$lengths = [16, 32, 64];
foreach ($lengths as $length) {
$pass = PasswordUtil::randomPassword($length);
$this->assertEquals($length, strlen($pass));
foreach (PasswordUtil::checkStrength(str_split($pass)) as $type => $count) {
$this->assertGreaterThan(0, $count);
}
}
}
public function testRandomPasswordNoFlags()
{
$pass = PasswordUtil::randomPassword(16, 0);
$strength = PasswordUtil::checkStrength(str_split($pass));
$this->assertGreaterThan(0, $strength['lower']);
$this->assertGreaterThan(0, $strength['upper']);
$this->assertEquals(0, $strength['special']);
$this->assertEquals(0, $strength['number']);
}
public function testRandomPasswordSpecial()
{
$flags = PasswordUtil::FLAG_PASSWORD_SPECIAL | PasswordUtil::FLAG_PASSWORD_STRENGTH;
$pass = PasswordUtil::randomPassword(16, $flags);
$strength = PasswordUtil::checkStrength(str_split($pass));
$this->assertGreaterThan(0, $strength['lower']);
$this->assertGreaterThan(0, $strength['upper']);
$this->assertGreaterThan(0, $strength['special']);
$this->assertEquals(0, $strength['number']);
}
public function testRandomPasswordNumbers()
{
$flags = PasswordUtil::FLAG_PASSWORD_NUMBER | PasswordUtil::FLAG_PASSWORD_STRENGTH;
$pass = PasswordUtil::randomPassword(16, $flags);
$strength = PasswordUtil::checkStrength(str_split($pass));
$this->assertGreaterThan(0, $strength['lower']);
$this->assertGreaterThan(0, $strength['upper']);
$this->assertGreaterThan(0, $strength['number']);
$this->assertEquals(0, $strength['special']);
}
public function testRandomPasswordAll()
{
$flags = PasswordUtil::FLAG_PASSWORD_NUMBER | PasswordUtil::FLAG_PASSWORD_SPECIAL | PasswordUtil::FLAG_PASSWORD_STRENGTH;
$pass = PasswordUtil::randomPassword(16, $flags);
$strength = PasswordUtil::checkStrength(str_split($pass));
$this->assertGreaterThan(0, $strength['lower']);
$this->assertGreaterThan(0, $strength['upper']);
$this->assertGreaterThan(0, $strength['number']);
$this->assertGreaterThan(0, $strength['special']);
}
/**
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
*/
public function testGenerateRandomBytes()
{
$bytesHex = PasswordUtil::generateRandomBytes(16);
$this->assertEquals(32, strlen($bytesHex));
$bytesHex = PasswordUtil::generateRandomBytes(32);
$this->assertEquals(64, strlen($bytesHex));
$bytesHex = PasswordUtil::generateRandomBytes(64);
$this->assertEquals(128, strlen($bytesHex));
}
}

127
tests/SP/Util/UtilTest.php Normal file
View File

@@ -0,0 +1,127 @@
<?php
/**
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Tests\SP\Util;
use PHPUnit\Framework\TestCase;
use SP\Util\Util;
/**
* Class UtilTest
*
* @package SP\Tests\Util
*/
class UtilTest extends TestCase
{
public function testCastToClass()
{
self::markTestIncomplete();
}
public function testUnserialize()
{
self::markTestIncomplete();
}
/**
* @dataProvider unitsProvider
*
* @param $unit
* @param $expected
*/
public function testConvertShortUnit($unit, $expected)
{
$this->assertEquals($expected, Util::convertShortUnit($unit));
}
public function testGetMaxUpload()
{
$upload = ini_set('upload_max_filesize', '30M');
$post = ini_set('post_max_size', '10M');
$memory = ini_set('memory_limit', 15728640);
if ($upload !== false
&& $post !== false
&& $memory !== false
) {
$this->assertEquals(10485760, Util::getMaxUpload());
} else {
self::markTestSkipped('Unable to set PHP\'s ini variables');
}
}
/**
* @dataProvider boolProvider
*
* @param $value
* @param $expected
*/
public function testBoolval($value, $expected)
{
$this->assertEquals($expected, Util::boolval($value));
$this->assertEquals($expected, Util::boolval($value, true));
}
/**
* @return array
*/
public function boolProvider()
{
return [
['false', false],
['no', false],
['n', false],
['0', false],
['off', false],
[0, false],
['true', true],
['yes', true],
['y', true],
['1', true],
['on', true],
[1, true]
];
}
public function testGetTempDir()
{
self::markTestIncomplete();
}
/**
* @return array
*/
public function unitsProvider()
{
return [
['128K', 131072],
['128M', 134217728],
['128G', 137438953472],
[131072, 131072],
[134217728, 134217728],
[137438953472, 137438953472],
];
}
}

View File

@@ -9,11 +9,11 @@
<authBasicAutoLoginEnabled>1</authBasicAutoLoginEnabled>
<authBasicDomain></authBasicDomain>
<authBasicEnabled>1</authBasicEnabled>
<backup_hash>469d8c9e4929938ef00640f07de42d56e3b9b29b</backup_hash>
<backup_hash>84a8f7e5acfaea173ff49c3d9e2dec220b0cb4f9</backup_hash>
<checkUpdates>0</checkUpdates>
<checknotices>0</checknotices>
<configDate>1539562721</configDate>
<configHash>70ced48a5cd70bf112f386361d4c10ac603132fe</configHash>
<configDate>1540762364</configDate>
<configHash>347560028fad7863c9de6d844d42003aa9317b12</configHash>
<configSaver></configSaver>
<configVersion></configVersion>
<databaseVersion></databaseVersion>
@@ -32,7 +32,7 @@
<dokuwikiUrlBase></dokuwikiUrlBase>
<dokuwikiUser></dokuwikiUser>
<encryptSession>0</encryptSession>
<export_hash>0dcdb304c5e122e25fbbb97f5b9de17f87195c62</export_hash>
<export_hash>e3a8d2f14c5c32a01852c265bed7bb141f81ae94</export_hash>
<filesAllowedExts>
<item type="filesAllowedExts">PDF</item>
<item type="filesAllowedExts">JPG</item>

View File

@@ -6,9 +6,7 @@
<field name="id">1</field>
<field name="type">Prueba</field>
<field name="component">Accounts</field>
<field name="description">
Notificación de prueba
</field>
<field name="description">Notificación de prueba</field>
<field name="date">1529145158</field>
<field name="checked">0</field>
<field name="userId">2</field>
@@ -19,9 +17,7 @@
<field name="id">2</field>
<field name="type">Global</field>
<field name="component">Accounts</field>
<field name="description">
test
</field>
<field name="description">test</field>
<field name="date">1529145296</field>
<field name="checked">0</field>
<field name="userId" xsi:nil="true" />
@@ -32,9 +28,7 @@
<field name="id">3</field>
<field name="type">Admins</field>
<field name="component">Accounts</field>
<field name="description">
test
</field>
<field name="description">test</field>
<field name="date">1529145313</field>
<field name="checked">0</field>
<field name="userId" xsi:nil="true" />