diff --git a/app/locales/es_ES/LC_MESSAGES/messages.mo b/app/locales/es_ES/LC_MESSAGES/messages.mo index bd1c8923..5a1e94bd 100644 Binary files a/app/locales/es_ES/LC_MESSAGES/messages.mo and b/app/locales/es_ES/LC_MESSAGES/messages.mo differ diff --git a/app/locales/es_ES/LC_MESSAGES/messages.po b/app/locales/es_ES/LC_MESSAGES/messages.po index 616db2dd..a63f9a5f 100644 --- a/app/locales/es_ES/LC_MESSAGES/messages.po +++ b/app/locales/es_ES/LC_MESSAGES/messages.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: sysPass\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-11 09:41+0100\n" -"PO-Revision-Date: 2018-11-11 09:41+0100\n" +"POT-Creation-Date: 2018-11-11 23:55+0100\n" +"PO-Revision-Date: 2018-11-11 23:55+0100\n" "Last-Translator: nuxsmin \n" "Language-Team: nuxsmin@syspass.org\n" "Language: es_ES\n" @@ -537,7 +537,7 @@ msgstr "Grupo actualizado" msgid "Group deleted" msgstr "Grupo eliminado" -#: app/modules/api/Init.php:149 +#: app/modules/api/Init.php:150 msgid "Updating needed" msgstr "Es necesario actualizar" @@ -727,7 +727,7 @@ msgstr "Archivo visualizado" #: app/modules/web/Controllers/ConfigBackupController.php:255 #: app/modules/web/Controllers/ConfigGeneralController.php:195 #: app/modules/web/Controllers/ConfigGeneralController.php:236 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:123 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:124 #: app/modules/web/themes/material-blue/views/config/import.inc:72 msgid "File" msgstr "Archivo" @@ -1118,10 +1118,10 @@ msgid "Verification of exported data finished" msgstr "Verificación de datos exportados finalizada" #: app/modules/web/Controllers/ConfigBackupController.php:122 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:114 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:255 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:306 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:163 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:115 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:256 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:307 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:164 #: app/modules/web/themes/material-blue/views/config/info.inc:49 #: app/modules/web/themes/material-blue/views/plugin/plugin.inc:34 msgid "Version" @@ -1294,7 +1294,7 @@ msgstr "Importación finalizada" #: app/modules/web/Controllers/ConfigImportController.php:82 #: app/modules/web/Controllers/ConfigImportController.php:85 #: lib/SP/Services/Backup/FileBackupService.php:120 -#: lib/SP/Services/Export/XmlExportService.php:205 +#: lib/SP/Services/Export/XmlExportService.php:201 msgid "Please check out the event log for more details" msgstr "Revise el registro de eventos para más detalles" @@ -1570,10 +1570,10 @@ msgstr "Ver Actual" #: app/modules/web/themes/material-blue/views/_partials/error.inc:15 #: app/modules/web/themes/material-blue/views/account/account-editpass.inc:123 #: app/modules/web/themes/material-blue/views/account/account-request.inc:67 -#: app/modules/web/themes/material-blue/views/config/accounts.inc:367 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:366 #: app/modules/web/themes/material-blue/views/config/backup.inc:173 #: app/modules/web/themes/material-blue/views/config/encryption.inc:310 -#: app/modules/web/themes/material-blue/views/config/general.inc:28 +#: app/modules/web/themes/material-blue/views/config/general.inc:27 #: app/modules/web/themes/material-blue/views/config/import.inc:91 #: app/modules/web/themes/material-blue/views/config/info.inc:193 #: app/modules/web/themes/material-blue/views/config/ldap.inc:295 @@ -1994,7 +1994,7 @@ msgstr "Vaciar registro de eventos" #. (itstool) path: action/text #: app/modules/web/Controllers/Helpers/Grid/FileGrid.php:94 #: app/modules/web/themes/material-blue/views/account/account.inc:41 -#: app/modules/web/themes/material-blue/views/config/accounts.inc:280 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:279 #: app/modules/web/themes/material-blue/views/itemshow/user_profile.inc:150 #: app/modules/web/themes/material-blue/views/itemshow/user_profile.inc:410 #: app/config/actions.xml:19 @@ -3099,12 +3099,12 @@ msgstr "Primera página" msgid "Last page" msgstr "Última página" -#: lib/SP/Bootstrap.php:278 +#: lib/SP/Bootstrap.php:279 #, php-format msgid "Required PHP version >= %s <= %s" msgstr "Versión de PHP requerida >= %s <= %s" -#: lib/SP/Bootstrap.php:280 +#: lib/SP/Bootstrap.php:281 msgid "Please update the PHP version to run sysPass" msgstr "" "Actualice la versión de PHP para que la aplicación funcione correctamente" @@ -3161,7 +3161,7 @@ msgstr "Contexto inválido" msgid "Context not initialized" msgstr "Contexto no inicializado" -#: lib/SP/Core/Context/SessionContext.php:547 +#: lib/SP/Core/Context/SessionContext.php:490 msgid "Session cannot be initialized" msgstr "La sesión no puede ser inicializada" @@ -3204,12 +3204,12 @@ msgstr "Error de codificación" msgid "Invalid XML-RPC response" msgstr "Respuesta XML-RPC inválida" -#: lib/SP/Mvc/Controller/ControllerTrait.php:70 +#: lib/SP/Mvc/Controller/ControllerTrait.php:73 msgid "Session not started or timed out" msgstr "La sesión no se ha iniciado o ha caducado" -#: lib/SP/Mvc/Controller/ControllerTrait.php:115 -#: lib/SP/Mvc/Controller/ControllerTrait.php:124 +#: lib/SP/Mvc/Controller/ControllerTrait.php:118 +#: lib/SP/Mvc/Controller/ControllerTrait.php:127 msgid "Invalid Action" msgstr "Acción Inválida" @@ -4080,34 +4080,33 @@ msgstr "Error al eliminar los campos" msgid "Field type not found" msgstr "Tipo de campo no encontrado" -#: lib/SP/Services/Export/XmlExportService.php:127 -#: lib/SP/Storage/File/FileCache.php:74 -#: lib/SP/Storage/File/FileCachePacked.php:116 +#: lib/SP/Services/Export/XmlExportService.php:125 +#: lib/SP/Storage/File/FileCacheBase.php:98 #, php-format msgid "Unable to create the directory (%s)" msgstr "No es posible crear el directorio (%s)" -#: lib/SP/Services/Export/XmlExportService.php:203 +#: lib/SP/Services/Export/XmlExportService.php:199 msgid "Error while exporting" msgstr "Error al realizar la exportación" -#: lib/SP/Services/Export/XmlExportService.php:271 +#: lib/SP/Services/Export/XmlExportService.php:267 msgid "Exporting categories" msgstr "Exportando categorías" -#: lib/SP/Services/Export/XmlExportService.php:383 +#: lib/SP/Services/Export/XmlExportService.php:379 msgid "Exporting clients" msgstr "Exportando clientes" -#: lib/SP/Services/Export/XmlExportService.php:429 +#: lib/SP/Services/Export/XmlExportService.php:425 msgid "Exporting tags" msgstr "Exportando etiquetas" -#: lib/SP/Services/Export/XmlExportService.php:473 +#: lib/SP/Services/Export/XmlExportService.php:469 msgid "Exporting accounts" msgstr "Exportando cuentas" -#: lib/SP/Services/Export/XmlExportService.php:583 +#: lib/SP/Services/Export/XmlExportService.php:579 msgid "Error while creating the XML file" msgstr "Error al crear el archivo XML" @@ -4519,18 +4518,18 @@ msgstr "Segundos" msgid "IP address not set" msgstr "Dirección IP no establecida" -#: lib/SP/Services/Upgrade/UpgradeAppService.php:65 -#: lib/SP/Services/Upgrade/UpgradeAppService.php:88 +#: lib/SP/Services/Upgrade/UpgradeAppService.php:66 +#: lib/SP/Services/Upgrade/UpgradeAppService.php:89 msgid "Update Application" msgstr "Actualizar Aplicación" -#: lib/SP/Services/Upgrade/UpgradeAppService.php:72 +#: lib/SP/Services/Upgrade/UpgradeAppService.php:73 msgid "Error while applying the application update" msgstr "Error al aplicar la actualización de la aplicación" -#: lib/SP/Services/Upgrade/UpgradeAppService.php:74 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:100 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:108 +#: lib/SP/Services/Upgrade/UpgradeAppService.php:75 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:101 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:109 msgid "Please, check the event log for more details" msgstr "Compruebe el registro de eventos para más detalles" @@ -4539,36 +4538,36 @@ msgstr "Compruebe el registro de eventos para más detalles" msgid "API authorizations update" msgstr "Actualización de autorizaciones API" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:71 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:207 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:254 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:305 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:72 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:208 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:255 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:306 msgid "Update Configuration" msgstr "Actualizar Configuración" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:83 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:84 msgid "Parameter" msgstr "Parámetro" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:122 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:126 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:123 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:127 msgid "Error while updating the configuration" msgstr "Error al actualizar la configuración" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:282 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:283 msgid "MIME type set for this extension" msgstr "Tipo MIME establecido para esta extensión" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:283 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:284 msgid "MIME type" msgstr "Tipo MIME" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:284 -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:293 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:285 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:294 msgid "Extension" msgstr "Extensión" -#: lib/SP/Services/Upgrade/UpgradeConfigService.php:292 +#: lib/SP/Services/Upgrade/UpgradeConfigService.php:293 msgid "MIME type not found for this extension" msgstr "Tipo MIME no encontrado para esta extensión" @@ -4581,27 +4580,27 @@ msgstr "Tipo MIME no encontrado para esta extensión" msgid "Custom fields update" msgstr "Actualización de campos personalizados" -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:91 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:122 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:92 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:123 msgid "Update DB" msgstr "Actualizar BBDD" -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:98 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:99 msgid "Error while applying an auxiliary update" msgstr "Error al aplicar la actualización auxiliar" -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:106 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:177 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:181 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:107 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:178 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:182 msgid "Error while updating the database" msgstr "Error al aplicar la actualización de la Base de Datos" -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:154 -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:156 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:155 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:157 msgid "Update file does not contain data" msgstr "El archivo de actualización no contiene datos" -#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:187 +#: lib/SP/Services/Upgrade/UpgradeDatabaseService.php:188 msgid "Database updating was completed successfully." msgstr "Actualización de la Base de Datos realizada correctamente." @@ -4683,63 +4682,64 @@ msgstr "Compruebe los datos de conexión" msgid "Error while querying" msgstr "Error en la consulta" -#: lib/SP/Storage/File/FileCachePacked.php:57 +#: lib/SP/Storage/File/FileCachePacked.php:45 #, php-format msgid "Error while decompressing the file data (%s)" msgstr "Error al descomprimir datos del archivo (%s)" -#: lib/SP/Storage/File/FileCachePacked.php:61 +#: lib/SP/Storage/File/FileCachePacked.php:51 msgid "Error while retrieving the data" msgstr "Error al obtener los datos" -#: lib/SP/Storage/File/FileCachePacked.php:99 +#: lib/SP/Storage/File/FileCachePacked.php:70 #, php-format msgid "Error while compressing the file data (%s)" msgstr "Error al comprimir datos del archivo (%s)" -#: lib/SP/Storage/File/FileCachePacked.php:144 -msgid "Data not loaded" -msgstr "Datos no cargados" - -#: lib/SP/Storage/File/FileHandler.php:72 -#: lib/SP/Storage/File/FileHandler.php:135 +#: lib/SP/Storage/File/FileHandler.php:76 +#: lib/SP/Storage/File/FileHandler.php:165 #, php-format msgid "Unable to read/write the file (%s)" msgstr "No es posible leer/escribir el archivo (%s)" -#: lib/SP/Storage/File/FileHandler.php:89 +#: lib/SP/Storage/File/FileHandler.php:101 #, php-format msgid "Unable to open the file (%s)" msgstr "No es posible abrir el archivo (%s)" -#: lib/SP/Storage/File/FileHandler.php:104 -#: lib/SP/Storage/File/FileHandler.php:118 +#: lib/SP/Storage/File/FileHandler.php:119 +#, php-format +msgid "Unable to obtain a lock (%s)" +msgstr "No es posible obtener un bloqueo (%s)" + +#: lib/SP/Storage/File/FileHandler.php:134 +#: lib/SP/Storage/File/FileHandler.php:148 #, php-format msgid "Unable to read from file (%s)" msgstr "No es posible leer desde el archivo (%s)" -#: lib/SP/Storage/File/FileHandler.php:173 +#: lib/SP/Storage/File/FileHandler.php:207 #, php-format msgid "Unable to close the file (%s)" msgstr "No es posible cerrar el archivo (%s)" -#: lib/SP/Storage/File/FileHandler.php:219 +#: lib/SP/Storage/File/FileHandler.php:261 #, php-format msgid "Unable to write in file (%s)" msgstr "No es posible escribir el archivo (%s)" -#: lib/SP/Storage/File/FileHandler.php:234 +#: lib/SP/Storage/File/FileHandler.php:276 #, php-format msgid "File not found (%s)" msgstr "Archivo no encontrado (%s)" -#: lib/SP/Storage/File/FileHandler.php:259 -#: lib/SP/Storage/File/FileHandler.php:314 +#: lib/SP/Storage/File/FileHandler.php:301 +#: lib/SP/Storage/File/FileHandler.php:356 #, php-format msgid "Unable to read/write file (%s)" msgstr "No es posible leer el archivo (%s)" -#: lib/SP/Storage/File/FileHandler.php:286 +#: lib/SP/Storage/File/FileHandler.php:328 #, php-format msgid "Unable to delete file (%s)" msgstr "No es posible eliminar el archivo (%s)" @@ -5412,61 +5412,61 @@ msgstr "La extensión '%s' no está disponible" msgid "This extension is needed to display passwords as images" msgstr "Esta extensión es necesaria para mostrar las claves como imágenes" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:30 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:29 msgid "Searching" msgstr "Búsqueda" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:36 -#: app/modules/web/themes/material-blue/views/config/accounts.inc:52 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:35 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:51 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:56 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:72 msgid "Results per page" msgstr "Resultados por página" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:41 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:40 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:61 msgid "Number of results per page to display when performing a search." msgstr "Número de resultados por página a mostrar, al realizar una búsqueda." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:70 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:69 #: app/modules/web/themes/material-blue/views/itemshow/item_preset-password.inc:30 msgid "Accounts password expiry" msgstr "Caducidad clave cuentas" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:71 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:70 msgid "Enables the accounts password expiry date." msgstr "Habilita la caducidad de la clave de cuentas." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:79 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:78 msgid "Password expiry time" msgstr "Tiempo caducidad clave" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:84 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:83 msgid "Number of days for account's password expiry date." msgstr "Número de días para la caducidad de la clave de cuenta." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:94 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:93 #: app/modules/web/themes/material-blue/views/itemshow/item_preset-password.inc:38 msgid "Expire time (days)" msgstr "Tiempo caducidad (días)" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:112 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:111 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:90 msgid "Account name as link" msgstr "Nombre de cuenta como enlace" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:113 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:112 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:92 msgid "Enables to use the account name as a link to account details." msgstr "" "Habilita el nombre de la cuenta de la búsqueda, como enlace a los detalles " "de la cuenta." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:128 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:127 msgid "Global searches" msgstr "Búsquedas globales" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:129 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:128 msgid "" "Allows the users to do searches that includes all accounts, they won't be " "able to display the account details if they don't have permission." @@ -5474,17 +5474,17 @@ msgstr "" "Permite que todos los usuarios puedan realizar búsquedas en todas las " "cuentas, pero no pueden ver el contenido de las que no tienen permisos." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:144 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:143 #: app/modules/web/themes/material-blue/views/itemshow/item_preset-password.inc:154 msgid "Image to show password" msgstr "Imagen para mostrar clave" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:146 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:145 #: app/modules/web/themes/material-blue/views/itemshow/item_preset-password.inc:156 msgid "Generate an image with a text of the account password." msgstr "Generar una imagen con el texto de la clave de la cuenta." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:148 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:147 #: app/modules/web/themes/material-blue/views/itemshow/item_preset-password.inc:158 msgid "" "Useful for environments where copying a password to clipboard is a security " @@ -5492,27 +5492,27 @@ msgid "" msgstr "" "Util para entornos donde copiar la clave supone un riesgo de seguridad." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:164 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:163 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:158 msgid "Results like Cards" msgstr "Resultados en Tarjetas" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:166 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:165 #: app/modules/web/themes/material-blue/views/usersettings/general.inc:160 msgid "Displays account's search results on a card like format." msgstr "Muestra los resultados de búsqueda de cuentas en formato tarjeta." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:182 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:181 msgid "Secondary Groups Access" msgstr "Acceso Grupos Secundarios" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:184 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:183 msgid "Grants access to users that are included in secondary groups." msgstr "" "Habilita el acceso a los usuarios que estén incluidos en los grupos " "secundarios." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:186 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:185 msgid "" "By default, user in a secondary group is granted if the secondary group is " "set as user's main group." @@ -5521,28 +5521,28 @@ msgstr "" "secundario está establecido como el primario del usuario." #. (itstool) path: action/text -#: app/modules/web/themes/material-blue/views/config/accounts.inc:197 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:196 #: app/modules/web/themes/material-blue/views/itemshow/user_profile.inc:378 #: app/config/actions.xml:73 msgid "Public Links" msgstr "Enlaces Públicos" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:215 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:214 msgid "Enable Public Links" msgstr "Habilitar Enlaces Públicos" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:217 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:216 msgid "Enables the ability to create public links to view an account's details" msgstr "" "Habilita la posibilidad de generar enlaces públicos para ver los detalles de " "una cuenta." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:219 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:218 msgid "Linked accounts will be visible by anyone that have the link." msgstr "" "Las cuentas enlazadas serán visibles por cualquiera que disponga del enlace." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:221 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:220 msgid "" "In order to create links, users must have activated the option on their " "profiles." @@ -5550,43 +5550,43 @@ msgstr "" "Para crear enlaces, los usuarios tienen que tener activada la opción en su " "perfl." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:237 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:236 msgid "Use an image for password" msgstr "Usar imagen para clave" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:239 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:238 msgid "The account password is shown as image." msgstr "La clave de la cuenta es visualizada como una imagen." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:248 -#: app/modules/web/themes/material-blue/views/config/accounts.inc:257 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:247 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:256 msgid "Expire time" msgstr "Tiempo de caducidad" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:263 -#: app/modules/web/themes/material-blue/views/config/accounts.inc:272 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:262 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:271 msgid "Maximum visits" msgstr "Número máximo de visitas" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:298 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:297 #: app/modules/web/themes/material-blue/views/itemshow/user_profile.inc:411 msgid "Files management" msgstr "Gestión de archivos" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:299 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:298 msgid "Enables the uploading and downloading of accounts files." msgstr "Habilita la subida/descarga de archivos para las cuentas." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:307 -#: app/modules/web/themes/material-blue/views/config/accounts.inc:320 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:306 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:319 msgid "Allowed MIME types" msgstr "Tipos MIME permitidos" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:312 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:311 msgid "Allowed file MIME types for uploading." msgstr "Tipos MIME permitidos para subida de archivos" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:315 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:314 msgid "" "In order to add more MIME types, you need to add them into mime.xml file " "within the config directory." @@ -5594,19 +5594,19 @@ msgstr "" "Para añadir más tipos MIME, es necesario modificar el archivo mime.xml en el " "directorio de configuración." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:335 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:334 msgid "Maximum file size" msgstr "Tamaño máximo de archivo" -#: app/modules/web/themes/material-blue/views/config/accounts.inc:340 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:339 msgid "Sets the maximum file size for uploading." msgstr "Establece el tamaño máximo para subir archivos." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:344 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:343 msgid "Absolute maximum is 16MB." msgstr "El máximo absuluto es de 16MB." -#: app/modules/web/themes/material-blue/views/config/accounts.inc:355 +#: app/modules/web/themes/material-blue/views/config/accounts.inc:354 msgid "Maximum file size in kilobytes" msgstr "Tamaño máximo de archivo en kilobytes" @@ -7512,3 +7512,6 @@ msgstr "Área de Texto" #: app/config/strings.xml:8 msgid "Text" msgstr "Texto" + +#~ msgid "Data not loaded" +#~ msgstr "Datos no cargados" diff --git a/app/modules/api/Init.php b/app/modules/api/Init.php index 80de32cd..f74de45f 100644 --- a/app/modules/api/Init.php +++ b/app/modules/api/Init.php @@ -73,6 +73,7 @@ final class Init extends ModuleBase * @throws \DI\DependencyException * @throws \DI\NotFoundException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Storage\File\FileException */ public function initialize($controller) { @@ -82,7 +83,7 @@ final class Init extends ModuleBase $this->context->initialize(); // Load config - $this->config->loadConfig($this->context); + $this->config->loadConfig(); // Load language $this->language->setLanguage(); diff --git a/app/modules/web/Controllers/ControllerBase.php b/app/modules/web/Controllers/ControllerBase.php index ec44329d..4743a0df 100644 --- a/app/modules/web/Controllers/ControllerBase.php +++ b/app/modules/web/Controllers/ControllerBase.php @@ -137,7 +137,7 @@ abstract class ControllerBase $this->view->assign('isDemo', $this->configData->isDemoEnabled()); $this->view->assign('themeUri', $this->view->getTheme()->getThemeUri()); $this->view->assign('configData', $this->configData); - $this->view->assign('sk', $loggedIn ? $this->session->generateSecurityKey() : ''); + $this->view->assign('sk', $loggedIn ? $this->session->generateSecurityKey($this->configData->getPasswordSalt()) : ''); // Pass the action name to the template as a variable $this->view->assign($this->actionName, true); @@ -238,6 +238,7 @@ abstract class ControllerBase $this->checkLoggedInSession( $this->session, $this->request, + $this->configData, function ($redirect) { $this->router->response() ->redirect($redirect) diff --git a/app/modules/web/Controllers/Helpers/LayoutHelper.php b/app/modules/web/Controllers/Helpers/LayoutHelper.php index 93b9de62..1deccf45 100644 --- a/app/modules/web/Controllers/Helpers/LayoutHelper.php +++ b/app/modules/web/Controllers/Helpers/LayoutHelper.php @@ -111,7 +111,7 @@ final class LayoutHelper extends HelperBase $this->loggedIn = $this->context->isLoggedIn(); - $this->view->assign('sk', $this->view->get('sk') ?: $this->context->generateSecurityKey()); + $this->view->assign('sk', $this->view->get('sk') ?: $this->context->generateSecurityKey($this->configData->getPasswordSalt())); $this->view->assign('loggedIn', $this->loggedIn); $this->view->assign('lang', $this->loggedIn ? Language::$userLang : substr(Language::$globalLang, 0, 2)); $this->view->assign('loadApp', $this->context->getAuthCompleted()); diff --git a/app/modules/web/Controllers/SimpleControllerBase.php b/app/modules/web/Controllers/SimpleControllerBase.php index 7d6c57cb..51ee862c 100644 --- a/app/modules/web/Controllers/SimpleControllerBase.php +++ b/app/modules/web/Controllers/SimpleControllerBase.php @@ -78,6 +78,7 @@ abstract class SimpleControllerBase $this->checkLoggedInSession( $this->session, $this->request, + $this->configData, function ($redirect) { $this->router->response() ->redirect($redirect) diff --git a/app/modules/web/Init.php b/app/modules/web/Init.php index ae86bd58..953d707a 100644 --- a/app/modules/web/Init.php +++ b/app/modules/web/Init.php @@ -138,7 +138,7 @@ final class Init extends ModuleBase // Volver a cargar la configuración si se recarga la página if ($this->request->checkReload() === false) { // Cargar la configuración - $this->config->loadConfig($this->context); + $this->config->loadConfig(); // Cargar el lenguaje $this->language->setLanguage(); @@ -151,7 +151,7 @@ final class Init extends ModuleBase $this->context->setAppStatus(SessionContext::APP_STATUS_RELOADED); // Cargar la configuración - $this->config->loadConfig($this->context, true); + $this->config->loadConfig(true); // Restablecer el idioma $this->language->setLanguage(true); @@ -313,9 +313,6 @@ final class Init extends ModuleBase if ($sidStartTime === 0) { // Try to set PHP's session lifetime @ini_set('session.gc_maxlifetime', $this->getSessionLifeTime()); - - $this->context->setSidStartTime(time()); - $this->context->setStartActivity(time()); } else if (!$inMaintenance && time() > ($sidStartTime + SessionContext::MAX_SID_TIME) && $this->context->isLoggedIn() diff --git a/app/modules/web/themes/material-blue/views/config/accounts.inc b/app/modules/web/themes/material-blue/views/config/accounts.inc index 726adcf0..be466f87 100644 --- a/app/modules/web/themes/material-blue/views/config/accounts.inc +++ b/app/modules/web/themes/material-blue/views/config/accounts.inc @@ -22,7 +22,6 @@
diff --git a/app/modules/web/themes/material-blue/views/config/general.inc b/app/modules/web/themes/material-blue/views/config/general.inc index 1030a51f..e5f6a801 100644 --- a/app/modules/web/themes/material-blue/views/config/general.inc +++ b/app/modules/web/themes/material-blue/views/config/general.inc @@ -9,7 +9,6 @@ includeTemplate('general-site'); ?> diff --git a/lib/Definitions.php b/lib/Definitions.php index ee17285d..65a07178 100644 --- a/lib/Definitions.php +++ b/lib/Definitions.php @@ -55,7 +55,10 @@ return [ } }, Config::class => function (ContainerInterface $c) { - return new Config(new XmlHandler(new FileHandler(CONFIG_FILE)), $c->get(ContextInterface::class), $c); + return new Config( + new XmlHandler(new FileHandler(CONFIG_FILE)), + new FileCache(Config::CONFIG_CACHE_FILE), + $c); }, ConfigData::class => function (Config $config) { return $config->getConfigData(); diff --git a/lib/SP/Config/Config.php b/lib/SP/Config/Config.php index f65d979a..e0a1e794 100644 --- a/lib/SP/Config/Config.php +++ b/lib/SP/Config/Config.php @@ -24,12 +24,12 @@ namespace SP\Config; -use DI\Container; use Psr\Container\ContainerInterface; use ReflectionObject; use SP\Core\Context\ContextInterface; use SP\Core\Exceptions\ConfigException; use SP\Services\Config\ConfigBackupService; +use SP\Storage\File\FileCacheInterface; use SP\Storage\File\FileException; use SP\Storage\File\XmlFileStorageInterface; use SP\Util\PasswordUtil; @@ -41,10 +41,18 @@ defined('APP_ROOT') || die(); */ final class Config { + /** + * Cache file name + */ + const CONFIG_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'config.cache'; /** * @var int */ private static $timeUpdated; + /** + * @var ContextInterface + */ + private $context; /** * @var bool */ @@ -54,13 +62,13 @@ final class Config */ private $configData; /** - * @var \SP\Storage\File\XmlFileStorageInterface + * @var XmlFileStorageInterface */ private $fileStorage; /** - * @var ContextInterface + * @var FileCacheInterface */ - private $context; + private $fileCache; /** * @var ContainerInterface */ @@ -69,16 +77,17 @@ final class Config /** * Config constructor. * - * @param \SP\Storage\File\XmlFileStorageInterface $fileStorage - * @param ContextInterface $session - * @param Container $dic + * @param XmlFileStorageInterface $fileStorage + * @param FileCacheInterface $fileCache + * @param ContainerInterface $dic * * @throws ConfigException */ - public function __construct(XmlFileStorageInterface $fileStorage, ContextInterface $session, Container $dic) + public function __construct(XmlFileStorageInterface $fileStorage, FileCacheInterface $fileCache, ContainerInterface $dic) { - $this->context = $session; + $this->fileCache = $fileCache; $this->fileStorage = $fileStorage; + $this->context = $dic->get(ContextInterface::class); $this->dic = $dic; $this->initialize(); @@ -91,24 +100,48 @@ final class Config { if (!$this->configLoaded) { try { - if (file_exists($this->fileStorage->getFileHandler()->getFile())) { - $this->configData = $this->loadConfigFromFile(); + if ($this->fileCache->exists() + && !$this->checkCacheDate() + ) { + logger('Config cache loaded'); + $this->configData = $this->fileCache->load(); } else { - $this->saveConfig(new ConfigData(), false); + if (file_exists($this->fileStorage->getFileHandler()->getFile())) { + $this->configData = $this->loadConfigFromFile(); + $this->fileCache->save($this->configData); + } else { + $this->saveConfig(new ConfigData(), false); + } + + logger('Config loaded'); } self::$timeUpdated = $this->configData->getConfigDate(); $this->configLoaded = true; - - logger('Config loaded'); } catch (\Exception $e) { processException($e); - throw new ConfigException($e->getMessage(), ConfigException::CRITICAL, null, $e->getCode(), $e); + throw new ConfigException($e->getMessage(), + ConfigException::CRITICAL, + null, + $e->getCode(), + $e); } } } + /** + * @return bool + */ + private function checkCacheDate() + { + try { + return $this->fileCache->isExpiredDate($this->fileStorage->getFileHandler()->getFileTime()); + } catch (FileException $e) { + return true; + } + } + /** * Cargar el archivo de configuración * @@ -144,8 +177,6 @@ final class Config * * @return Config * @throws FileException - * @throws \DI\DependencyException - * @throws \DI\NotFoundException */ public function saveConfig(ConfigData $configData, $backup = true) { @@ -159,6 +190,7 @@ final class Config $configData->setConfigHash(); $this->fileStorage->save($configData, 'config'); + $this->fileCache->save($configData); $this->configData = $configData; @@ -196,37 +228,30 @@ final class Config /** * Cargar la configuración desde el contexto * - * @param ContextInterface $context - * @param bool $reload + * @param bool $reload * * @return ConfigData */ - public function loadConfig(ContextInterface $context, $reload = false) + public function loadConfig($reload = false) { - $configData = $context->getConfig(); + try { + $configData = $this->fileCache->load(); - if ($reload === true - || $configData === null - || time() >= ($context->getConfigTime() + $configData->getSessionTimeout() / 2) - ) { - return $this->saveConfigInSession($context); + if ($reload === true + || $configData === null + || !$this->checkCacheDate() + ) { + $this->configData = $this->loadConfigFromFile(); + $this->fileCache->save($this->configData); + + return $this->configData; + } + + return $configData; + } catch (FileException $e) { + processException($e); } - return $configData; - } - - /** - * Guardar la configuración en la sesión - * - * @param ContextInterface $context - * - * @return ConfigData - */ - private function saveConfigInSession(ContextInterface $context) - { - $context->setConfig($this->configData); - $context->setConfigTime(time()); - return $this->configData; } @@ -241,8 +266,6 @@ final class Config /** * @return Config * @throws FileException - * @throws \DI\DependencyException - * @throws \DI\NotFoundException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public function generateUpgradeKey() diff --git a/lib/SP/Core/Context/ContextInterface.php b/lib/SP/Core/Context/ContextInterface.php index 4b4dc439..d4ebc35f 100644 --- a/lib/SP/Core/Context/ContextInterface.php +++ b/lib/SP/Core/Context/ContextInterface.php @@ -24,7 +24,6 @@ namespace SP\Core\Context; -use SP\Config\ConfigData; use SP\DataModel\Dto\AccountCache; use SP\DataModel\ProfileData; use SP\Services\User\UserLoginResponse; @@ -41,13 +40,6 @@ interface ContextInterface */ public function initialize(); - /** - * Establecer la configuración - * - * @param ConfigData $config - */ - public function setConfig(ConfigData $config); - /** * Establecer la hora de carga de la configuración * @@ -103,22 +95,17 @@ interface ContextInterface public function getSecurityKey(); /** + * @param string $salt + * * @return string */ - public function generateSecurityKey(); + public function generateSecurityKey(string $salt); /** * @param $sk */ public function setSecurityKey($sk); - /** - * Devolver la configuración - * - * @return ConfigData - */ - public function getConfig(); - /** * Establecer el lenguaje de la sesión * diff --git a/lib/SP/Core/Context/SessionContext.php b/lib/SP/Core/Context/SessionContext.php index e7c0e2ff..50842702 100644 --- a/lib/SP/Core/Context/SessionContext.php +++ b/lib/SP/Core/Context/SessionContext.php @@ -24,7 +24,6 @@ namespace SP\Core\Context; -use SP\Config\ConfigData; use SP\Core\Crypt\Vault; use SP\DataModel\Dto\AccountCache; use SP\DataModel\ProfileData; @@ -139,16 +138,6 @@ final class SessionContext extends ContextBase return null; } - /** - * Establecer la configuración - * - * @param ConfigData $config - */ - public function setConfig(ConfigData $config) - { - $this->setContextKey('config', $config); - } - /** * Establecer la hora de carga de la configuración * @@ -288,11 +277,13 @@ final class SessionContext extends ContextBase } /** + * @param string $salt + * * @return string */ - public function generateSecurityKey() + public function generateSecurityKey(string $salt) { - return $this->setSecurityKey(sha1(time() . $this->getConfig()->getPasswordSalt())); + return $this->setSecurityKey(sha1(time() . $salt)); } /** @@ -305,16 +296,6 @@ final class SessionContext extends ContextBase return $this->setContextKey('sk', $sk); } - /** - * Devolver la configuración - * - * @return ConfigData - */ - public function getConfig() - { - return $this->getContextKey('config'); - } - /** * Devolver la clave pública * @@ -379,30 +360,6 @@ final class SessionContext extends ContextBase $this->setContextKey('lastActivity', $time); } - /** - * Devuelve la hora en la que el SID de sesión fue creado - * - * @return int - */ - public function getSidStartTime() - { - return $this->getContextKey('sidStartTime', 0); - } - - /** - * Establece la hora de creación del SID - * - * @param $time int La marca de hora - * - * @return int - */ - public function setSidStartTime($time) - { - $this->setContextKey('sidStartTime', $time); - - return $time; - } - /** * Devuelve la hora de inicio de actividad. * @@ -413,20 +370,6 @@ final class SessionContext extends ContextBase return $this->getContextKey('startActivity', 0); } - /** - * Establece la hora de inicio de actividad - * - * @param $time int La marca de hora - * - * @return int - */ - public function setStartActivity($time) - { - $this->setContextKey('startActivity', $time); - - return $time; - } - /** * Establecer el lenguaje de la sesión * @@ -548,6 +491,49 @@ final class SessionContext extends ContextBase } $this->setContextReference($_SESSION); + + if ($this->getSidStartTime() === 0) { + $this->setSidStartTime(time()); + $this->setStartActivity(time()); + } + } + + /** + * Devuelve la hora en la que el SID de sesión fue creado + * + * @return int + */ + public function getSidStartTime() + { + return $this->getContextKey('sidStartTime', 0); + } + + /** + * Establece la hora de creación del SID + * + * @param $time int La marca de hora + * + * @return int + */ + public function setSidStartTime($time) + { + $this->setContextKey('sidStartTime', $time); + + return $time; + } + + /** + * Establece la hora de inicio de actividad + * + * @param $time int La marca de hora + * + * @return int + */ + public function setStartActivity($time) + { + $this->setContextKey('startActivity', $time); + + return $time; } /** diff --git a/lib/SP/Core/Context/StatelessContext.php b/lib/SP/Core/Context/StatelessContext.php index 5652e8e2..127dff30 100644 --- a/lib/SP/Core/Context/StatelessContext.php +++ b/lib/SP/Core/Context/StatelessContext.php @@ -24,7 +24,6 @@ namespace SP\Core\Context; -use SP\Config\ConfigData; use SP\DataModel\ProfileData; use SP\Services\User\UserLoginResponse; @@ -35,16 +34,6 @@ use SP\Services\User\UserLoginResponse; */ final class StatelessContext extends ContextBase { - /** - * Establecer la configuración - * - * @param ConfigData $config - */ - public function setConfig(ConfigData $config) - { - $this->setContextKey('config', $config); - } - /** * Establecer una variable de sesión * @@ -144,11 +133,13 @@ final class StatelessContext extends ContextBase } /** + * @param string $salt + * * @return string */ - public function generateSecurityKey() + public function generateSecurityKey(string $salt) { - return $this->setSecurityKey(sha1(time() . $this->getConfig()->getPasswordSalt())); + return $this->setSecurityKey(sha1(time() . $salt)); } /** @@ -161,16 +152,6 @@ final class StatelessContext extends ContextBase return $this->setContextKey('sk', $sk); } - /** - * Devolver la configuración - * - * @return ConfigData - */ - public function getConfig() - { - return $this->getContextKey('config'); - } - /** * Establecer el lenguaje de la sesión * diff --git a/lib/SP/Mvc/Controller/ControllerTrait.php b/lib/SP/Mvc/Controller/ControllerTrait.php index a42be6d3..9b17082b 100644 --- a/lib/SP/Mvc/Controller/ControllerTrait.php +++ b/lib/SP/Mvc/Controller/ControllerTrait.php @@ -24,6 +24,7 @@ namespace SP\Mvc\Controller; +use SP\Config\ConfigData; use SP\Core\Context\SessionContext; use SP\Core\Exceptions\SPException; use SP\Http\Json; @@ -55,11 +56,13 @@ trait ControllerTrait * * @param SessionContext $context * @param Request $request + * @param ConfigData $configData * @param \Closure $onRedirect * @param bool $requireAuthCompleted */ protected function checkLoggedInSession(SessionContext $context, Request $request, + ConfigData $configData, \Closure $onRedirect, $requireAuthCompleted = true) { @@ -85,7 +88,7 @@ trait ControllerTrait $uri->addParam('_r', 'login'); if ($route && $hash) { - $key = $context->getConfig()->getPasswordSalt(); + $key = $configData->getPasswordSalt(); $request->verifySignature($key); $uri->addParam('from', $route); diff --git a/lib/SP/Services/Account/AccountFilterUser.php b/lib/SP/Services/Account/AccountFilterUser.php index 1f1f0c37..9bce44ec 100644 --- a/lib/SP/Services/Account/AccountFilterUser.php +++ b/lib/SP/Services/Account/AccountFilterUser.php @@ -60,10 +60,12 @@ final class AccountFilterUser * AccountFilterUser constructor. * * @param ContextInterface $context + * @param ConfigData $configData */ - public function __construct(ContextInterface $context) + public function __construct(ContextInterface $context, ConfigData $configData) { $this->context = $context; + $this->configData = $configData; } /** @@ -117,7 +119,6 @@ final class AccountFilterUser */ private function setUp() { - $this->configData = $this->context->getConfig(); $this->userData = $this->context->getUserData(); $this->userProfile = $this->context->getUserProfile(); } diff --git a/lib/SP/Services/Export/XmlExportService.php b/lib/SP/Services/Export/XmlExportService.php index ecb00958..29ee0bd4 100644 --- a/lib/SP/Services/Export/XmlExportService.php +++ b/lib/SP/Services/Export/XmlExportService.php @@ -95,8 +95,6 @@ final class XmlExportService extends Service * @param string $pass string La clave de exportación * * @throws ServiceException - * @throws \DI\DependencyException - * @throws \DI\NotFoundException * @throws \SP\Storage\File\FileException */ public function doExport(string $exportPath, string $pass = null) @@ -134,8 +132,6 @@ final class XmlExportService extends Service * Genera el nombre del archivo usado para la exportación. * * @return string - * @throws \DI\DependencyException - * @throws \DI\NotFoundException * @throws \SP\Storage\File\FileException */ private function generateExportFilename(): string @@ -217,8 +213,8 @@ final class XmlExportService extends Service private function createRoot() { try { - $root = $this->xml->createElement('Root'); - $this->root = $this->xml->appendChild($root); + $this->xml = new \DOMDocument('1.0', 'UTF-8'); + $this->root = $this->xml->appendChild($this->xml->createElement('Root')); } catch (\Exception $e) { throw new ServiceException($e->getMessage(), ServiceException::ERROR, __FUNCTION__); } @@ -624,7 +620,6 @@ final class XmlExportService extends Service { $this->extensionChecker = $this->dic->get(PhpExtensionChecker::class); $this->configData = $this->config->getConfigData(); - $this->xml = new \DOMDocument('1.0', 'UTF-8'); } /** diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php index d57573d7..f4a8776b 100644 --- a/lib/SP/Services/Install/Installer.php +++ b/lib/SP/Services/Install/Installer.php @@ -53,11 +53,11 @@ defined('APP_ROOT') || die(); final class Installer extends Service { /** - * Versión y número de compilación de sysPass + * sysPass' version and build number */ const VERSION = [3, 0, 0]; - const VERSION_TEXT = '3.0-beta'; - const BUILD = 18111001; + const VERSION_TEXT = '3.0-rc1'; + const BUILD = 18111201; /** * @var DatabaseSetupInterface diff --git a/lib/SP/Storage/File/FileCache.php b/lib/SP/Storage/File/FileCache.php index bcf47c42..68e72040 100644 --- a/lib/SP/Storage/File/FileCache.php +++ b/lib/SP/Storage/File/FileCache.php @@ -50,9 +50,10 @@ final class FileCache extends FileCacheBase { $this->createPath(); - $this->path->checkIsWritable() - ->write(serialize($data)) - ->close(); + $this->path->checkIsWritable(); + $this->path->open('wb', true); + $this->path->write(serialize($data)); + $this->path->close(); return $this; } diff --git a/lib/SP/Storage/File/FileCacheBase.php b/lib/SP/Storage/File/FileCacheBase.php index c7bbbb25..394c8202 100644 --- a/lib/SP/Storage/File/FileCacheBase.php +++ b/lib/SP/Storage/File/FileCacheBase.php @@ -47,6 +47,16 @@ abstract class FileCacheBase implements FileCacheInterface $this->path = new FileHandler($path); } + /** + * @param $path + * + * @return FileCacheBase + */ + public static function factory($path) + { + return new static($path); + } + /** * Returns if the file is expired adding time to modification date * @@ -101,12 +111,10 @@ abstract class FileCacheBase implements FileCacheInterface } /** - * @param $path - * - * @return FileCacheBase + * @return bool */ - public static function factory($path) + public function exists(): bool { - return new static($path); + return file_exists($this->path->getFile()); } } \ No newline at end of file diff --git a/lib/SP/Storage/File/FileCacheInterface.php b/lib/SP/Storage/File/FileCacheInterface.php index 944221c8..f10e00de 100644 --- a/lib/SP/Storage/File/FileCacheInterface.php +++ b/lib/SP/Storage/File/FileCacheInterface.php @@ -60,7 +60,7 @@ interface FileCacheInterface public function isExpired($time = 86400): bool; /** - * Returns if the file is expired adding time to modification date + * Returns if the file is expired comparing against a reference date * * @param int $date * @@ -68,4 +68,9 @@ interface FileCacheInterface * @throws FileException */ public function isExpiredDate($date): bool; + + /** + * @return bool + */ + public function exists(): bool; } \ No newline at end of file diff --git a/lib/SP/Storage/File/FileHandler.php b/lib/SP/Storage/File/FileHandler.php index b8845886..f6e27fcb 100644 --- a/lib/SP/Storage/File/FileHandler.php +++ b/lib/SP/Storage/File/FileHandler.php @@ -43,6 +43,10 @@ final class FileHandler * @var resource */ protected $handle; + /** + * @var bool + */ + private $locked = false; /** * FileHandler constructor. @@ -57,7 +61,7 @@ final class FileHandler /** * Writes data into file * - * @param $data + * @param mixed $data * * @return FileHandler * @throws FileException @@ -78,20 +82,46 @@ final class FileHandler /** * Opens the file * - * @param $mode + * @param string $mode + * + * @param bool $lock * * @return resource * @throws FileException */ - public function open($mode = 'r') + public function open($mode = 'r', $lock = false) { - if (($this->handle = @fopen($this->file, $mode)) === false) { + $this->handle = @fopen($this->file, $mode); + + if ($lock && $this->locked === false) { + $this->lock(); + } + + if ($this->handle === false) { throw new FileException(sprintf(__('Unable to open the file (%s)'), $this->file)); } return $this->handle; } + /** + * Lock the file + * + * @param int $mode + * + * @throws FileException + */ + private function lock($mode = LOCK_EX) + { + $this->locked = flock($this->handle, $mode); + + if (!$this->locked) { + throw new FileException(sprintf(__('Unable to obtain a lock (%s)'), $this->file)); + } + + logger(sprintf('File locked: %s', $this->file)); + } + /** * Reads data from file into a string * @@ -169,6 +199,10 @@ final class FileHandler */ public function close() { + if ($this->locked) { + $this->unlock(); + } + if (!is_resource($this->handle) || @fclose($this->handle) === false) { throw new FileException(sprintf(__('Unable to close the file (%s)'), $this->file)); } @@ -176,6 +210,14 @@ final class FileHandler return $this; } + /** + * Unlock the file + */ + private function unlock() + { + $this->locked = !flock($this->handle, LOCK_UN); + } + /** * @param callable $chunker * @param float $rate diff --git a/tests/SP/Config/ConfigTest.php b/tests/SP/Config/ConfigTest.php index d485ae15..6f132f67 100644 --- a/tests/SP/Config/ConfigTest.php +++ b/tests/SP/Config/ConfigTest.php @@ -30,8 +30,8 @@ use DI\NotFoundException; use PHPUnit\Framework\TestCase; use SP\Config\Config; use SP\Config\ConfigData; -use SP\Core\Context\ContextInterface; use function SP\Tests\getResource; +use function SP\Tests\recreateDir; use function SP\Tests\saveResource; use function SP\Tests\setupContext; @@ -60,6 +60,7 @@ class ConfigTest extends TestCase { self::$dic = setupContext(); + // Save current config self::$currentConfig = getResource('config', 'config.xml'); } @@ -68,7 +69,9 @@ class ConfigTest extends TestCase */ public static function tearDownAfterClass() { + // Restore to the initial state saveResource('config', 'config.xml', self::$currentConfig); + recreateDir(CACHE_PATH); } /** @@ -94,13 +97,11 @@ class ConfigTest extends TestCase * * @param Config $config * - * @throws DependencyException - * @throws NotFoundException * @throws \SP\Storage\File\FileException */ public function testSaveConfig($config) { - $config->saveConfig(new ConfigData(), false); + $config->saveConfig($config->getConfigData(), false); $this->assertFileExists(CONFIG_FILE); } @@ -113,16 +114,10 @@ class ConfigTest extends TestCase * * @param Config $config * - * @throws DependencyException - * @throws NotFoundException */ public function testLoadConfig($config) { - $context = self::$dic->get(ContextInterface::class); - - $config->loadConfig($context); - - $this->assertInstanceOf(ConfigData::class, $context->getConfig()); + $this->assertInstanceOf(ConfigData::class, $config->loadConfig()); } /** @@ -134,7 +129,7 @@ class ConfigTest extends TestCase */ public function testUpdateConfig($config) { - $config->updateConfig(new ConfigData()); + $config->updateConfig($config->getConfigData()); $this->assertEquals(Config::getTimeUpdated(), $config->getConfigData()->getConfigDate()); } @@ -147,6 +142,7 @@ class ConfigTest extends TestCase * @param Config $config * * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Storage\File\FileException */ public function testGenerateUpgradeKey($config) { diff --git a/tests/SP/Repositories/PublicLinkRepositoryTest.php b/tests/SP/Repositories/PublicLinkRepositoryTest.php index bb3874b3..46a21752 100644 --- a/tests/SP/Repositories/PublicLinkRepositoryTest.php +++ b/tests/SP/Repositories/PublicLinkRepositoryTest.php @@ -184,7 +184,7 @@ class PublicLinkRepositoryTest extends DatabaseTestCase $this->assertEquals($data->getTypeId(), $resultData->getTypeId()); $this->assertEquals($data->isNotify(), $resultData->isNotify()); $this->assertEquals($data->getDateExpire(), $resultData->getDateExpire()); - $this->assertEquals($data->getDateAdd(), $resultData->getDateAdd()); + $this->assertTrue($data->getDateAdd() >= $resultData->getDateAdd()); $this->assertEquals($data->getMaxCountViews(), $resultData->getMaxCountViews()); $this->expectException(DuplicatedItemException::class); diff --git a/tests/SP/Services/Config/ConfigBackupServiceTest.php b/tests/SP/Services/Config/ConfigBackupServiceTest.php index 723460aa..d260d3ce 100644 --- a/tests/SP/Services/Config/ConfigBackupServiceTest.php +++ b/tests/SP/Services/Config/ConfigBackupServiceTest.php @@ -29,6 +29,7 @@ use SP\Config\Config; use SP\Config\ConfigData; use SP\Services\Config\ConfigBackupService; use function SP\Tests\getResource; +use function SP\Tests\recreateDir; use function SP\Tests\saveResource; use function SP\Tests\setupContext; @@ -52,6 +53,7 @@ class ConfigBackupServiceTest extends TestCase public static function tearDownAfterClass() { saveResource('config', 'config.xml', self::$currentConfig); + recreateDir(CACHE_PATH); } /** diff --git a/tests/SP/Services/Export/XmlExportServiceTest.php b/tests/SP/Services/Export/XmlExportServiceTest.php index faf12a4b..1bc97872 100644 --- a/tests/SP/Services/Export/XmlExportServiceTest.php +++ b/tests/SP/Services/Export/XmlExportServiceTest.php @@ -24,6 +24,7 @@ namespace SP\Tests\Services\Export; +use Defuse\Crypto\Exception\CryptoException; use SP\Services\Export\VerifyResult; use SP\Services\Export\XmlExportService; use SP\Services\Export\XmlVerifyService; @@ -40,6 +41,15 @@ use function SP\Tests\setupContext; */ class XmlExportServiceTest extends DatabaseTestCase { + /** + * @var XmlExportService + */ + private static $xmlExportService; + /** + * @var XmlVerifyService + */ + private static $xmlVerifyService; + /** * @throws \DI\DependencyException * @throws \DI\NotFoundException @@ -55,24 +65,21 @@ class XmlExportServiceTest extends DatabaseTestCase // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + self::$xmlExportService = $dic->get(XmlExportService::class); + self::$xmlVerifyService = $dic->get(XmlVerifyService::class); } /** - * @throws \DI\DependencyException - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException - * @throws \SP\Services\ServiceException + * @throws ServiceException * @throws \SP\Storage\File\FileException */ public function testDoExportWithoutPassword() { - $dic = setupContext(); - $service = $dic->get(XmlExportService::class); - $service->doExport(TMP_DIR); + self::$xmlExportService->doExport(TMP_DIR); - $this->assertFileExists($service->getExportFile()); + $this->assertFileExists(self::$xmlExportService->getExportFile()); - $this->verifyExportWithoutPassword($service->getExportFile()); + $this->verifyExportWithoutPassword(self::$xmlExportService->getExportFile()); } /** @@ -80,18 +87,12 @@ class XmlExportServiceTest extends DatabaseTestCase * * @param $file * - * @throws \DI\DependencyException - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException * @throws \SP\Services\ServiceException * @throws \SP\Storage\File\FileException */ private function verifyExportWithoutPassword($file) { - $dic = setupContext(); - $service = $dic->get(XmlVerifyService::class); - - $result = $service->verify($file); + $result = self::$xmlVerifyService->verify($file); $this->assertInstanceOf(VerifyResult::class, $result); @@ -117,44 +118,32 @@ class XmlExportServiceTest extends DatabaseTestCase } /** - * @throws \DI\DependencyException - * @throws \DI\NotFoundException - * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \SP\Core\Context\ContextException - * @throws \SP\Services\ServiceException + * @throws CryptoException + * @throws ServiceException * @throws \SP\Storage\File\FileException */ public function testDoExportWithPassword() { - $dic = setupContext(); - $service = $dic->get(XmlExportService::class); - $password = PasswordUtil::randomPassword(); - $service->doExport(TMP_DIR, $password); + self::$xmlExportService->doExport(TMP_DIR, $password); - $this->assertFileExists($service->getExportFile()); + $this->assertFileExists(self::$xmlExportService->getExportFile()); - $this->verifyExportWithPassword($service->getExportFile(), $password); + $this->verifyExportWithPassword(self::$xmlExportService->getExportFile(), $password); } /** * @param $file * @param $password * - * @throws \DI\DependencyException - * @throws \DI\NotFoundException - * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \SP\Core\Context\ContextException - * @throws \SP\Services\ServiceException + * @throws CryptoException + * @throws ServiceException * @throws \SP\Storage\File\FileException */ private function verifyExportWithPassword($file, $password) { - $dic = setupContext(); - $service = $dic->get(XmlVerifyService::class); - - $result = $service->verifyEncrypted($file, $password); + $result = self::$xmlVerifyService->verifyEncrypted($file, $password); $this->assertInstanceOf(VerifyResult::class, $result); $this->assertTrue($result->isEncrypted()); @@ -163,6 +152,6 @@ class XmlExportServiceTest extends DatabaseTestCase $this->expectException(ServiceException::class); - $service->verifyEncrypted($file, 'test123'); + self::$xmlVerifyService->verifyEncrypted($file, 'test123'); } } diff --git a/tests/SP/Services/Export/XmlVerifyServiceTest.php b/tests/SP/Services/Export/XmlVerifyServiceTest.php index 5b048ef1..0030244d 100644 --- a/tests/SP/Services/Export/XmlVerifyServiceTest.php +++ b/tests/SP/Services/Export/XmlVerifyServiceTest.php @@ -36,23 +36,33 @@ use function SP\Tests\setupContext; */ class XmlVerifyServiceTest extends TestCase { + /** + * @var XmlVerifyService + */ + private static $xmlVerifyService; /** * @throws \DI\DependencyException * @throws \DI\NotFoundException - * @throws \Defuse\Crypto\Exception\CryptoException * @throws \SP\Core\Context\ContextException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + self::$xmlVerifyService = $dic->get(XmlVerifyService::class); + } + + /** + * @throws \Defuse\Crypto\Exception\CryptoException * @throws \SP\Services\ServiceException * @throws \SP\Storage\File\FileException */ public function testVerifyEncrypted() { - $dic = setupContext(); - $service = $dic->get(XmlVerifyService::class); - $file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass_encrypted.xml'; - $result = $service->verifyEncrypted($file, 'test_encrypt'); + $result = self::$xmlVerifyService->verifyEncrypted($file, 'test_encrypt'); $this->assertInstanceOf(VerifyResult::class, $result); $this->assertEquals(300.18082201, $result->getVersion()); @@ -67,20 +77,14 @@ class XmlVerifyServiceTest extends TestCase } /** - * @throws \DI\DependencyException - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException * @throws \SP\Services\ServiceException * @throws \SP\Storage\File\FileException */ public function testVerify() { - $dic = setupContext(); - $service = $dic->get(XmlVerifyService::class); - $file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'import' . DIRECTORY_SEPARATOR . 'data_syspass.xml'; - $result = $service->verify($file); + $result = self::$xmlVerifyService->verify($file); $this->assertInstanceOf(VerifyResult::class, $result); $this->assertEquals(300.18071701, $result->getVersion()); diff --git a/tests/SP/Services/Install/InstallerTest.php b/tests/SP/Services/Install/InstallerTest.php index d14d2944..987f021e 100644 --- a/tests/SP/Services/Install/InstallerTest.php +++ b/tests/SP/Services/Install/InstallerTest.php @@ -35,6 +35,7 @@ use SP\Storage\Database\DBStorageInterface; use SP\Tests\DatabaseUtil; use SP\Util\PasswordUtil; use function SP\Tests\getResource; +use function SP\Tests\recreateDir; use function SP\Tests\saveResource; use function SP\Tests\setupContext; @@ -70,6 +71,7 @@ class InstallerTest extends TestCase public static function tearDownAfterClass() { saveResource('config', 'config.xml', self::$currentConfig); + recreateDir(CACHE_PATH); } /** diff --git a/tests/SP/bootstrap.php b/tests/SP/bootstrap.php index 00cc5307..dba1636b 100644 --- a/tests/SP/bootstrap.php +++ b/tests/SP/bootstrap.php @@ -25,7 +25,6 @@ namespace SP\Tests; use DI\ContainerBuilder; -use SP\Config\ConfigData; use SP\Core\Context\ContextInterface; use SP\DataModel\ProfileData; use SP\Services\User\UserLoginResponse; @@ -113,10 +112,6 @@ function setupContext() $context = $dic->get(ContextInterface::class); $context->initialize(); -// $configData = new ConfigData(); -// $configData->setPasswordSalt('fd1058ca0bbaf967d08184ed22ee2c8d5675ca0c9d569c1f237f23fefadf'); - - $context->setConfig($dic->get(ConfigData::class)); $context->setTrasientKey('_masterpass', '12345678900'); $userData = new UserLoginResponse(); @@ -129,9 +124,6 @@ function setupContext() $context->setUserProfile(new ProfileData()); - // Inicializar la configuración -// $dic->set(ConfigData::class, $configData); - // Inicializar los datos de conexión a la BBDD $dic->set(DBStorageInterface::class, getDbHandler()); diff --git a/tests/res/config/config.xml b/tests/res/config/config.xml index f48f7344..b6a94ba3 100644 --- a/tests/res/config/config.xml +++ b/tests/res/config/config.xml @@ -9,11 +9,11 @@ 1 1 - 335463b295db194139a4483b30bed5dc4a8e8fab + d076af62e68e3974a8c80d75bfd6fef31fcb9073 0 0 - 1541937033 - c80d905efab57187b4a1f32374fafbcff3c4d57b + 1541977640 + 71556fad3a4bf8a87356c496fb4afca8c980c424 @@ -32,7 +32,7 @@ 0 - d101e3b4cfc15c62090eb1c5f737a454e9a7c35e + e64dc162b9c052e097f7abd149bffcaccdd72d63 PDF JPG diff --git a/tests/res/datasets/syspass_import.xml b/tests/res/datasets/syspass_import.xml index e634ba18..9a5616e6 100644 --- a/tests/res/datasets/syspass_import.xml +++ b/tests/res/datasets/syspass_import.xml @@ -1,6 +1,146 @@ + + + 1 + Admins + sysPass Admins + + + 2 + Demo + + + + 3 + Usuarios + Grupo Usuarios + + + + + 1 + Admin + 4F3A32343A2253505C446174614D6F64656C5C50726F66696C6544617461223A32393A7B733A31303A22002A0061636356696577223B623A303B733A31343A22002A006163635669657750617373223B623A303B733A31373A22002A0061636356696577486973746F7279223B623A303B733A31303A22002A0061636345646974223B623A303B733A31343A22002A006163634564697450617373223B623A303B733A393A22002A00616363416464223B623A303B733A31323A22002A0061636344656C657465223B623A303B733A31313A22002A0061636346696C6573223B623A303B733A31333A22002A0061636350726976617465223B623A313B733A31383A22002A006163635072697661746547726F7570223B623A313B733A31363A22002A006163635065726D697373696F6E223B623A303B733A31373A22002A006163635075626C69634C696E6B73223B623A303B733A31383A22002A00616363476C6F62616C536561726368223B623A303B733A31363A22002A00636F6E66696747656E6572616C223B623A303B733A31393A22002A00636F6E666967456E6372797074696F6E223B623A303B733A31353A22002A00636F6E6669674261636B7570223B623A303B733A31353A22002A00636F6E666967496D706F7274223B623A303B733A31313A22002A006D676D5573657273223B623A303B733A31323A22002A006D676D47726F757073223B623A303B733A31343A22002A006D676D50726F66696C6573223B623A303B733A31363A22002A006D676D43617465676F72696573223B623A303B733A31353A22002A006D676D437573746F6D657273223B623A303B733A31353A22002A006D676D417069546F6B656E73223B623A303B733A31373A22002A006D676D5075626C69634C696E6B73223B623A303B733A31343A22002A006D676D4163636F756E7473223B623A303B733A31303A22002A006D676D54616773223B623A303B733A31313A22002A006D676D46696C6573223B623A303B733A363A22002A0065766C223B623A303B733A31383A22002A006D676D437573746F6D4669656C6473223B623A303B7D + + + 2 + Demo + 4F3A32343A2253505C446174614D6F64656C5C50726F66696C6544617461223A32393A7B733A31303A22002A0061636356696577223B623A313B733A31343A22002A006163635669657750617373223B623A313B733A31373A22002A0061636356696577486973746F7279223B623A313B733A31303A22002A0061636345646974223B623A313B733A31343A22002A006163634564697450617373223B623A313B733A393A22002A00616363416464223B623A313B733A31323A22002A0061636344656C657465223B623A313B733A31313A22002A0061636346696C6573223B623A303B733A31333A22002A0061636350726976617465223B623A303B733A31383A22002A006163635072697661746547726F7570223B623A303B733A31363A22002A006163635065726D697373696F6E223B623A303B733A31373A22002A006163635075626C69634C696E6B73223B623A303B733A31383A22002A00616363476C6F62616C536561726368223B623A303B733A31363A22002A00636F6E66696747656E6572616C223B623A303B733A31393A22002A00636F6E666967456E6372797074696F6E223B623A303B733A31353A22002A00636F6E6669674261636B7570223B623A303B733A31353A22002A00636F6E666967496D706F7274223B623A303B733A31313A22002A006D676D5573657273223B623A303B733A31323A22002A006D676D47726F757073223B623A303B733A31343A22002A006D676D50726F66696C6573223B623A303B733A31363A22002A006D676D43617465676F72696573223B623A303B733A31353A22002A006D676D437573746F6D657273223B623A303B733A31353A22002A006D676D417069546F6B656E73223B623A303B733A31373A22002A006D676D5075626C69634C696E6B73223B623A303B733A31343A22002A006D676D4163636F756E7473223B623A303B733A31303A22002A006D676D54616773223B623A303B733A31313A22002A006D676D46696C6573223B623A303B733A363A22002A0065766C223B623A303B733A31383A22002A006D676D437573746F6D4669656C6473223B623A303B7D + + + 3 + Usuarios + 4F3A32343A2253505C446174614D6F64656C5C50726F66696C6544617461223A32393A7B733A31303A22002A0061636356696577223B623A313B733A31343A22002A006163635669657750617373223B623A313B733A31373A22002A0061636356696577486973746F7279223B623A313B733A31303A22002A0061636345646974223B623A313B733A31343A22002A006163634564697450617373223B623A313B733A393A22002A00616363416464223B623A313B733A31323A22002A0061636344656C657465223B623A313B733A31313A22002A0061636346696C6573223B623A303B733A31333A22002A0061636350726976617465223B623A303B733A31383A22002A006163635072697661746547726F7570223B623A303B733A31363A22002A006163635065726D697373696F6E223B623A303B733A31373A22002A006163635075626C69634C696E6B73223B623A303B733A31383A22002A00616363476C6F62616C536561726368223B623A303B733A31363A22002A00636F6E66696747656E6572616C223B623A303B733A31393A22002A00636F6E666967456E6372797074696F6E223B623A303B733A31353A22002A00636F6E6669674261636B7570223B623A303B733A31353A22002A00636F6E666967496D706F7274223B623A303B733A31313A22002A006D676D5573657273223B623A303B733A31323A22002A006D676D47726F757073223B623A303B733A31343A22002A006D676D50726F66696C6573223B623A303B733A31363A22002A006D676D43617465676F72696573223B623A303B733A31353A22002A006D676D437573746F6D657273223B623A303B733A31353A22002A006D676D417069546F6B656E73223B623A303B733A31373A22002A006D676D5075626C69634C696E6B73223B623A303B733A31343A22002A006D676D4163636F756E7473223B623A303B733A31303A22002A006D676D54616773223B623A303B733A31313A22002A006D676D46696C6573223B623A303B733A363A22002A0065766C223B623A303B733A31383A22002A006D676D437573746F6D4669656C6473223B623A303B7D + + + + + 1 + sysPass Admin + 1 + admin + + 243279243130247635695230547A4933744E3036416A304C4A656B39755371496834356C70575539366E644A71444A704E6969713139306A444A486D + 64656635303230306330383635633335373637316233366261353266333137346134356466333633626135656431613962323261356461353965376134373930356664656239373436356462373934613831373635316133316432626363636266663836626233353235643930333932393734323535663937316261616239656436346637383266363066646465386539336637363164356663633436393031356433363164333234643436633533633138313335613334663739633039 + 6465663130303030646566353032303062316163626161346361643036643237386562323533616462643433613966376463636439343063656265313962343061383436643464633035303636306466653630613561653139363433643636353936643733333764646236386536363930336562383031373764356463386430663963623661643361663565643766303936376262393964663530373936316330656132373462663830346333663966373563336538643539396336326231623738333730303963616263373836383637366433636337376162383365386338323335336335626164396534656535333532656132346632653434653663316336656131643162313264393332386335303539623437656235343534666138356435626437343637353333383132636662313230316634633635383733316465323934613664643035396332613362373333613765343462633539306338363337393032306662303263363262303565613030623234646235323566653863303263323138666561356661353139306563396266333461316637613937633733396637343534323333316466323932343965323138656338343233306161623038373336346463353236363935383630656638623232313439626262656636656266373030366638376434343661333535353863323062353462376336623330 + + + 81 + 1 + 2018-04-19 23:46:48 + + 1521887152 + 1 + 0 + 0 + 0 + + 0 + 0 + 0 + 4F3A33323A2253505C446174614D6F64656C5C55736572507265666572656E63657344617461223A31303A7B733A373A22757365725F6964223B693A313B733A363A22757365324661223B623A303B733A343A226C616E67223B733A353A22656E5F5553223B733A353A227468656D65223B733A31333A226D6174657269616C2D626C7565223B733A31343A22726573756C747350657250616765223B693A34383B733A31313A226163636F756E744C696E6B223B623A313B733A393A22736F72745669657773223B623A303B733A393A22746F704E6176626172223B623A303B733A31353A226F7074696F6E616C416374696F6E73223B623A303B733A31343A22726573756C747341734361726473223B623A303B7D + + + 2 + sysPass demo + 2 + demo + demo + 2432792431302454726E69756C5763754361433635346F76566F35392E766B4C5433414E31624A6D726A79553462696335325069436A6B5572396669 + 64656635303230303231616533353730373263373165626239393534353966366236636164373235336534316336633534353036336339326136653730616366333930393165373934613865376662386662326664333931383932363562396466303133333631623063323732323339653465373165343839313030646534326265633737623966343238396635633936613837646531343864313963653663643338613131343932623163313765653630326430623532343564346566 + 6465663130303030646566353032303035643534316262633462653032333563313338626561366561333536626436663037353365313035653030333563653166316235336534663364343565366262353335626163396639646538653131316262356334383865336535633637323333666632626365313837626335386135353839373535373034386564353634366361646638623736396132323164363032353435653034306264613135663138323638383665373536313236353361313037306530333261323365636364336339616438323162306363383962643130333035303931653965626332653935313465656631373462663339343664656132393661346262366264343463646333363361643335623032373561356633323430313936346531633131663937313764313139633130633561373161666332356365346534366661623234646663626362326237303964336335316532623834326464303933653230353965373265356638376363366236626239306231346265376264373637663163303937366231313362393630613265636565336633313131663538656131346139353736623332653163303962636435313366383733656664653062373333366238643464646637616237323333373038613264393965633738356139393036306135643262316366306262663739346262663765 + demo@syspass.org + aaaa + 12 + 2 + 2018-04-01 21:29:47 + 2018-04-14 08:47:43 + 1522582852 + 0 + 0 + 0 + 0 + + 0 + 0 + 0 + + + + 3 + User A + 2 + user_a + user_a + 2432792431302469444B442E2F4F624D79742E6F43594F5249514D5065624454783966744D636A703034365A435976662E765479597A594F6A4C472E + + + user_a@syspass.org + + 0 + 1 + + 2018-04-14 08:48:08 + 0 + 0 + 0 + 0 + 0 + + 0 + 0 + 0 + + + + 4 + User B + 2 + user_b + + 243279243130244C37643658736A663955794F6E583662472E6F384E4F713961674B6F64536B4B5674485350462F6861414E657971517065372E6532 + + + user_b@syspass.org + + 0 + 1 + + 2018-03-30 18:38:32 + 0 + 0 + 0 + 0 + 0 + + 0 + 0 + 0 + + + 1