diff --git a/.env.example b/.env.example index de3a1660..9100a77b 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,26 @@ +# Please, notice that this path could be outside the webserver root. You can move it and then update accordingly # CONFIG_PATH="/var/www/html/syspass/app/config" + +# This path should be accesible by the webserver since backups and export files could be downloaded from the UI # BACKUP_PATH="/var/www/html/syspass/app/backup" + +# This path could be outside the webserver root and preferably in a separate partition, because it will store a lot of small files for caching purposes # CACHE_PATH="/var/www/html/syspass/app/cache" + +# This path could be outside the webserver root # TMP_PATH="/var/www/html/syspass/app/temp" + +# The main configuration file # CONFIG_FILE="config.xml" + +# Actions file is meant to contain all the actions supported by the application # ACTIONS_FILE="actions.xml" + +# Mime types file is meant to contain all the mimetypes supported by the application (from https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types) # MIMETYPES_FILE="mime.xml" + +# The log file will be used to log all the actions and error messages from the application. It could outside the websever root. # LOG_FILE="syspass.log" + +# Whether to enable (true) or disable (false) the debug mode. It's useful when trying to solve some issues and developing # DEBUG=true \ No newline at end of file diff --git a/app/modules/api/Controllers/AccountController.php b/app/modules/api/Controllers/AccountController.php index 70a0405a..1a5d9323 100644 --- a/app/modules/api/Controllers/AccountController.php +++ b/app/modules/api/Controllers/AccountController.php @@ -27,12 +27,16 @@ namespace SP\Modules\Api\Controllers; use DI\DependencyException; use DI\NotFoundException; use Exception; +use League\Fractal\Resource\Item; +use SP\Adapters\AccountAdapter; use SP\Core\Acl\ActionsInterface; use SP\Core\Crypt\Crypt; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\InvalidClassException; +use SP\DataModel\Dto\AccountDetailsResponse; use SP\Modules\Api\Controllers\Help\AccountHelp; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\Model\QueryCondition; use SP\Services\Account\AccountPresetService; use SP\Services\Account\AccountRequest; @@ -47,6 +51,8 @@ use SP\Services\Api\ApiResponse; */ final class AccountController extends ControllerBase { + use ItemTrait; + /** * @var AccountPresetService */ @@ -61,14 +67,28 @@ final class AccountController extends ControllerBase */ public function viewAction() { + try { $this->setupApi(ActionsInterface::ACCOUNT_VIEW); $id = $this->apiService->getParamInt('id', true); + $customFields = boolval($this->apiService->getParamString('customFields')); + + if ($customFields) { + $this->apiService->requireMasterPass(); + } + $accountDetails = $this->accountService->getById($id)->getAccountVData(); $this->accountService->incrementViewCounter($id); + $accountResponse = new AccountDetailsResponse($id, $accountDetails); + + $this->accountService + ->withUsersById($accountResponse) + ->withUserGroupsById($accountResponse) + ->withTagsById($accountResponse); + $this->eventDispatcher->notifyEvent('show.account', new Event($this, EventMessage::factory() ->addDescription(__u('Account displayed')) @@ -77,7 +97,15 @@ final class AccountController extends ControllerBase ->addDetail('ID', $id)) ); - $this->returnResponse(ApiResponse::makeSuccess($accountDetails, $id)); + $adapter = new AccountAdapter($this->configData); + + if ($customFields) { + $adapter->withCustomFields($this->getCustomFieldsForItem(ActionsInterface::ACCOUNT, $id)); + } + + $item = new Item($accountResponse, $adapter); + + $this->returnResponse(ApiResponse::makeSuccess($this->fractal->createData($item)->toArray(), $id)); } catch (Exception $e) { $this->returnResponseException($e); diff --git a/app/modules/api/Controllers/ControllerBase.php b/app/modules/api/Controllers/ControllerBase.php index f5bcdfcf..23e1df24 100644 --- a/app/modules/api/Controllers/ControllerBase.php +++ b/app/modules/api/Controllers/ControllerBase.php @@ -29,7 +29,10 @@ use DI\DependencyException; use DI\NotFoundException; use Exception; use Klein\Klein; +use League\Fractal\Manager; use Psr\Container\ContainerInterface; +use SP\Config\ConfigData; +use SP\Core\Acl\Acl; use SP\Core\Context\StatelessContext; use SP\Core\Events\EventDispatcher; use SP\Core\Exceptions\SPException; @@ -75,6 +78,18 @@ abstract class ControllerBase * @var Klein */ protected $router; + /** + * @var ConfigData + */ + protected $configData; + /** + * @var Manager + */ + protected $fractal; + /** + * @var Acl + */ + protected $acl; /** * @var bool */ @@ -93,9 +108,12 @@ abstract class ControllerBase { $this->dic = $container; $this->context = $container->get(StatelessContext::class); + $this->configData = $container->get(ConfigData::class); $this->eventDispatcher = $container->get(EventDispatcher::class); $this->router = $container->get(Klein::class); $this->apiService = $container->get(ApiService::class); + $this->acl = $container->get(Acl::class); + $this->fractal = new Manager(); $this->controllerName = $this->getControllerName(); $this->actionName = $actionName; diff --git a/app/modules/api/Controllers/Help/AccountHelp.php b/app/modules/api/Controllers/Help/AccountHelp.php index 4e9c26bf..e5f3632a 100644 --- a/app/modules/api/Controllers/Help/AccountHelp.php +++ b/app/modules/api/Controllers/Help/AccountHelp.php @@ -40,7 +40,9 @@ final class AccountHelp implements HelpInterface { return [ - self::getItem('id', __('Account Id'), true) + self::getItem('id', __('Account Id'), true), + self::getItem('customFields', __('Get custom fields for the account within the response')), + self::getItem('tokenPass', __('Token\'s password when custom fields are retrieved'), true) ]; } diff --git a/app/modules/web/Controllers/AccountController.php b/app/modules/web/Controllers/AccountController.php index 43d6ea85..e358bc28 100644 --- a/app/modules/web/Controllers/AccountController.php +++ b/app/modules/web/Controllers/AccountController.php @@ -53,10 +53,10 @@ use SP\Modules\Web\Controllers\Helpers\Account\AccountHistoryHelper; use SP\Modules\Web\Controllers\Helpers\Account\AccountPasswordHelper; use SP\Modules\Web\Controllers\Helpers\Account\AccountSearchHelper; use SP\Modules\Web\Controllers\Helpers\LayoutHelper; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\AccountForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Repositories\NoSuchItemException; use SP\Services\Account\AccountAclService; use SP\Services\Account\AccountHistoryService; diff --git a/app/modules/web/Controllers/AccountFileController.php b/app/modules/web/Controllers/AccountFileController.php index 0e21db78..4dcb65cc 100644 --- a/app/modules/web/Controllers/AccountFileController.php +++ b/app/modules/web/Controllers/AccountFileController.php @@ -40,9 +40,9 @@ use SP\DataModel\FileData; use SP\Html\Html; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\FileGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Services\Account\AccountFileService; use SP\Services\Account\AccountService; use SP\Services\Auth\AuthException; diff --git a/app/modules/web/Controllers/AccountHistoryManagerController.php b/app/modules/web/Controllers/AccountHistoryManagerController.php index 24e9df7c..fb1784b9 100644 --- a/app/modules/web/Controllers/AccountHistoryManagerController.php +++ b/app/modules/web/Controllers/AccountHistoryManagerController.php @@ -36,8 +36,8 @@ use SP\Core\Exceptions\SessionTimeout; use SP\Core\Exceptions\SPException; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\AccountHistoryGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; +use SP\Mvc\Controller\ItemTrait; use SP\Services\Account\AccountHistoryService; use SP\Services\Account\AccountService; use SP\Services\Auth\AuthException; diff --git a/app/modules/web/Controllers/AccountManagerController.php b/app/modules/web/Controllers/AccountManagerController.php index 191b8791..f8d317e8 100644 --- a/app/modules/web/Controllers/AccountManagerController.php +++ b/app/modules/web/Controllers/AccountManagerController.php @@ -36,9 +36,9 @@ use SP\Core\Exceptions\SessionTimeout; use SP\Core\Exceptions\SPException; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\AccountGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\AccountForm; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Services\Account\AccountBulkRequest; use SP\Services\Account\AccountHistoryService; diff --git a/app/modules/web/Controllers/AuthTokenController.php b/app/modules/web/Controllers/AuthTokenController.php index f3a9e05f..aadb4b27 100644 --- a/app/modules/web/Controllers/AuthTokenController.php +++ b/app/modules/web/Controllers/AuthTokenController.php @@ -38,10 +38,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\AuthTokenData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\AuthTokenGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\AuthTokenForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Services\Auth\AuthException; use SP\Services\AuthToken\AuthTokenService; diff --git a/app/modules/web/Controllers/CategoryController.php b/app/modules/web/Controllers/CategoryController.php index a46392a1..7fae2e22 100644 --- a/app/modules/web/Controllers/CategoryController.php +++ b/app/modules/web/Controllers/CategoryController.php @@ -38,10 +38,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\CategoryData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\CategoryGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\CategoryForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; use SP\Services\Category\CategoryService; diff --git a/app/modules/web/Controllers/ClientController.php b/app/modules/web/Controllers/ClientController.php index 65bc9017..efa0016e 100644 --- a/app/modules/web/Controllers/ClientController.php +++ b/app/modules/web/Controllers/ClientController.php @@ -39,10 +39,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\ClientData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\ClientGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\ClientForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; use SP\Services\Client\ClientService; diff --git a/app/modules/web/Controllers/CustomFieldController.php b/app/modules/web/Controllers/CustomFieldController.php index eb657ba0..1b0589cc 100644 --- a/app/modules/web/Controllers/CustomFieldController.php +++ b/app/modules/web/Controllers/CustomFieldController.php @@ -38,10 +38,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\CustomFieldDefinitionData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\CustomFieldGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\CustomFieldDefForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; diff --git a/app/modules/web/Controllers/EventlogController.php b/app/modules/web/Controllers/EventlogController.php index 535ed4da..009b0d65 100644 --- a/app/modules/web/Controllers/EventlogController.php +++ b/app/modules/web/Controllers/EventlogController.php @@ -36,8 +36,8 @@ use SP\Core\Exceptions\SessionTimeout; use SP\Core\Exceptions\SPException; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\EventlogGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; +use SP\Mvc\Controller\ItemTrait; use SP\Services\Auth\AuthException; use SP\Services\EventLog\EventlogService; diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php index 3ef16ff9..c30f1e01 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php @@ -41,9 +41,8 @@ use SP\DataModel\Dto\AccountAclDto; use SP\DataModel\Dto\AccountDetailsResponse; use SP\DataModel\ItemPreset\AccountPermission; use SP\DataModel\ItemPreset\AccountPrivate; -use SP\Http\Uri; use SP\Modules\Web\Controllers\Helpers\HelperBase; -use SP\Modules\Web\Controllers\Traits\ItemTrait; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Repositories\NoSuchItemException; use SP\Services\Account\AccountAcl; @@ -61,6 +60,7 @@ use SP\Services\Tag\TagService; use SP\Services\User\UpdatedMasterPassException; use SP\Services\User\UserService; use SP\Services\UserGroup\UserGroupService; +use SP\Util\Link; /** * Class AccountHelper @@ -323,22 +323,7 @@ final class AccountHelper extends HelperBase $this->view->assign('showViewCustomPass', $this->accountAcl->isShowViewPass()); $this->view->assign('accountAcl', $this->accountAcl); - $this->view->assign('deepLink', $this->getDeepLink()); - } - - /** - * @return string - */ - private function getDeepLink() - { - $route = Acl::getActionRoute($this->actionId) . ($this->accountId ? '/' . $this->accountId : ''); - - $baseUrl = ($this->configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . Bootstrap::$SUBURI; - - $uri = new Uri($baseUrl); - $uri->addParam('r', $route); - - return $uri->getUriSigned($this->configData->getPasswordSalt()); + $this->view->assign('deepLink', Link::getDeepLink($this->accountId, $this->actionId, $this->configData)); } /** diff --git a/app/modules/web/Controllers/ItemPresetController.php b/app/modules/web/Controllers/ItemPresetController.php index 8a0807bf..09b00c78 100644 --- a/app/modules/web/Controllers/ItemPresetController.php +++ b/app/modules/web/Controllers/ItemPresetController.php @@ -41,10 +41,10 @@ use SP\DataModel\ItemPresetData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\ItemPresetGrid; use SP\Modules\Web\Controllers\Helpers\ItemPresetHelper; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\ItemsPresetForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; use SP\Services\ItemPreset\ItemPresetInterface; diff --git a/app/modules/web/Controllers/NotificationController.php b/app/modules/web/Controllers/NotificationController.php index bb183c8c..f64542c3 100644 --- a/app/modules/web/Controllers/NotificationController.php +++ b/app/modules/web/Controllers/NotificationController.php @@ -37,10 +37,10 @@ use SP\Core\Exceptions\SPException; use SP\DataModel\NotificationData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\NotificationGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\NotificationForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; diff --git a/app/modules/web/Controllers/PluginController.php b/app/modules/web/Controllers/PluginController.php index 3f1389e3..30edc1fd 100644 --- a/app/modules/web/Controllers/PluginController.php +++ b/app/modules/web/Controllers/PluginController.php @@ -36,8 +36,8 @@ use SP\Core\Exceptions\SessionTimeout; use SP\Core\Exceptions\SPException; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\PluginGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; +use SP\Mvc\Controller\ItemTrait; use SP\Plugin\PluginManager; use SP\Repositories\NoSuchItemException; use SP\Repositories\Plugin\PluginModel; diff --git a/app/modules/web/Controllers/PublicLinkController.php b/app/modules/web/Controllers/PublicLinkController.php index 3590f437..78e761bc 100644 --- a/app/modules/web/Controllers/PublicLinkController.php +++ b/app/modules/web/Controllers/PublicLinkController.php @@ -42,10 +42,10 @@ use SP\DataModel\PublicLinkData; use SP\DataModel\PublicLinkListData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\PublicLinkGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\PublicLinkForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Services\Account\AccountService; use SP\Services\Auth\AuthException; diff --git a/app/modules/web/Controllers/TagController.php b/app/modules/web/Controllers/TagController.php index 5481f162..69f5caeb 100644 --- a/app/modules/web/Controllers/TagController.php +++ b/app/modules/web/Controllers/TagController.php @@ -37,10 +37,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\TagData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\TagGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\TagForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; use SP\Services\Tag\TagService; diff --git a/app/modules/web/Controllers/TrackController.php b/app/modules/web/Controllers/TrackController.php index 9f33d504..c83fef71 100644 --- a/app/modules/web/Controllers/TrackController.php +++ b/app/modules/web/Controllers/TrackController.php @@ -36,8 +36,8 @@ use SP\Core\Exceptions\SessionTimeout; use SP\Core\Exceptions\SPException; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\TrackGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; +use SP\Mvc\Controller\ItemTrait; use SP\Services\Auth\AuthException; use SP\Services\Track\TrackService; diff --git a/app/modules/web/Controllers/UserController.php b/app/modules/web/Controllers/UserController.php index f5b31c1b..12157306 100644 --- a/app/modules/web/Controllers/UserController.php +++ b/app/modules/web/Controllers/UserController.php @@ -40,10 +40,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\UserData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\UserGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\UserForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Services\Auth\AuthException; use SP\Services\Mail\MailService; diff --git a/app/modules/web/Controllers/UserGroupController.php b/app/modules/web/Controllers/UserGroupController.php index bac48b43..91af707d 100644 --- a/app/modules/web/Controllers/UserGroupController.php +++ b/app/modules/web/Controllers/UserGroupController.php @@ -38,10 +38,10 @@ use SP\Core\Exceptions\ValidationException; use SP\DataModel\UserGroupData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\UserGroupGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\UserGroupForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Mvc\View\Components\SelectItemAdapter; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; diff --git a/app/modules/web/Controllers/UserProfileController.php b/app/modules/web/Controllers/UserProfileController.php index 284ca1ab..0821b2b7 100644 --- a/app/modules/web/Controllers/UserProfileController.php +++ b/app/modules/web/Controllers/UserProfileController.php @@ -39,10 +39,10 @@ use SP\DataModel\ProfileData; use SP\DataModel\UserProfileData; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Helpers\Grid\UserProfileGrid; -use SP\Modules\Web\Controllers\Traits\ItemTrait; use SP\Modules\Web\Controllers\Traits\JsonTrait; use SP\Modules\Web\Forms\UserProfileForm; use SP\Mvc\Controller\CrudControllerInterface; +use SP\Mvc\Controller\ItemTrait; use SP\Repositories\NoSuchItemException; use SP\Services\Auth\AuthException; use SP\Services\ServiceException; diff --git a/composer.json b/composer.json index 84ea5d4a..5edeffae 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,8 @@ "ext-fileinfo": "*", "ext-zlib": "*", "ext-libxml": "*", - "ext-mbstring": "*" + "ext-mbstring": "*", + "league/fractal": "^0.18.0" }, "require-dev": { "phpunit/phpunit": "^6", diff --git a/composer.lock b/composer.lock index 56734644..6da8bbf6 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ad9fd0dceb4efeeff785a1a658062f6d", + "content-hash": "a7cb7dc0ecb4a9646f39707655662075", "packages": [ { "name": "ademarre/binary-to-text-php", @@ -1083,6 +1083,70 @@ ], "time": "2017-02-01T23:08:58+00:00" }, + { + "name": "league/fractal", + "version": "0.18.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/fractal.git", + "reference": "4e553dae1a9402adbe11c81430a64675dc97b4fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/fractal/zipball/4e553dae1a9402adbe11c81430a64675dc97b4fc", + "reference": "4e553dae1a9402adbe11c81430a64675dc97b4fc", + "shasum": "" + }, + "require": { + "php": ">=5.4" + }, + "require-dev": { + "doctrine/orm": "^2.5", + "illuminate/contracts": "~5.0", + "mockery/mockery": "~0.9", + "pagerfanta/pagerfanta": "~1.0.0", + "phpunit/phpunit": "^4.8.35 || ^7.5", + "squizlabs/php_codesniffer": "~1.5", + "zendframework/zend-paginator": "~2.3" + }, + "suggest": { + "illuminate/pagination": "The Illuminate Pagination component.", + "pagerfanta/pagerfanta": "Pagerfanta Paginator", + "zendframework/zend-paginator": "Zend Framework Paginator" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.13-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Fractal\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Sturgeon", + "email": "me@philsturgeon.uk", + "homepage": "http://philsturgeon.uk/", + "role": "Developer" + } + ], + "description": "Handle the output of complex data structures ready for API output.", + "homepage": "http://fractal.thephpleague.com/", + "keywords": [ + "api", + "json", + "league", + "rest" + ], + "time": "2019-05-10T02:16:43+00:00" + }, { "name": "monolog/monolog", "version": "1.25.3", diff --git a/lib/Base.php b/lib/Base.php index 106608a6..a547ff66 100644 --- a/lib/Base.php +++ b/lib/Base.php @@ -49,7 +49,6 @@ $dotenv->load(); defined('APP_MODULE') || define('APP_MODULE', 'web'); define('DEBUG', getenv('DEBUG') || false); -// Please, notice that this file should be outside the webserver root. You can move it and then update this path define('CONFIG_PATH', getenv('CONFIG_PATH') ?: APP_PATH . DIRECTORY_SEPARATOR . 'config'); define('RESOURCES_PATH', APP_PATH . DIRECTORY_SEPARATOR . 'resources'); diff --git a/lib/SP/Adapters/AccountAdapter.php b/lib/SP/Adapters/AccountAdapter.php new file mode 100644 index 00000000..f7aa8bf1 --- /dev/null +++ b/lib/SP/Adapters/AccountAdapter.php @@ -0,0 +1,126 @@ +. + */ + +namespace SP\Adapters; + +use League\Fractal\TransformerAbstract; +use SP\Config\ConfigData; +use SP\Core\Acl\ActionsInterface; +use SP\DataModel\Dto\AccountDetailsResponse; +use SP\DataModel\ItemData; +use SP\Mvc\View\Components\SelectItemAdapter; +use SP\Services\CustomField\CustomFieldItem; +use SP\Util\Link; + +/** + * Class AccountAdapter + * + * @package SP\Adapters + */ +final class AccountAdapter extends TransformerAbstract +{ + /** + * @var CustomFieldItem[] + */ + private $customFields; + /** + * @var ConfigData + */ + private $configData; + + /** + * AccountAdapter constructor. + * + * @param ConfigData $configData + */ + public function __construct(ConfigData $configData) + { + $this->configData = $configData; + } + + /** + * @param ItemData[] $items + */ + public function withCustomFields(array $items) + { + $this->customFields = $items; + } + + /** + * @param AccountDetailsResponse $data + * + * @return array + */ + public function transform(AccountDetailsResponse $data) + { + $account = $data->getAccountVData(); + + return [ + 'id' => (int)$account->getId(), + 'name' => $account->getName(), + 'clientId' => (int)$account->getClientId(), + 'clientName' => $account->getClientName(), + 'categoryId' => (int)$account->getCategoryId(), + 'categoryName' => $account->getCategoryName(), + 'userId' => (int)$account->getUserId(), + 'userName' => $account->getUserName(), + 'userLogin' => $account->getUserLogin(), + 'userGroupId' => (int)$account->getUserGroupId(), + 'userGroupName' => $account->getUserGroupName(), + 'userEditId' => (int)$account->getUserEditId(), + 'userEditName' => $account->getUserEditName(), + 'userEditLogin' => $account->getUserEditLogin(), + 'login' => $account->getLogin(), + 'url' => $account->getUrl(), + 'notes' => $account->getNotes(), + 'otherUserEdit' => (int)$account->getOtherUserEdit(), + 'otherUserGroupEdit' => (int)$account->getOtherUserGroupEdit(), + 'dateAdd' => (int)$account->getDateAdd(), + 'dateEdit' => (int)$account->getDateEdit(), + 'countView' => (int)$account->getCountView(), + 'countDecrypt' => (int)$account->getCountDecrypt(), + 'isPrivate' => (int)$account->getIsPrivate(), + 'isPrivateGroup' => (int)$account->getIsPrivateGroup(), + 'passDate' => (int)$account->getPassDate(), + 'passDateChange' => (int)$account->getPassDateChange(), + 'parentId' => (int)$account->getParentId(), + 'publicLinkHash' => $account->getPublicLinkHash(), + 'tags' => SelectItemAdapter::factory($data->getTags())->getItemsFromModel(), + 'users' => SelectItemAdapter::factory($data->getUsers())->getItemsFromModel(), + 'userGroups' => SelectItemAdapter::factory($data->getUserGroups())->getItemsFromModel(), + 'customFields' => $this->customFields, + 'links' => [ + [ + 'rel' => 'self', + 'uri' => Link::getDeepLink($account->getId(), + ActionsInterface::ACCOUNT_VIEW, + $this->configData, + true) + ] + ], + ]; + } + + +} \ No newline at end of file diff --git a/app/modules/web/Controllers/Traits/ItemTrait.php b/lib/SP/Mvc/Controller/ItemTrait.php similarity index 97% rename from app/modules/web/Controllers/Traits/ItemTrait.php rename to lib/SP/Mvc/Controller/ItemTrait.php index 432c3d02..1f15b927 100644 --- a/app/modules/web/Controllers/Traits/ItemTrait.php +++ b/lib/SP/Mvc/Controller/ItemTrait.php @@ -2,9 +2,9 @@ /** * sysPass * - * @author nuxsmin - * @link https://syspass.org - * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org + * @author nuxsmin + * @link https://syspass.org + * @copyright 2012-2020, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -22,7 +22,7 @@ * along with sysPass. If not, see . */ -namespace SP\Modules\Web\Controllers\Traits; +namespace SP\Mvc\Controller; use Defuse\Crypto\Exception\CryptoException; use Psr\Container\ContainerExceptionInterface; diff --git a/lib/SP/Mvc/View/Components/SelectItem.php b/lib/SP/Mvc/View/Components/SelectItem.php index e9845b10..7d7ef310 100644 --- a/lib/SP/Mvc/View/Components/SelectItem.php +++ b/lib/SP/Mvc/View/Components/SelectItem.php @@ -24,12 +24,14 @@ namespace SP\Mvc\View\Components; +use JsonSerializable; + /** * Class SelectItem * * @package SP\Mvc\View\Components */ -final class SelectItem +final class SelectItem implements JsonSerializable { /** * @var int @@ -123,4 +125,12 @@ final class SelectItem { $this->skip = (bool)$skip; } + + /** + * @inheritDoc + */ + public function jsonSerialize() + { + return ['id' => (int)$this->id, 'name' => $this->name]; + } } \ No newline at end of file diff --git a/lib/SP/Services/Api/ApiService.php b/lib/SP/Services/Api/ApiService.php index 81e45ba1..664dc83b 100644 --- a/lib/SP/Services/Api/ApiService.php +++ b/lib/SP/Services/Api/ApiService.php @@ -26,6 +26,7 @@ namespace SP\Services\Api; use Defuse\Crypto\Exception\CryptoException; use Exception; +use SP\Core\Context\ContextException; use SP\Core\Crypt\Hash; use SP\Core\Crypt\Vault; use SP\Core\Exceptions\InvalidArgumentException; @@ -125,7 +126,7 @@ final class ApiService extends Service $this->setupUser(); if (AuthTokenService::isSecuredAction($actionId)) { - $this->context->setTrasientKey('_masterpass', $this->getMasterPassFromVault()); + $this->requireMasterPass(); } $this->initialized = true; @@ -258,6 +259,15 @@ final class ApiService extends Service } } + /** + * @throws ServiceException + * @throws ContextException + */ + public function requireMasterPass() + { + $this->context->setTrasientKey('_masterpass', $this->getMasterPassFromVault()); + } + /** * @param string $param * @param bool $required diff --git a/lib/SP/Services/Api/JsonRpcResponse.php b/lib/SP/Services/Api/JsonRpcResponse.php index 06179428..80d8e8ce 100644 --- a/lib/SP/Services/Api/JsonRpcResponse.php +++ b/lib/SP/Services/Api/JsonRpcResponse.php @@ -55,7 +55,7 @@ final class JsonRpcResponse 'jsonrpc' => '2.0', 'result' => $apiResponse->getResponse(), 'id' => $id - ]); + ], JSON_UNESCAPED_SLASHES); } /** diff --git a/lib/SP/Services/AuthToken/AuthTokenService.php b/lib/SP/Services/AuthToken/AuthTokenService.php index 729e1472..76402693 100644 --- a/lib/SP/Services/AuthToken/AuthTokenService.php +++ b/lib/SP/Services/AuthToken/AuthTokenService.php @@ -61,6 +61,10 @@ final class AuthTokenService extends Service ActionsInterface::ACCOUNT_CREATE ]; + const CAN_USE_SECURE_TOKEN_ACTIONS = [ + ActionsInterface::ACCOUNT_VIEW, + ]; + /** * @var AuthTokenRepository */ @@ -202,7 +206,9 @@ final class AuthTokenService extends Service $token = $this->authTokenRepository->getTokenByUserId($authTokenData->getUserId()) ?: $this->generateToken(); } - if (self::isSecuredAction($authTokenData->getActionId())) { + if (self::isSecuredAction($authTokenData->getActionId()) + || self::canUseSecureTokenAction($authTokenData->getActionId()) + ) { $authTokenData->setVault($this->getSecureData($token, $authTokenData->getHash())); $authTokenData->setHash(Hash::hashKey($authTokenData->getHash())); } else { @@ -236,6 +242,16 @@ final class AuthTokenService extends Service return in_array($action, self::SECURED_ACTIONS, true); } + /** + * @param int $action + * + * @return bool + */ + public static function canUseSecureTokenAction(int $action) + { + return in_array($action, self::CAN_USE_SECURE_TOKEN_ACTIONS, true); + } + /** * Generar la llave segura del token * diff --git a/lib/SP/Services/CustomField/CustomFieldItem.php b/lib/SP/Services/CustomField/CustomFieldItem.php index 14011cd0..e35b227c 100644 --- a/lib/SP/Services/CustomField/CustomFieldItem.php +++ b/lib/SP/Services/CustomField/CustomFieldItem.php @@ -29,7 +29,7 @@ namespace SP\Services\CustomField; * * @package SP\Services\CustomField */ -final class CustomFieldItem +final class CustomFieldItem implements \JsonSerializable { public $required = false; public $showInList = false; @@ -44,4 +44,23 @@ final class CustomFieldItem public $value; public $isEncrypted; public $isValueEncrypted; + + /** + * @inheritDoc + */ + public function jsonSerialize() + { + return [ + 'required' => $this->required, + 'showInList' => $this->showInList, + 'help' => $this->help, + 'typeId' => $this->typeId, + 'typeName' => $this->typeName, + 'typeText' => $this->typeText, + 'moduleId' => $this->moduleId, + 'value' => $this->value, + 'isEncrypted' => $this->isEncrypted, + 'isValueEncrypted' => $this->isValueEncrypted + ]; + } } \ No newline at end of file diff --git a/lib/SP/Util/Link.php b/lib/SP/Util/Link.php new file mode 100644 index 00000000..6b21882a --- /dev/null +++ b/lib/SP/Util/Link.php @@ -0,0 +1,64 @@ +. + */ + +namespace SP\Util; + + +use SP\Bootstrap; +use SP\Config\ConfigData; +use SP\Core\Acl\Acl; +use SP\Http\Uri; + +/** + * Class Link + * + * @package SP\Util + */ +final class Link +{ + /** + * @param int $itemId + * @param int $actionId + * @param ConfigData $configData + * + * @param bool $useUI + * + * @return string + */ + public static function getDeepLink(int $itemId, int $actionId, ConfigData $configData, bool $useUI = false) + { + $route = Acl::getActionRoute($actionId) . '/' . $itemId; + + if ($useUI) { + $baseUrl = ($configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . '/index.php'; + } else { + $baseUrl = ($configData->getApplicationUrl() ?: Bootstrap::$WEBURI) . Bootstrap::$SUBURI; + } + + $uri = new Uri($baseUrl); + $uri->addParam('r', $route); + + return $uri->getUriSigned($configData->getPasswordSalt()); + } +} \ No newline at end of file