new api 2.0
This commit is contained in:
parent
3a509b9415
commit
b2a5472be3
Binary file not shown.
After Width: | Height: | Size: 665 B |
Binary file not shown.
After Width: | Height: | Size: 628 B |
|
@ -0,0 +1,16 @@
|
|||
html {
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: #fafafa;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
|
||||
<link rel="stylesheet" type="text/css" href="index.css" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
href="./favicon-32x32.png"
|
||||
sizes="32x32"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
href="./favicon-16x16.png"
|
||||
sizes="16x16"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"></script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"></script>
|
||||
<script src="./swagger-initializer.js" charset="UTF-8"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,95 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Swagger UI: OAuth2 Redirect</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
"use strict";
|
||||
function run() {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1).replace("?", "&");
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&");
|
||||
arr.forEach(function(v, i, _arr) {
|
||||
_arr[i] = '"' + v.replace("=", '":"') + '"';
|
||||
});
|
||||
qp = qp
|
||||
? JSON.parse("{" + arr.join() + "}", function(key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value);
|
||||
})
|
||||
: {};
|
||||
|
||||
isValid = qp.state === sentState;
|
||||
|
||||
if (
|
||||
(oauth2.auth.schema.get("flow") === "accessCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode" ||
|
||||
oauth2.auth.schema.get("flow") === "authorization_code") &&
|
||||
!oauth2.auth.code
|
||||
) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message:
|
||||
"Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({ auth: oauth2.auth, redirectUrl: redirectUrl });
|
||||
} else {
|
||||
let oauthErrorMsg;
|
||||
if (qp.error) {
|
||||
oauthErrorMsg =
|
||||
"[" +
|
||||
qp.error +
|
||||
"]: " +
|
||||
(qp.error_description
|
||||
? qp.error_description + ". "
|
||||
: "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: " + qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message:
|
||||
oauthErrorMsg ||
|
||||
"[Authorization failed]: no accessCode received from the server."
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({
|
||||
auth: oauth2.auth,
|
||||
token: qp,
|
||||
isValid: isValid,
|
||||
redirectUrl: redirectUrl
|
||||
});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
|
||||
if (document.readyState !== "loading") {
|
||||
run();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
run();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,41 @@
|
|||
window.onload = function() {
|
||||
//<editor-fold desc="Changeable Configuration Block">
|
||||
const UrlMutatorPlugin = system => ({
|
||||
rootInjects: {
|
||||
setServer: server => {
|
||||
const jsonSpec = system.getState().toJSON().spec.json;
|
||||
const endpoint = window.location.pathname.replace(
|
||||
"/api/documentation/",
|
||||
""
|
||||
);
|
||||
const servers = [
|
||||
{
|
||||
url: endpoint + jsonSpec.servers[0].url,
|
||||
description: "Integria API"
|
||||
}
|
||||
];
|
||||
const newJsonSpec = Object.assign({}, jsonSpec, { servers });
|
||||
|
||||
return system.specActions.updateJsonSpec(newJsonSpec);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "../v1/swagger.json",
|
||||
dom_id: "#swagger-ui",
|
||||
docExpansion: "none",
|
||||
deepLinking: true,
|
||||
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
|
||||
plugins: [SwaggerUIBundle.plugins.DownloadUrl, UrlMutatorPlugin],
|
||||
layout: "StandaloneLayout",
|
||||
onComplete: () => {
|
||||
window.ui.setServer();
|
||||
}
|
||||
});
|
||||
|
||||
window.ui = ui;
|
||||
|
||||
//</editor-fold>
|
||||
};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
<meta http-equiv="REFRESH" content="0; url=documentation" />
|
|
@ -0,0 +1,5 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ public/ [L]
|
||||
RewriteRule (.*) public/$1 [L]
|
||||
</IfModule>
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
use DI\ContainerBuilder;
|
||||
use Slim\App;
|
||||
|
||||
require_once __DIR__.'/includeDependencies.php';
|
||||
|
||||
$containerBuilder = new ContainerBuilder();
|
||||
|
||||
// Add DI container definitions.
|
||||
$containerBuilder->addDefinitions(__DIR__.'/container.php');
|
||||
|
||||
// Create DI container instance.
|
||||
$container = $containerBuilder->build();
|
||||
|
||||
// Create Slim App instance.
|
||||
$app = $container->get(App::class);
|
||||
|
||||
// Set attachment directory.
|
||||
$config['attachment_directory'] = __DIR__.'/../../../attachment';
|
||||
|
||||
// Register routes.
|
||||
(require __DIR__.'/routes.php')($app);
|
||||
|
||||
return $app;
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
use PandoraFMS\Modules\Shared\Repositories\Repository;
|
||||
use PandoraFMS\Modules\Shared\Repositories\RepositoryMySQL;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepositoryMySQL;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Slim\App;
|
||||
use Slim\Factory\AppFactory;
|
||||
|
||||
return [
|
||||
'settings' => function () {
|
||||
return include __DIR__.'/settings.php';
|
||||
},
|
||||
App::class => function (ContainerInterface $container) {
|
||||
AppFactory::setContainer($container);
|
||||
|
||||
$app = AppFactory::create();
|
||||
|
||||
$basePath = rtrim(
|
||||
preg_replace(
|
||||
'/(.*)public\/.*/',
|
||||
'$1',
|
||||
$_SERVER['SCRIPT_NAME']
|
||||
),
|
||||
'/'
|
||||
);
|
||||
|
||||
$app->setBasePath($basePath);
|
||||
|
||||
// Register middleware.
|
||||
(include __DIR__.'/middleware.php')($app, $container);
|
||||
|
||||
return $app;
|
||||
},
|
||||
Repository::class => function (ContainerInterface $container) {
|
||||
return $container->get(RepositoryMySQL::class);
|
||||
},
|
||||
UserRepository::class => function (ContainerInterface $container) {
|
||||
return $container->get(UserRepositoryMySQL::class);
|
||||
},
|
||||
];
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/../../../vendor/autoload.php';
|
||||
|
||||
$exclude = ['tests'];
|
||||
$pattern = '*.php';
|
||||
|
||||
$openapi = \OpenApi\Generator::scan(
|
||||
\OpenApi\Util::finder(
|
||||
[
|
||||
__DIR__.'/..',
|
||||
__DIR__.'/../../../include/lib/Modules',
|
||||
],
|
||||
$exclude,
|
||||
$pattern
|
||||
)
|
||||
);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
file_put_contents(__DIR__.'/../public/swagger.json', $openapi->toJson());
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__.'/../../../vendor/autoload.php';
|
||||
require_once __DIR__.'/../../../include/config.php';
|
||||
global $config;
|
||||
|
||||
if (file_exists($config['homedir'].'/'.ENTERPRISE_DIR.'/load_enterprise.php') === true) {
|
||||
include_once $config['homedir'].'/'.ENTERPRISE_DIR.'/load_enterprise.php';
|
||||
include_once $config['homedir'].'/'.ENTERPRISE_DIR.'/include/functions_login.php';
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
// use PandoraFMS\Modules\Shared\Middlewares\UserTokenMiddleware;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Slim\App;
|
||||
|
||||
return function (App $app, ContainerInterface $container) {
|
||||
// Parse json, form data and xml.
|
||||
$app->addBodyParsingMiddleware();
|
||||
|
||||
// Add the Slim built-in routing middleware.
|
||||
$app->addRoutingMiddleware();
|
||||
|
||||
// Authenticate Integria.
|
||||
$beforeMiddleware = function (
|
||||
Request $request,
|
||||
RequestHandler $handler
|
||||
) use (
|
||||
$app,
|
||||
$container
|
||||
) {
|
||||
global $config;
|
||||
$authorization = $request->getHeader('Authorization');
|
||||
$user = false;
|
||||
if (empty($authorization) === false && empty($authorization[0]) === false) {
|
||||
$bearer = explode('Bearer ', $authorization[0]);
|
||||
if (empty($bearer) === false && isset($bearer[1]) === true) {
|
||||
// $user = \get_db_value(
|
||||
// 'id_usuario',
|
||||
// 'tusuario',
|
||||
// 'api_key',
|
||||
// $bearer[1]
|
||||
// );
|
||||
if ($user !== false) {
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$_SESSION['id_usuario'] = $user;
|
||||
$config['id_user'] = $user;
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$user = 'admin';
|
||||
$_SESSION['id_usuario'] = $user;
|
||||
$config['id_user'] = $user;
|
||||
|
||||
if (empty($user) === true) {
|
||||
// $userTokenMiddleware = $container->get(UserTokenMiddleware::class);
|
||||
// if ($userTokenMiddleware->check($request) === false) {
|
||||
$response = $app->getResponseFactory()->createResponse();
|
||||
$response->getBody()->write(
|
||||
json_encode(['error' => 'You need to be authenticated to perform this action'])
|
||||
);
|
||||
|
||||
$errorCode = 401;
|
||||
$newResponse = $response->withStatus($errorCode);
|
||||
return $newResponse;
|
||||
}
|
||||
|
||||
$response = $handler->handle($request);
|
||||
return $response;
|
||||
};
|
||||
|
||||
$app->add($beforeMiddleware);
|
||||
|
||||
// Handle exceptions.
|
||||
// Define Custom Error Handler.
|
||||
$customErrorHandler = function (
|
||||
Request $request,
|
||||
Throwable $exception,
|
||||
bool $displayErrorDetails,
|
||||
bool $logErrors,
|
||||
bool $logErrorDetails,
|
||||
?LoggerInterface $logger=null
|
||||
) use ($app) {
|
||||
$logger?->error($exception->getMessage());
|
||||
$response = $app->getResponseFactory()->createResponse();
|
||||
$response->getBody()->write(
|
||||
json_encode(['error' => $exception->getMessage()])
|
||||
);
|
||||
|
||||
$errorCode = 500;
|
||||
if (empty($exception->getCode()) === false) {
|
||||
$errorCode = $exception->getCode();
|
||||
}
|
||||
|
||||
$newResponse = $response->withStatus($errorCode);
|
||||
return $newResponse;
|
||||
};
|
||||
|
||||
// Add Error Middleware.
|
||||
// $errorMiddleware = $app->addErrorMiddleware(true, true, true);
|
||||
// $errorMiddleware->setDefaultErrorHandler($customErrorHandler);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Slim\App;
|
||||
|
||||
return function (App $app) {
|
||||
(include __DIR__.'/../../../include/lib/Modules/Users/routes.php')($app);
|
||||
};
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
require __DIR__.'/../../../include/config.php';
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', $config['homedir'].'/log/console.log');
|
||||
|
||||
return [];
|
|
@ -0,0 +1,7 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule ^ index.php [QSA,L]
|
||||
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
</IfModule>
|
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
|
||||
(require __DIR__.'/../config/bootstrap.php')->run();
|
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "8.0.2"
|
||||
"php": "8.1"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
|
@ -18,7 +18,16 @@
|
|||
"amphp/parallel-functions": "^1.0",
|
||||
"chrome-php/chrome": "^1.8.1",
|
||||
"artica/phpchartjs": "^1.0",
|
||||
"tinymce/tinymce": "^6.4"
|
||||
"tinymce/tinymce": "^6.4",
|
||||
"slim/slim": "4.*",
|
||||
"slim/psr7": "^1.6",
|
||||
"nyholm/psr7": "^1.8",
|
||||
"nyholm/psr7-server": "^1.1",
|
||||
"guzzlehttp/psr7": "^2",
|
||||
"laminas/laminas-diactoros": "^3.2",
|
||||
"php-di/php-di": "^7.0",
|
||||
"zircote/swagger-php": "^4.8",
|
||||
"doctrine/annotations": "^2.0"
|
||||
},
|
||||
"repositories": {
|
||||
"phpchartjs": {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Builders;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Entities\Entity;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
|
||||
class Builder
|
||||
{
|
||||
|
||||
|
||||
public function build(Entity $entity, array $data): Entity
|
||||
{
|
||||
foreach ($data as $field => $value) {
|
||||
if (method_exists($entity, 'set'.ucfirst($field)) === false) {
|
||||
throw new BadRequestException(__('Not exists method set%s', ucfirst($field)));
|
||||
}
|
||||
|
||||
$entity->{'set'.ucfirst($field)}($value);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Core\SerializableAbstract;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\ForbiddenActionException;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\InvalidClassException;
|
||||
|
||||
use Nyholm\Psr7\Stream;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Slim\Routing\RouteContext;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function getParam(Request $request, string $param): mixed
|
||||
{
|
||||
$routeContext = RouteContext::fromRequest($request);
|
||||
$route = $routeContext->getRoute();
|
||||
$value = $route->getArgument($param);
|
||||
|
||||
if (empty($value) === true) {
|
||||
throw new BadRequestException(__('Parameter %s is required as an argument', $param));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
public function getFile(Request $request, string $file): UploadedFileInterface
|
||||
{
|
||||
$files = $request->getUploadedFiles();
|
||||
if (isset($files[$file]) === false || empty($files[$file]) === true) {
|
||||
throw new BadRequestException(__('File %s is required as an argument', $file));
|
||||
}
|
||||
|
||||
if ($files[$file]->getError() !== UPLOAD_ERR_OK) {
|
||||
throw new BadRequestException(__('Error upload file'));
|
||||
}
|
||||
|
||||
return $files[$file];
|
||||
}
|
||||
|
||||
|
||||
public function extractParams(Request $request): array
|
||||
{
|
||||
$queryParams = ($request->getQueryParams() ?? []);
|
||||
$parsedBody = ($request->getParsedBody() ?? []);
|
||||
// if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
// throw new \UnexpectedValueException(sprintf(
|
||||
// 'Cannot decoded body JSON, error: %s',
|
||||
// json_last_error_msg()
|
||||
// ));
|
||||
// }
|
||||
$params = array_merge($queryParams, $parsedBody);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
||||
public function fromRequest(Request $request, string $className): mixed
|
||||
{
|
||||
$params = $this->extractParams($request);
|
||||
|
||||
if (class_exists($className) === false) {
|
||||
throw new InvalidClassException(__('Class %s is not defined', $className));
|
||||
}
|
||||
|
||||
$class = new $className();
|
||||
|
||||
if (!$class instanceof SerializableAbstract) {
|
||||
throw new InvalidClassException(__('Class %s is not instance of Serializable abstract', $className));
|
||||
}
|
||||
|
||||
return $class->fromArray($params);
|
||||
}
|
||||
|
||||
|
||||
public function getResponse(
|
||||
Response $response,
|
||||
mixed $result,
|
||||
?string $contentType='application/json'
|
||||
): Response {
|
||||
if ($contentType === 'application/json') {
|
||||
$result = json_encode($result);
|
||||
}
|
||||
|
||||
$response->getBody()->write($result);
|
||||
return $response->withHeader('Content-Type', $contentType);
|
||||
}
|
||||
|
||||
|
||||
public function getResponseAttachment(Response $response, string $path, string $fileName)
|
||||
{
|
||||
try {
|
||||
ob_clean();
|
||||
$stream = fopen($path, 'r');
|
||||
$file_stream = Stream::create($stream);
|
||||
} catch (\Throwable $th) {
|
||||
throw new ForbiddenActionException(
|
||||
__('Error download file: ').$th->getMessage(),
|
||||
empty($th->getCode()) === true ? HttpCodesEnum::BAD_REQUEST : $th->getCode()
|
||||
);
|
||||
}
|
||||
|
||||
return $response->withBody($file_stream)->withHeader('Content-Disposition', 'attachment; filename='.$fileName)->withHeader('Content-Type', mime_content_type($path));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Core;
|
||||
|
||||
abstract class DataMapperAbstract
|
||||
{
|
||||
|
||||
private null|string $tableRelated = null;
|
||||
|
||||
private null|string $keyRelated = null;
|
||||
|
||||
private null|string $searchFieldRelated = null;
|
||||
|
||||
private mixed $searchFieldValueRelated = null;
|
||||
|
||||
|
||||
public function __construct(
|
||||
private string $tableName,
|
||||
private string $primaryKey
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
abstract public function getClassName(): string;
|
||||
|
||||
|
||||
abstract public function fromDatabase(array $data): MappeableInterface;
|
||||
|
||||
|
||||
abstract public function toDatabase(MappeableInterface $data): array;
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of tableName.
|
||||
*/
|
||||
public function getTableName(): string
|
||||
{
|
||||
return $this->tableName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of primaryKey.
|
||||
*/
|
||||
public function getPrimaryKey(): string
|
||||
{
|
||||
return $this->primaryKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of tableRelated.
|
||||
*/
|
||||
public function getTableRelated(): null|string
|
||||
{
|
||||
return $this->tableRelated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of tableRelated.
|
||||
*/
|
||||
public function setTableRelated(null|string $tableRelated): self
|
||||
{
|
||||
$this->tableRelated = $tableRelated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of keyRelated.
|
||||
*/
|
||||
public function getKeyRelated(): null|string
|
||||
{
|
||||
return $this->keyRelated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of keyRelated.
|
||||
*/
|
||||
public function setKeyRelated(null|string $keyRelated): self
|
||||
{
|
||||
$this->keyRelated = $keyRelated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of searchFieldRelated.
|
||||
*/
|
||||
public function getSearchFieldRelated(): null|string
|
||||
{
|
||||
return $this->searchFieldRelated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of searchFieldRelated.
|
||||
*/
|
||||
public function setSearchFieldRelated(null|string $searchFieldRelated): self
|
||||
{
|
||||
$this->searchFieldRelated = $searchFieldRelated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of searchFieldValueRelated.
|
||||
*/
|
||||
public function getSearchFieldValueRelated(): mixed
|
||||
{
|
||||
return $this->searchFieldValueRelated;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of searchFieldValueRelated.
|
||||
*/
|
||||
public function setSearchFieldValueRelated(mixed $searchFieldValueRelated): self
|
||||
{
|
||||
$this->searchFieldValueRelated = $searchFieldValueRelated;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function getStringNameClass(): string
|
||||
{
|
||||
$strname = [
|
||||
'PandoraFMS\\Modules\\Users\\Entities\\User' => 'User',
|
||||
'PandoraFMS\\Modules\\Shared\\Workunits\\Entities\\Workunit' => 'Workunit',
|
||||
'PandoraFMS\\Modules\\Shared\\Attachments\\Entities\\Attachment' => 'Attachment',
|
||||
'PandoraFMS\\Modules\\Users\\UserProfiles\\Entities\\UserProfile' => 'Profile',
|
||||
'PandoraFMS\\Modules\\Profiles\\Entities\\Profile' => 'Profile',
|
||||
'PandoraFMS\\Modules\\Groups\\Entities\\Group' => 'Group',
|
||||
];
|
||||
|
||||
$result = ($strname[$this->getClassName()] ?? '');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Core;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Entities\Entity;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\InvalidFilterException;
|
||||
use PandoraFMS\Modules\Shared\Traits\GroupByFilterTrait;
|
||||
use PandoraFMS\Modules\Shared\Traits\OrderFilterTrait;
|
||||
use PandoraFMS\Modules\Shared\Traits\PaginationFilterTrait;
|
||||
|
||||
abstract class FilterAbstract extends SerializableAbstract
|
||||
{
|
||||
use PaginationFilterTrait;
|
||||
use OrderFilterTrait;
|
||||
use GroupByFilterTrait;
|
||||
|
||||
public const ASC = 'ascending';
|
||||
public const DESC = 'descending';
|
||||
|
||||
private ?int $limit = null;
|
||||
|
||||
private ?int $offset = null;
|
||||
|
||||
private ?string $defaultFieldOrder = null;
|
||||
|
||||
private ?string $defaultDirectionOrder = null;
|
||||
|
||||
private ?array $fields = null;
|
||||
|
||||
private ?Entity $entityFilter = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// abstract public function getWhereClause(): string;
|
||||
abstract public function fieldsTranslate(): array;
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of fieldsFreeSearch.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getFieldsFreeSearch(): ?array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of multipleSearch.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getMultipleSearch(): ?array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of multipleSearchString.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getMultipleSearchString(): ?array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of fieldsFreeSearch.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getFieldAclGroupMysql(): ?string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of fieldsFreeSearch.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getModeAclGroupMysql(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function fromArray(array $params): static
|
||||
{
|
||||
$fails = $this->validate($params);
|
||||
if (empty($fails) === false) {
|
||||
throw new InvalidFilterException($fails);
|
||||
}
|
||||
|
||||
foreach ($params as $field => $value) {
|
||||
if (method_exists($this, 'set'.ucfirst($field)) === false) {
|
||||
if ($this->getEntityFilter() === null || method_exists($this->getEntityFilter(), 'set'.ucfirst($field)) === false) {
|
||||
throw new BadRequestException(__('Field').': '.$field.' '.__('is not a valid parameter'));
|
||||
}
|
||||
}
|
||||
|
||||
if (method_exists($this, 'set'.ucfirst($field)) === true) {
|
||||
$this->{'set'.ucfirst($field)}($value ?? null);
|
||||
} else if ($this->getEntityFilter() !== null && method_exists($this->getEntityFilter(), 'set'.ucfirst($field)) === true) {
|
||||
$this->getEntityFilter()->{'set'.ucfirst($field)}($value ?? null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of limit.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getLimit(): ?int
|
||||
{
|
||||
return $this->limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of limit.
|
||||
*
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function setLimit(?int $limit): self
|
||||
{
|
||||
$this->limit = $limit;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of offset.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getOffset(): ?int
|
||||
{
|
||||
return $this->offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of offset.
|
||||
*
|
||||
* @param integer $offset
|
||||
*/
|
||||
public function setOffset(?int $offset): self
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of defaultFieldOrder.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getDefaultFieldOrder(): ?string
|
||||
{
|
||||
return $this->defaultFieldOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of defaultFieldOrder.
|
||||
*
|
||||
* @param string $defaultFieldOrder
|
||||
*/
|
||||
public function setDefaultFieldOrder(?string $defaultFieldOrder): self
|
||||
{
|
||||
$this->defaultFieldOrder = $defaultFieldOrder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of defaultDirectionOrder.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getDefaultDirectionOrder(): ?string
|
||||
{
|
||||
return $this->defaultDirectionOrder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of defaultDirectionOrder.
|
||||
*
|
||||
* @param string $defaultDirectionOrder
|
||||
*/
|
||||
public function setDefaultDirectionOrder(?string $defaultDirectionOrder): self
|
||||
{
|
||||
$this->defaultDirectionOrder = $defaultDirectionOrder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of entityFilter.
|
||||
*
|
||||
* @return ?Entity
|
||||
*/
|
||||
public function getEntityFilter(): ?Entity
|
||||
{
|
||||
return $this->entityFilter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of entityFilter.
|
||||
*
|
||||
* @param Entity $entityFilter
|
||||
*/
|
||||
public function setEntityFilter(?Entity $entityFilter): self
|
||||
{
|
||||
$this->entityFilter = $entityFilter;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of fields.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getFields(): ?array
|
||||
{
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of fields.
|
||||
*
|
||||
* @param array $fields
|
||||
*/
|
||||
public function setFields(?array $fields): self
|
||||
{
|
||||
$this->fields = $fields;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Core;
|
||||
|
||||
interface MappeableInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Core;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\InvalidFilterException;
|
||||
use JsonSerializable;
|
||||
|
||||
abstract class SerializableAbstract implements JsonSerializable
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
abstract public function fieldsReadOnly(): array;
|
||||
|
||||
|
||||
abstract public function jsonSerialize(): mixed;
|
||||
|
||||
|
||||
abstract public function getValidations(): array;
|
||||
|
||||
|
||||
abstract public function validateFields(array $filters): array;
|
||||
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return $this->jsonSerialize();
|
||||
}
|
||||
|
||||
|
||||
public function validate(array $params): array
|
||||
{
|
||||
$filters = [];
|
||||
foreach ($this->getValidations() as $field => $type) {
|
||||
if (isset($params[$field]) === true) {
|
||||
$filters[$field] = [
|
||||
'type' => $type,
|
||||
'value' => ($params[$field] ?? ''),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->validateFields($filters);
|
||||
}
|
||||
|
||||
|
||||
public function fromArray(array $params): static
|
||||
{
|
||||
$fails = $this->validate($params);
|
||||
if (empty($fails) === false) {
|
||||
throw new InvalidFilterException($fails);
|
||||
}
|
||||
|
||||
foreach ($params as $field => $value) {
|
||||
// Not valid parameters.
|
||||
if (method_exists($this, 'set'.ucfirst($field)) === false) {
|
||||
throw new BadRequestException(__('Field').': '.$field.' '.__('is not a valid parameter'));
|
||||
}
|
||||
|
||||
// Read only parameters.
|
||||
if (isset($this->fieldsReadOnly()[$field]) === true) {
|
||||
throw new BadRequestException(__('Field').': '.$field.' '.__('is a read only parameter'));
|
||||
}
|
||||
|
||||
$this->{'set'.ucfirst($field)}($value ?? null);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,260 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Documentation;
|
||||
|
||||
use OpenApi\Annotations as OA;
|
||||
|
||||
/**
|
||||
* @OA\Info(
|
||||
* title="Nueva API de Pandora FMS",
|
||||
* description="Nueva Api de pandora FMS",
|
||||
* termsOfService="https://example.com/terms/",
|
||||
* @OA\Contact(
|
||||
* name="Nombre del contacto",
|
||||
* url="https://www.example.com/support",
|
||||
* email="contacto@example.com"
|
||||
* ),
|
||||
* @OA\License(
|
||||
* name="Apache 2.0",
|
||||
* url="https://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
* ),
|
||||
* version="0.0.1"
|
||||
* ),
|
||||
* @OA\Schemes(
|
||||
* format="http"
|
||||
* ),
|
||||
* @OA\SecurityScheme(
|
||||
* securityScheme="bearerAuth",
|
||||
* in="header",
|
||||
* name="bearerAuth",
|
||||
* type="http",
|
||||
* scheme="bearer",
|
||||
* bearerFormat="pandoraBearer",
|
||||
* ),
|
||||
* @OA\Server(
|
||||
* url="/api/v1",
|
||||
* description="PandoraFMS API Server"
|
||||
* ),
|
||||
* @OA\Tag(
|
||||
* name="Users",
|
||||
* description="API Endpoints of users"
|
||||
* ),
|
||||
* @OA\OpenApi(
|
||||
* x={
|
||||
* "tagGroups"= {
|
||||
* {
|
||||
* "name"="Users",
|
||||
* "tags"={"Users"}
|
||||
* },
|
||||
* }
|
||||
* }
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* parameter="parameterPage",
|
||||
* name="page",
|
||||
* in="query",
|
||||
* description="page",
|
||||
* required=false,
|
||||
* @OA\Schema(
|
||||
* type="integer",
|
||||
* default=0
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* parameter="parameterSizePage",
|
||||
* name="sizePage",
|
||||
* in="query",
|
||||
* description="Size page",
|
||||
* required=false,
|
||||
* @OA\Schema(
|
||||
* type="integer",
|
||||
* default=0
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* parameter="parameterSortField",
|
||||
* name="sortField",
|
||||
* in="query",
|
||||
* description="sort field",
|
||||
* required=false,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* default=""
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* parameter="parameterSortDirection",
|
||||
* name="sortDirection",
|
||||
* in="query",
|
||||
* description="sort direction",
|
||||
* required=false,
|
||||
* @OA\Schema(
|
||||
* type="string",
|
||||
* enum={
|
||||
* "ascending",
|
||||
* "descending"
|
||||
* },
|
||||
* default=""
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="BadRequest",
|
||||
* description="Bad request",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* description="Error",
|
||||
* @OA\Property(
|
||||
* property="error",
|
||||
* type="string",
|
||||
* default="Message error"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="Unauthorized",
|
||||
* description="Unauthorized",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* description="Error",
|
||||
* @OA\Property(
|
||||
* property="error",
|
||||
* type="string",
|
||||
* default="Message error"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="Forbidden",
|
||||
* description="Forbidden",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* description="Error",
|
||||
* @OA\Property(
|
||||
* property="error",
|
||||
* type="string",
|
||||
* default="Message error"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="NotFound",
|
||||
* description="Not found",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* description="Error",
|
||||
* @OA\Property(
|
||||
* property="error",
|
||||
* type="string",
|
||||
* default="Message error"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="InternalServerError",
|
||||
* description="Internal server error",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* description="Error",
|
||||
* @OA\Property(
|
||||
* property="error",
|
||||
* type="string",
|
||||
* default="Message error"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="successfullyDeleted",
|
||||
* description="Successfully deleted",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="result",
|
||||
* type="string",
|
||||
* default="Successfully deleted"
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="paginationData",
|
||||
* type="object",
|
||||
* description="Info pagination data",
|
||||
* @OA\Property(
|
||||
* property="totalPages",
|
||||
* type="integer",
|
||||
* nullable=true,
|
||||
* description="Number of pages",
|
||||
* readOnly=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="sizePage",
|
||||
* type="integer",
|
||||
* nullable=true,
|
||||
* description="Items per page",
|
||||
* readOnly=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="totalRegisters",
|
||||
* type="integer",
|
||||
* nullable=true,
|
||||
* description="Number of items",
|
||||
* readOnly=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="totalRegistersPage",
|
||||
* type="integer",
|
||||
* nullable=true,
|
||||
* description="Number of items this page",
|
||||
* readOnly=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="currentPage",
|
||||
* type="integer",
|
||||
* nullable=true,
|
||||
* description="Number of current page",
|
||||
* readOnly=true
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
class OpenApi
|
||||
{
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Entities;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Core\MappeableInterface;
|
||||
use PandoraFMS\Modules\Shared\Core\SerializableAbstract;
|
||||
|
||||
abstract class Entity extends SerializableAbstract implements MappeableInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Entities;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class PaginationData implements JsonSerializable
|
||||
{
|
||||
|
||||
private ?int $totalPages = null;
|
||||
|
||||
private ?int $sizePage = null;
|
||||
|
||||
private ?int $currentPage = null;
|
||||
|
||||
private ?int $totalRegisters = null;
|
||||
|
||||
private ?int $totalRegistersPage = null;
|
||||
|
||||
private ?array $data = null;
|
||||
|
||||
|
||||
public function __construct(
|
||||
$currentPage,
|
||||
$sizePage,
|
||||
$totalRegisters,
|
||||
$data,
|
||||
) {
|
||||
$totalPages = empty($sizePage) === false ? ceil($totalRegisters / $sizePage) : 0;
|
||||
$this->setTotalPages($totalPages);
|
||||
$this->setSizePage($sizePage);
|
||||
$this->setCurrentPage($currentPage);
|
||||
$this->setSizePage($currentPage);
|
||||
$this->setTotalRegisters($totalRegisters);
|
||||
$this->setTotalRegistersPage(count($data));
|
||||
$this->setData($data);
|
||||
}
|
||||
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return $this->jsonSerialize();
|
||||
}
|
||||
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'paginationData' => [
|
||||
'totalPages' => $this->getTotalPages(),
|
||||
'sizePage' => $this->getSizePage(),
|
||||
'currentPage' => $this->getCurrentPage(),
|
||||
'totalRegisters' => $this->getTotalRegisters(),
|
||||
'totalRegistersPage' => $this->getTotalRegistersPage(),
|
||||
],
|
||||
'data' => $this->getData(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of totalPages.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getTotalPages(): ?int
|
||||
{
|
||||
return $this->totalPages;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of totalPages.
|
||||
*
|
||||
* @param integer $totalPages
|
||||
*/
|
||||
public function setTotalPages(?int $totalPages): self
|
||||
{
|
||||
$this->totalPages = $totalPages;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of sizePage.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getSizePage(): ?int
|
||||
{
|
||||
return $this->sizePage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of sizePage.
|
||||
*
|
||||
* @param integer $sizePage
|
||||
*/
|
||||
public function setSizePage(?int $sizePage): self
|
||||
{
|
||||
$this->sizePage = $sizePage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of currentPage.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getCurrentPage(): ?int
|
||||
{
|
||||
return $this->currentPage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of currentPage.
|
||||
*
|
||||
* @param integer $currentPage
|
||||
*/
|
||||
public function setCurrentPage(?int $currentPage): self
|
||||
{
|
||||
$this->currentPage = $currentPage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of totalRegisters.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getTotalRegisters(): ?int
|
||||
{
|
||||
return $this->totalRegisters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of totalRegisters.
|
||||
*
|
||||
* @param integer $totalRegisters
|
||||
*/
|
||||
public function setTotalRegisters(?int $totalRegisters): self
|
||||
{
|
||||
$this->totalRegisters = $totalRegisters;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of totalRegistersPage.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getTotalRegistersPage(): ?int
|
||||
{
|
||||
return $this->totalRegistersPage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of totalRegistersPage.
|
||||
*
|
||||
* @param integer $totalRegistersPage
|
||||
*/
|
||||
public function setTotalRegistersPage(?int $totalRegistersPage): self
|
||||
{
|
||||
$this->totalRegistersPage = $totalRegistersPage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of data.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getData(): ?array
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of data.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function setData(?array $data): self
|
||||
{
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Enums;
|
||||
|
||||
enum HttpCodesEnum: int
|
||||
{
|
||||
public const CONTINUE = 100;
|
||||
public const SWITCHING_PROTOCOLS = 101;
|
||||
public const PROCESSING = 102;
|
||||
// RFC2518
|
||||
public const EARLY_HINTS = 103;
|
||||
// RFC8297
|
||||
public const OK = 200;
|
||||
public const CREATED = 201;
|
||||
public const ACCEPTED = 202;
|
||||
public const NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
public const NO_CONTENT = 204;
|
||||
public const RESET_CONTENT = 205;
|
||||
public const PARTIAL_CONTENT = 206;
|
||||
public const MULTI_STATUS = 207;
|
||||
// RFC4918
|
||||
public const ALREADY_REPORTED = 208;
|
||||
// RFC5842
|
||||
public const IM_USED = 226;
|
||||
// RFC3229
|
||||
public const MULTIPLE_CHOICES = 300;
|
||||
public const MOVED_PERMANENTLY = 301;
|
||||
public const FOUND = 302;
|
||||
public const SEE_OTHER = 303;
|
||||
public const NOT_MODIFIED = 304;
|
||||
public const USE_PROXY = 305;
|
||||
public const RESERVED = 306;
|
||||
public const TEMPORARY_REDIRECT = 307;
|
||||
public const PERMANENTLY_REDIRECT = 308;
|
||||
// RFC7238
|
||||
public const BAD_REQUEST = 400;
|
||||
public const UNAUTHORIZED = 401;
|
||||
public const PAYMENT_REQUIRED = 402;
|
||||
public const FORBIDDEN = 403;
|
||||
public const NOT_FOUND = 404;
|
||||
public const METHOD_NOT_ALLOWED = 405;
|
||||
public const NOT_ACCEPTABLE = 406;
|
||||
public const PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
public const REQUEST_TIMEOUT = 408;
|
||||
public const CONFLICT = 409;
|
||||
public const GONE = 410;
|
||||
public const LENGTH_REQUIRED = 411;
|
||||
public const PRECONDITION_FAILED = 412;
|
||||
public const REQUEST_ENTITY_TOO_LARGE = 413;
|
||||
public const REQUEST_URI_TOO_LONG = 414;
|
||||
public const UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
public const REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
public const EXPECTATION_FAILED = 417;
|
||||
public const I_AM_A_TEAPOT = 418;
|
||||
// RFC2324
|
||||
public const MISDIRECTED_REQUEST = 421;
|
||||
// RFC7540
|
||||
public const UNPROCESSABLE_ENTITY = 422;
|
||||
// RFC4918
|
||||
public const LOCKED = 423;
|
||||
// RFC4918
|
||||
public const FAILED_DEPENDENCY = 424;
|
||||
// RFC4918
|
||||
public const TOO_EARLY = 425;
|
||||
// RFC-ietf-httpbis-replay-04
|
||||
public const UPGRADE_REQUIRED = 426;
|
||||
// RFC2817
|
||||
public const PRECONDITION_REQUIRED = 428;
|
||||
// RFC6585
|
||||
public const TOO_MANY_REQUESTS = 429;
|
||||
// RFC6585
|
||||
public const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
|
||||
// RFC6585
|
||||
public const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
// RFC7725
|
||||
public const INTERNAL_SERVER_ERROR = 500;
|
||||
public const NOT_IMPLEMENTED = 501;
|
||||
public const BAD_GATEWAY = 502;
|
||||
public const SERVICE_UNAVAILABLE = 503;
|
||||
public const GATEWAY_TIMEOUT = 504;
|
||||
public const VERSION_NOT_SUPPORTED = 505;
|
||||
public const VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506;
|
||||
// RFC2295
|
||||
public const INSUFFICIENT_STORAGE = 507;
|
||||
// RFC4918
|
||||
public const LOOP_DETECTED = 508;
|
||||
// RFC5842
|
||||
public const NOT_EXTENDED = 510;
|
||||
// RFC2774
|
||||
public const NETWORK_AUTHENTICATION_REQUIRED = 511;
|
||||
// RFC6585
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Enums;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Traits\EnumTrait;
|
||||
|
||||
enum LanguagesEnum: string
|
||||
{
|
||||
use EnumTrait;
|
||||
|
||||
case CATALONIAN = 'ca';
|
||||
case ENGLISH = 'en_GB';
|
||||
case SPANISH = 'es';
|
||||
case FRENCH = 'fr';
|
||||
case JAPANESE = 'ja';
|
||||
case RUSSIAN = 'ru';
|
||||
case CHINESE = 'zh_CN';
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
|
||||
class BadRequestException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public function __construct(string $fails)
|
||||
{
|
||||
parent::__construct($fails, HttpCodesEnum::BAD_REQUEST);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
|
||||
class ForbiddenACLException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public function __construct(string $fails)
|
||||
{
|
||||
parent::__construct($fails, HttpCodesEnum::FORBIDDEN);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ForbiddenActionException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public function __construct(string $fails, int $httpCodesEnum)
|
||||
{
|
||||
parent::__construct($fails, $httpCodesEnum);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
|
||||
class InvalidClassException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public function __construct(string $fails)
|
||||
{
|
||||
parent::__construct($fails, HttpCodesEnum::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
|
||||
class InvalidFilterException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public function __construct(array $fails)
|
||||
{
|
||||
$str = '';
|
||||
foreach ($fails as $fail) {
|
||||
$str .= $fail['message'];
|
||||
}
|
||||
|
||||
parent::__construct(__($str), HttpCodesEnum::BAD_REQUEST);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
|
||||
class NotFoundException extends Exception
|
||||
{
|
||||
|
||||
|
||||
public function __construct(string $fails)
|
||||
{
|
||||
parent::__construct($fails, HttpCodesEnum::NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Middlewares;
|
||||
|
||||
use PandoraFMS\Modules\Authentication\Services\GetUserTokenService;
|
||||
use PandoraFMS\Modules\Authentication\Services\UpdateTokenService;
|
||||
use PandoraFMS\Modules\Authentication\Services\ValidateUserTokenService;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\NotFoundException;
|
||||
use PandoraFMS\Modules\Shared\Services\Timestamp;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class UserTokenMiddleware
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private readonly ValidateUserTokenService $validateUserTokenService,
|
||||
private readonly GetUserTokenService $getUserTokenService,
|
||||
private readonly UpdateTokenService $updateTokenService,
|
||||
private readonly Timestamp $timestamp
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function check(Request $request): bool
|
||||
{
|
||||
global $config;
|
||||
$authorization = ($request->getHeader('Authorization')[0] ?? '');
|
||||
|
||||
/*
|
||||
@var ?Token $token
|
||||
*/
|
||||
try {
|
||||
$authorization = str_replace('Bearer ', '', $authorization);
|
||||
preg_match(
|
||||
'/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/',
|
||||
$authorization,
|
||||
$matches
|
||||
);
|
||||
|
||||
$uuid = ($matches[0] ?? '');
|
||||
$token = str_replace($uuid.'-', '', $authorization);
|
||||
$validToken = $this->validateUserTokenService->__invoke($uuid, $token);
|
||||
$token = $this->getUserTokenService->__invoke($uuid);
|
||||
if ($token !== null && $validToken) {
|
||||
$oldToken = clone $token;
|
||||
$token->setLastUsage($this->timestamp->getMysqlCurrentTimestamp(0));
|
||||
$this->updateTokenService->__invoke($token, $oldToken);
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
$token = null;
|
||||
}
|
||||
|
||||
if ($token !== null) {
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$_SESSION['id_usuario'] = $token->getIdUser();
|
||||
$config['id_user'] = $token->getIdUser();
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
}
|
||||
|
||||
return $token !== null && $validToken;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Repositories;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Core\DataMapperAbstract;
|
||||
use PandoraFMS\Modules\Shared\Core\FilterAbstract;
|
||||
use PandoraFMS\Modules\Shared\Entities\Entity;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\NotFoundException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
abstract class Repository
|
||||
{
|
||||
|
||||
|
||||
abstract protected function dbGetRow(
|
||||
string $field,
|
||||
string $table,
|
||||
mixed $value
|
||||
): array;
|
||||
|
||||
|
||||
abstract protected function dbGetValue(
|
||||
string $field,
|
||||
string $table,
|
||||
array $filters,
|
||||
string $whereJoin='AND'
|
||||
): mixed;
|
||||
|
||||
|
||||
abstract protected function dbGetValueSql(
|
||||
string $sql,
|
||||
?bool $cache=false
|
||||
): string;
|
||||
|
||||
|
||||
abstract protected function dbGetRowSql(
|
||||
string $sql
|
||||
): array;
|
||||
|
||||
|
||||
abstract protected function dbGetAllRowsSql(
|
||||
string $sql,
|
||||
?bool $cache=false
|
||||
): array;
|
||||
|
||||
|
||||
abstract protected function dbInsert(string $table, array $values): mixed;
|
||||
|
||||
|
||||
abstract protected function dbUpdate(string $table, array $values, array $condition): mixed;
|
||||
|
||||
|
||||
abstract protected function dbDelete(string $table, array $where): mixed;
|
||||
|
||||
|
||||
abstract protected function dbFormatWhereClauseSQL(array $values, $prefix=''): string;
|
||||
|
||||
|
||||
abstract public function buildQueryFilters(FilterAbstract $filter, DataMapperAbstract $mapper): string;
|
||||
|
||||
|
||||
abstract public function buildQueryPagination(FilterAbstract $filter): string;
|
||||
|
||||
|
||||
abstract public function buildQueryOrderBy(FilterAbstract $filter): string;
|
||||
|
||||
|
||||
abstract public function checkAclGroupMysql(string $field, ?string $mode=''): string;
|
||||
|
||||
|
||||
abstract public function buildQuery(
|
||||
FilterAbstract $filter,
|
||||
DataMapperAbstract $mapper,
|
||||
bool $count=false
|
||||
): string;
|
||||
|
||||
|
||||
abstract public function maxFieldSql(string $field): string;
|
||||
|
||||
|
||||
abstract public function safeInput(?string $value): ?string;
|
||||
|
||||
|
||||
abstract public function safeOutput(?string $value): ?string;
|
||||
|
||||
|
||||
/**
|
||||
* @return object[],
|
||||
*/
|
||||
public function __list(FilterAbstract $filter, DataMapperAbstract $mapper): array
|
||||
{
|
||||
try {
|
||||
$sql = $this->buildQuery($filter, $mapper);
|
||||
$list = $this->dbGetAllRowsSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
if (is_array($list) === false) {
|
||||
throw new NotFoundException(__('%s not found', $mapper->getStringNameClass()));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($list as $fields) {
|
||||
$result[] = $mapper->fromDatabase($fields);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function __rows(FilterAbstract $filter, DataMapperAbstract $mapper): array
|
||||
{
|
||||
try {
|
||||
$sql = $this->buildQuery($filter, $mapper);
|
||||
$rows = $this->dbGetAllRowsSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
|
||||
public function __count(FilterAbstract $filter, DataMapperAbstract $mapper): int
|
||||
{
|
||||
$sql = $this->buildQuery($filter, $mapper, true);
|
||||
try {
|
||||
$count = $this->dbGetValueSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return (int) $count;
|
||||
}
|
||||
|
||||
|
||||
public function __getOne(FilterAbstract $filter, DataMapperAbstract $mapper): object
|
||||
{
|
||||
try {
|
||||
$sql = $this->buildQuery($filter, $mapper);
|
||||
$result = $this->dbGetRowSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($result) === true) {
|
||||
throw new NotFoundException(__('%s not found', $mapper->getStringNameClass()));
|
||||
}
|
||||
|
||||
return $mapper->fromDatabase($result);
|
||||
}
|
||||
|
||||
|
||||
public function __create(Entity $entity, DataMapperAbstract $mapper): int
|
||||
{
|
||||
try {
|
||||
$id = $this->dbInsert(
|
||||
$mapper->getTableName(),
|
||||
$mapper->toDatabase($entity)
|
||||
);
|
||||
|
||||
// Create Relation.
|
||||
if (empty($mapper->getSearchFieldValueRelated()) === false) {
|
||||
$this->dbInsert(
|
||||
$mapper->getTableRelated(),
|
||||
[
|
||||
$mapper->getSearchFieldRelated() => $mapper->getSearchFieldValueRelated(),
|
||||
$mapper->getKeyRelated() => $id,
|
||||
]
|
||||
);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
|
||||
public function __update(Entity $entity, DataMapperAbstract $mapper, mixed $id): object
|
||||
{
|
||||
$values = $mapper->toDatabase($entity);
|
||||
unset($values[$mapper->getPrimaryKey()]);
|
||||
try {
|
||||
$this->dbUpdate(
|
||||
$mapper->getTableName(),
|
||||
$values,
|
||||
[$mapper->getPrimaryKey() => $id]
|
||||
);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
|
||||
public function __delete(
|
||||
mixed $id,
|
||||
DataMapperAbstract $mapper,
|
||||
?string $key=null,
|
||||
?array $where=null
|
||||
): void {
|
||||
try {
|
||||
if (empty($key) === true) {
|
||||
$key = $mapper->getPrimaryKey();
|
||||
}
|
||||
|
||||
$whereDelete = [$key => $id];
|
||||
if ($where !== null) {
|
||||
$whereDelete = array_merge($whereDelete, $where);
|
||||
}
|
||||
|
||||
$this->dbDelete($mapper->getTableName(), $whereDelete);
|
||||
|
||||
// Delete relation.
|
||||
if (empty($mapper->getTableRelated()) === false) {
|
||||
$this->dbDelete(
|
||||
$mapper->getTableRelated(),
|
||||
[
|
||||
$mapper->getSearchFieldRelated() => $mapper->getSearchFieldValueRelated(),
|
||||
$mapper->getKeyRelated() => $id,
|
||||
]
|
||||
);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function __getValue(FilterAbstract $filter, DataMapperAbstract $mapper): mixed
|
||||
{
|
||||
try {
|
||||
$sql = $this->buildQuery($filter, $mapper);
|
||||
$result = $this->dbGetValueSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function __maxField(string $field): string
|
||||
{
|
||||
return $this->maxFieldSql($field);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,484 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Repositories;
|
||||
|
||||
use Exception;
|
||||
use PandoraFMS\Modules\Shared\Core\DataMapperAbstract;
|
||||
use PandoraFMS\Modules\Shared\Core\FilterAbstract;
|
||||
use PandoraFMS\Modules\Shared\Services\Config;
|
||||
|
||||
class RepositoryMySQL extends Repository
|
||||
{
|
||||
|
||||
|
||||
protected function dbGetRow(
|
||||
string $field,
|
||||
string $table,
|
||||
mixed $value
|
||||
): array {
|
||||
ob_start();
|
||||
$result = \db_get_row($table, $field, $value);
|
||||
$error = ob_get_clean();
|
||||
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbGetValue(
|
||||
string $field,
|
||||
string $table,
|
||||
array $filters,
|
||||
string $whereJoin='AND'
|
||||
): mixed {
|
||||
return \db_get_value_filter($field, $table, $filters, $whereJoin);
|
||||
}
|
||||
|
||||
|
||||
protected function dbGetValueSql(
|
||||
string $sql,
|
||||
?bool $cache=false
|
||||
): string {
|
||||
ob_start();
|
||||
$result = \db_get_value_sql($sql, $cache);
|
||||
$error = ob_get_clean();
|
||||
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = '';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbGetRowSql(
|
||||
string $sql
|
||||
): array {
|
||||
ob_start();
|
||||
$result = \db_get_row_sql($sql);
|
||||
$error = ob_get_clean();
|
||||
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbGetAllRowsSql(
|
||||
string $sql,
|
||||
?bool $cache=false
|
||||
): array {
|
||||
ob_start();
|
||||
$result = \db_get_all_rows_sql($sql, $cache);
|
||||
$error = ob_get_clean();
|
||||
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbInsert(string $table, array $values): mixed
|
||||
{
|
||||
ob_start();
|
||||
$result = \db_process_sql_insert($table, $values);
|
||||
$error = ob_get_clean();
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbUpdate(string $table, array $values, array $condition): mixed
|
||||
{
|
||||
ob_start();
|
||||
$result = \db_process_sql_update(
|
||||
$table,
|
||||
$values,
|
||||
$condition
|
||||
);
|
||||
$error = ob_get_clean();
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbDelete(string $table, array $where): mixed
|
||||
{
|
||||
ob_start();
|
||||
$result = \db_process_sql_delete($table, $where);
|
||||
|
||||
$error = ob_get_clean();
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
$result = 0;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
protected function dbFormatWhereClauseSQL(array $values, $prefix=''): string
|
||||
{
|
||||
ob_start();
|
||||
$result = \db_format_array_where_clause_sql($values, 'AND', $prefix);
|
||||
$error = ob_get_clean();
|
||||
if ($result === false && empty($error) === false) {
|
||||
throw new Exception($error);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function buildQueryFilters(FilterAbstract $filter, DataMapperAbstract $mapper): string
|
||||
{
|
||||
$where_clause = '1=1';
|
||||
|
||||
if ($filter->getEntityFilter() !== null) {
|
||||
$searchEntity = $mapper->toDatabase($filter->getEntityFilter());
|
||||
$searchEntity = array_filter($searchEntity, fn ($value) => !is_null($value) && $value !== '' && $value !== 'null');
|
||||
if (empty($searchEntity) === false) {
|
||||
$where_clause .= ' AND '.$this->dbFormatWhereClauseSQL($searchEntity, '`'.$mapper->getTableName().'`.');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($filter->getFieldsFreeSearch()) === false
|
||||
&& empty($filter->toArray()['freeSearch']) === false
|
||||
) {
|
||||
$where_clause .= $this->freeSearch($filter->getFieldsFreeSearch(), $filter->toArray()['freeSearch']);
|
||||
}
|
||||
|
||||
if (empty($filter->getMultipleSearch()) === false) {
|
||||
$where_clause .= $this->multipleSearch($filter);
|
||||
}
|
||||
|
||||
if (empty($filter->getMultipleSearchString()) === false) {
|
||||
$where_clause .= $this->multipleSearchString($filter);
|
||||
}
|
||||
|
||||
if (empty($filter->getFieldAclGroupMysql()) === false) {
|
||||
$where_clause .= $this->checkAclGroupMysql(
|
||||
$filter->getFieldAclGroupMysql(),
|
||||
$filter->getModeAclGroupMysql()
|
||||
);
|
||||
}
|
||||
|
||||
return $where_clause;
|
||||
}
|
||||
|
||||
|
||||
private function freeSearch(array $fields, string $value): string
|
||||
{
|
||||
$clause = ' AND (';
|
||||
$count = count($fields);
|
||||
foreach ($fields as $field) {
|
||||
$clause .= sprintf('%s LIKE "%%%s%%"', $field, $value);
|
||||
|
||||
$count--;
|
||||
if ($count > 0) {
|
||||
$clause .= ' OR ';
|
||||
}
|
||||
}
|
||||
|
||||
$clause .= ') ';
|
||||
return $clause;
|
||||
}
|
||||
|
||||
|
||||
private function multipleSearch(FilterAbstract $filter): string
|
||||
{
|
||||
$fields = $filter->fieldsTranslate();
|
||||
$field = '';
|
||||
if (empty($fields) === false) {
|
||||
$field = ($fields[($filter->getMultipleSearch()['field'] ?? '')] ?? '');
|
||||
}
|
||||
|
||||
if (empty($field) === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$clause = ' AND '.$field.' IN ('.implode(',', $filter->getMultipleSearch()['data']).')';
|
||||
return $clause;
|
||||
}
|
||||
|
||||
|
||||
private function multipleSearchString(FilterAbstract $filter): string
|
||||
{
|
||||
$fields = $filter->fieldsTranslate();
|
||||
$field = '';
|
||||
if (empty($fields) === false) {
|
||||
$field = ($fields[($filter->getMultipleSearchString()['field'] ?? '')] ?? '');
|
||||
}
|
||||
|
||||
if (empty($field) === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$clause = ' AND '.$field.' IN ("'.implode('","', $filter->getMultipleSearchString()['data']).'")';
|
||||
return $clause;
|
||||
}
|
||||
|
||||
|
||||
public function buildQueryPagination(FilterAbstract $filter): string
|
||||
{
|
||||
$filter->setLimit($filter->getSizePage());
|
||||
$filter->setOffset($filter->getPage() * $filter->getSizePage());
|
||||
|
||||
$sqlLimit = '';
|
||||
if (empty($filter->getLimit()) === false) {
|
||||
$sqlLimit = sprintf(
|
||||
' LIMIT %d OFFSET %d',
|
||||
$filter->getLimit(),
|
||||
$filter->getOffset()
|
||||
);
|
||||
}
|
||||
|
||||
return $sqlLimit;
|
||||
}
|
||||
|
||||
|
||||
public function buildQueryOrderBy(FilterAbstract $filter): string
|
||||
{
|
||||
$default = '';
|
||||
if (empty($filter->getDefaultFieldOrder()) === false) {
|
||||
$default = sprintf(
|
||||
'ORDER BY %s %s',
|
||||
$filter->getDefaultFieldOrder(),
|
||||
$this->checkDirectionOrderByMsql($filter->getDefaultDirectionOrder())
|
||||
);
|
||||
}
|
||||
|
||||
$fieldsTranslate = $filter->fieldsTranslate();
|
||||
if (empty($fieldsTranslate) === true || isset($fieldsTranslate[$filter->getSortField()]) === false) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$field = $fieldsTranslate[$filter->getSortField()];
|
||||
$sort = 'ASC';
|
||||
if (empty($filter->getSortDirection()) === false) {
|
||||
$sort = $this->checkDirectionOrderByMsql($filter->getSortDirection());
|
||||
}
|
||||
|
||||
$return = '';
|
||||
if (empty($field) === false) {
|
||||
$return = 'ORDER BY '.$field.' '.$sort;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
public function buildQueryGroupBy(FilterAbstract $filter): string
|
||||
{
|
||||
$groupBy = '';
|
||||
$fieldsGroupByTranslate = [];
|
||||
if (empty($filter->getGroupByFields()) === false) {
|
||||
$fieldsTranslate = $filter->fieldsTranslate();
|
||||
if (empty($fieldsTranslate) === false) {
|
||||
foreach ($filter->getGroupByFields() as $value) {
|
||||
if (isset($fieldsTranslate[$value]) === false) {
|
||||
return $groupBy;
|
||||
}
|
||||
|
||||
$fieldsGroupByTranslate[] = $fieldsTranslate[$value];
|
||||
}
|
||||
|
||||
$groupBy = sprintf('GROUP BY %s', implode(',', $fieldsGroupByTranslate));
|
||||
}
|
||||
}
|
||||
|
||||
return $groupBy;
|
||||
}
|
||||
|
||||
|
||||
private function checkDirectionOrderByMsql(?string $direction): string
|
||||
{
|
||||
$directionArray = [
|
||||
'descending' => 'DESC',
|
||||
'ascending' => 'ASC',
|
||||
];
|
||||
|
||||
return (isset($directionArray[$direction]) === true) ? $directionArray[$direction] : 'ASC';
|
||||
}
|
||||
|
||||
|
||||
public function checkAclGroupMysql(string $field, ?string $mode=''): string
|
||||
{
|
||||
$config = new Config();
|
||||
$isAdmin = users_is_admin($config->get('id_user'));
|
||||
if ($isAdmin === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$userGroups = array_keys(
|
||||
\get_user_groups(
|
||||
$config->get('id_user'),
|
||||
'IM',
|
||||
true,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
if (empty($userGroups) === true) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($mode === 'array') {
|
||||
$filter = ' AND ( ';
|
||||
$i = 0;
|
||||
foreach ($userGroups as $group) {
|
||||
if ($i !== 0) {
|
||||
$filter .= ' OR ';
|
||||
}
|
||||
|
||||
$filter .= $group.' MEMBER OF ('.$field.') ';
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
$filter .= ' ) ';
|
||||
|
||||
return $filter;
|
||||
}
|
||||
|
||||
$filter = sprintf(
|
||||
' AND %s IN (%s)',
|
||||
$field,
|
||||
implode(',', $userGroups)
|
||||
);
|
||||
|
||||
return $filter;
|
||||
}
|
||||
|
||||
|
||||
public function buildQuery(
|
||||
FilterAbstract $filter,
|
||||
DataMapperAbstract $mapper,
|
||||
bool $count=false
|
||||
): string {
|
||||
$filters = $this->buildQueryFilters($filter, $mapper);
|
||||
if (empty($mapper->getSearchFieldRelated()) === false) {
|
||||
$filters .= sprintf(
|
||||
' AND %s.%s = %d',
|
||||
$mapper->getTableRelated(),
|
||||
$mapper->getSearchFieldRelated(),
|
||||
$mapper->getSearchFieldValueRelated()
|
||||
);
|
||||
}
|
||||
|
||||
$conditionInnerJoin = '';
|
||||
if (empty($mapper->getTableRelated()) === false) {
|
||||
$conditionInnerJoin = sprintf(
|
||||
'INNER JOIN %s ON %s.%s = %s.%s',
|
||||
$mapper->getTableRelated(),
|
||||
$mapper->getTableName(),
|
||||
$mapper->getPrimaryKey(),
|
||||
$mapper->getTableRelated(),
|
||||
$mapper->getKeyRelated()
|
||||
);
|
||||
}
|
||||
|
||||
$pagination = '';
|
||||
$orderBy = '';
|
||||
$groupBy = '';
|
||||
$fields = 'COUNT(*) as count';
|
||||
if ($count === false) {
|
||||
$pagination = $this->buildQueryPagination($filter);
|
||||
$orderBy = $this->buildQueryOrderBy($filter);
|
||||
$groupBy = $this->buildQueryGroupBy($filter);
|
||||
if (empty($filter->getFields()) === true) {
|
||||
$fields = $mapper->getTableName().'.*';
|
||||
} else {
|
||||
$buildFields = '';
|
||||
foreach ($filter->getFields() as $field) {
|
||||
if (empty($buildFields) === false) {
|
||||
$buildFields .= ' , ';
|
||||
}
|
||||
|
||||
$buildFields .= $field;
|
||||
}
|
||||
|
||||
$fields = $buildFields;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT %s
|
||||
FROM %s
|
||||
%s
|
||||
WHERE %s
|
||||
%s
|
||||
%s
|
||||
%s',
|
||||
$fields,
|
||||
$mapper->getTableName(),
|
||||
$conditionInnerJoin,
|
||||
$filters,
|
||||
$groupBy,
|
||||
$orderBy,
|
||||
$pagination
|
||||
);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
public function maxFieldSql(string $field): string
|
||||
{
|
||||
return 'MAX('.$field.')';
|
||||
}
|
||||
|
||||
|
||||
public function safeInput(?string $value): ?string
|
||||
{
|
||||
return \io_safe_input($value);
|
||||
}
|
||||
|
||||
|
||||
public function safeOutput(?string $value): ?string
|
||||
{
|
||||
return \io_safe_output($value);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Services;
|
||||
|
||||
class Audit
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function write(
|
||||
string $action,
|
||||
string $message='',
|
||||
string $extra=''
|
||||
): void {
|
||||
$idUser ??= $this->config->get('id_user');
|
||||
$remoteAddr ??= $this->config->get('REMOTE_ADDR');
|
||||
\db_pandora_audit(
|
||||
$action,
|
||||
__('User '.$idUser.': '.$message),
|
||||
$idUser,
|
||||
$remoteAddr,
|
||||
$extra
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Services;
|
||||
|
||||
final class Config
|
||||
{
|
||||
|
||||
|
||||
public function get(string $key, mixed $default=null): mixed
|
||||
{
|
||||
global $config;
|
||||
|
||||
return ($config[$key] ?? $default);
|
||||
}
|
||||
|
||||
|
||||
public function set(string $key, mixed $value): bool
|
||||
{
|
||||
global $config;
|
||||
// TODO: change.
|
||||
$res = \update_config_token($key, $value);
|
||||
if ($res === true) {
|
||||
$config[$key] = $value;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Services;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\ForbiddenActionException;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
class FileService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function moveUploadedFile(
|
||||
UploadedFileInterface $uploadedFile,
|
||||
?string $filename=null,
|
||||
?string $subdirectory=''
|
||||
) {
|
||||
$directory = $this->config->get('attachment_directory');
|
||||
$extension = pathinfo($uploadedFile->getClientFilename(), PATHINFO_EXTENSION);
|
||||
|
||||
if ($filename === null) {
|
||||
$basename = bin2hex(random_bytes(8));
|
||||
$filename = sprintf('%s.%0.8s', $basename, $extension);
|
||||
}
|
||||
|
||||
$path = $directory.DIRECTORY_SEPARATOR;
|
||||
if (empty($subdirectory) === false) {
|
||||
$path .= $subdirectory.DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
$path .= $filename;
|
||||
|
||||
try {
|
||||
$uploadedFile->moveTo($path);
|
||||
} catch (\Throwable $th) {
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
$th->getCode() ? $th->getCode() : HttpCodesEnum::FORBIDDEN
|
||||
);
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
|
||||
public function removeFile(string $filename)
|
||||
{
|
||||
$directory = $this->config->get('attachment_directory');
|
||||
if (unlink($directory.DIRECTORY_SEPARATOR.$filename) === false) {
|
||||
throw new ForbiddenActionException(
|
||||
__('Error remove file'),
|
||||
HttpCodesEnum::FORBIDDEN
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function validationFile(
|
||||
UploadedFileInterface $file,
|
||||
string $regexInvalidExtension=null,
|
||||
int $maxSize=null
|
||||
): void {
|
||||
if (empty($regexInvalidExtension) === true) {
|
||||
$regexInvalidExtension = '/^(bat|exe|cmd|sh|php|php1|php2|php3|php4|php5|pl|cgi|386|dll|com|torrent|js|app|jar|iso|
|
||||
pif|vb|vbscript|wsf|asp|cer|csr|jsp|drv|sys|ade|adp|bas|chm|cpl|crt|csh|fxp|hlp|hta|inf|ins|isp|jse|htaccess|
|
||||
htpasswd|ksh|lnk|mdb|mde|mdt|mdw|msc|msi|msp|mst|ops|pcd|prg|reg|scr|sct|shb|shs|url|vbe|vbs|wsc|wsf|wsh)$/i';
|
||||
}
|
||||
|
||||
$extension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
|
||||
|
||||
if (preg_match($regexInvalidExtension, $extension)) {
|
||||
throw new BadRequestException(__('Error upload file, the file extension is not allowed'));
|
||||
}
|
||||
|
||||
if (empty($maxSize) === true) {
|
||||
$maxSize = $this->config->get('max_file_size');
|
||||
}
|
||||
|
||||
if ($file->getSize() > $this->calculateSizeBytes($maxSize)) {
|
||||
throw new BadRequestException(__('Error upload file, the file size exceeds the established limit'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function calculateSizeBytes(int $maxSize)
|
||||
{
|
||||
$max = ini_get('upload_max_filesize');
|
||||
if (empty($maxSize) === false && $maxSize < $max) {
|
||||
$max = $maxSize;
|
||||
}
|
||||
|
||||
return ($maxSize * 1000000);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Services;
|
||||
|
||||
class Timestamp
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Config $config
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function getMysqlCurrentTimestamp(
|
||||
int $unixtime,
|
||||
?string $format='Y-m-d H:i:s',
|
||||
): string {
|
||||
if ($unixtime == 0) {
|
||||
$unixtime = time();
|
||||
}
|
||||
|
||||
if (!is_numeric($unixtime)) {
|
||||
$unixtime = strtotime($unixtime);
|
||||
}
|
||||
|
||||
return date($format, $unixtime);
|
||||
}
|
||||
|
||||
|
||||
public function getMysqlSystemUtimestamp() : int
|
||||
{
|
||||
$return = \mysql_get_system_time();
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Services;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Exceptions\ForbiddenACLException;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Actions\GetUserProfileAction;
|
||||
|
||||
class ValidateAclSystem
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private Audit $audit,
|
||||
private GetUserProfileAction $getUserProfileAction
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function validate(
|
||||
int $idGroup,
|
||||
string|array $permissions,
|
||||
string $message='',
|
||||
): void {
|
||||
// ACL.
|
||||
$idUser ??= $this->config->get('id_user');
|
||||
|
||||
$acl = false;
|
||||
if (is_array($permissions) === true) {
|
||||
foreach ($permissions as $permission) {
|
||||
if ((bool) \check_acl($idUser, $idGroup, $permission) === true) {
|
||||
$acl = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((bool) \check_acl($idUser, $idGroup, $permissions) === true) {
|
||||
$acl = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($acl === false) {
|
||||
$this->audit->write('ACL forbidden user does not have permission ', $message);
|
||||
throw new ForbiddenACLException('ACL forbidden user does not have permission '.$message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function validateUserGroups(
|
||||
int|array|null $idGroup,
|
||||
string $permissions,
|
||||
string $message='',
|
||||
): void {
|
||||
$idUser ??= $this->config->get('id_user');
|
||||
|
||||
$userGroups = \users_get_groups($idUser, $permissions, false, false);
|
||||
|
||||
$exist = true;
|
||||
if (is_array($idGroup) === true) {
|
||||
foreach ($idGroup as $group) {
|
||||
if (isset($userGroups[$group]) === false) {
|
||||
$exist = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isset($userGroups[$idGroup]) === false) {
|
||||
$exist = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($exist === false) {
|
||||
$this->audit->write('ACL Forbidden idGroup is not valid for this user', $message);
|
||||
throw new ForbiddenACLException('ACL Forbidden idGroup is not valid for this user');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function validateUserProfile(
|
||||
int $idProfile
|
||||
): void {
|
||||
$idUser ??= $this->config->get('id_user');
|
||||
$this->getUserProfileAction->__invoke($idUser, $idProfile);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Traits;
|
||||
|
||||
trait EnumTrait
|
||||
{
|
||||
|
||||
|
||||
public static function get(
|
||||
mixed $value,
|
||||
string $type='name'
|
||||
): mixed {
|
||||
$cases = static::cases();
|
||||
$index = array_search($value, array_column($cases, $type));
|
||||
if ($index !== false) {
|
||||
return $cases[$index];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Traits;
|
||||
|
||||
trait GroupByFilterTrait
|
||||
{
|
||||
|
||||
private ?array $groupByFields = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of groupByFields.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getGroupByFields(): ?array
|
||||
{
|
||||
return $this->groupByFields;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of groupByFields.
|
||||
*
|
||||
* @param array $groupByFields
|
||||
*/
|
||||
public function setGroupByFields(?array $groupByFields): self
|
||||
{
|
||||
$this->groupByFields = $groupByFields;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Traits;
|
||||
|
||||
trait OrderFilterTrait
|
||||
{
|
||||
|
||||
private ?string $sortField = null;
|
||||
|
||||
private ?string $sortDirection = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of sortField.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getSortField(): ?string
|
||||
{
|
||||
return $this->sortField;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of sortField.
|
||||
*
|
||||
* @param string $sortField
|
||||
*/
|
||||
public function setSortField(?string $sortField): self
|
||||
{
|
||||
$this->sortField = $sortField;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of sortDirection.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getSortDirection(): ?string
|
||||
{
|
||||
return $this->sortDirection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of sortDirection.
|
||||
*
|
||||
* @param string $sortDirection
|
||||
*/
|
||||
public function setSortDirection(?string $sortDirection): self
|
||||
{
|
||||
$this->sortDirection = $sortDirection;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Traits;
|
||||
|
||||
trait PaginationFilterTrait
|
||||
{
|
||||
|
||||
private ?int $sizePage = null;
|
||||
|
||||
private ?int $page = null;
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of sizePage.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getSizePage(): ?int
|
||||
{
|
||||
return $this->sizePage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of sizePage.
|
||||
*
|
||||
* @param integer $sizePage
|
||||
*/
|
||||
public function setSizePage(?int $sizePage): self
|
||||
{
|
||||
$this->sizePage = $sizePage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of page.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getPage(): ?int
|
||||
{
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of page.
|
||||
*
|
||||
* @param integer $page
|
||||
*/
|
||||
public function setPage(?int $page): self
|
||||
{
|
||||
$this->page = $page;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Utils;
|
||||
|
||||
final class ArrayTools
|
||||
{
|
||||
|
||||
|
||||
public function extractFromObjectByAttribute(string $attribute, array $list): array
|
||||
{
|
||||
return array_reduce(
|
||||
$list,
|
||||
static function ($carry, $item) use ($attribute) {
|
||||
$carry[] = $item->{$attribute}();
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function indexObjectByAttribute(string $attribute, array $list): array
|
||||
{
|
||||
return array_reduce(
|
||||
$list,
|
||||
static function ($carry, $item) use ($attribute) {
|
||||
$carry[$item->{$attribute}()][] = $item;
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Shared\Validators;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Enums\LanguagesEnum;
|
||||
|
||||
class Validator
|
||||
{
|
||||
public const INTEGER = 'Integer';
|
||||
public const BOOLEAN = 'Bool';
|
||||
public const STRING = 'String';
|
||||
public const ARRAY = 'Array';
|
||||
public const GREATERTHAN = 'GreaterThan';
|
||||
public const GREATEREQUALTHAN = 'GreaterEqualThan';
|
||||
public const DATETIME = 'DateTime';
|
||||
public const TIMEZONE = 'TimeZone';
|
||||
public const LANGUAGE = 'Language';
|
||||
public const MAIL = 'Mail';
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function validate(array $args): array
|
||||
{
|
||||
$failed = [];
|
||||
foreach ($args as $field => $info) {
|
||||
$type = $info['type'];
|
||||
$value = $info['value'];
|
||||
|
||||
if (is_array($type) === true) {
|
||||
foreach ($type as $subType) {
|
||||
$result = $this->buildError($subType, $field, $value);
|
||||
if ($result) {
|
||||
$failed[$field] = $result;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$result = $this->buildError($type, $field, $value);
|
||||
if ($result) {
|
||||
$failed[$field] = $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $failed;
|
||||
}
|
||||
|
||||
|
||||
private function buildError(string $type, string $field, $value): ?array
|
||||
{
|
||||
if ($this->{'is'.$type}($value) !== true) {
|
||||
return [
|
||||
'type' => 'integer',
|
||||
'message' => 'Field '.$field.' The value '.$value.' is not a valid '.$type.'.',
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function isInteger($arg): bool
|
||||
{
|
||||
return is_numeric($arg);
|
||||
}
|
||||
|
||||
|
||||
public function isGreaterThan($arg): bool
|
||||
{
|
||||
return $arg > 0;
|
||||
}
|
||||
|
||||
|
||||
public function isGreaterEqualThan($arg): bool
|
||||
{
|
||||
return $arg >= 0;
|
||||
}
|
||||
|
||||
|
||||
public function isBool($arg): bool
|
||||
{
|
||||
return is_bool($arg);
|
||||
}
|
||||
|
||||
|
||||
public function isString($arg): bool
|
||||
{
|
||||
return is_string($arg) || is_numeric($arg);
|
||||
}
|
||||
|
||||
|
||||
public function isArray($arg): bool
|
||||
{
|
||||
return is_array($arg);
|
||||
}
|
||||
|
||||
|
||||
public function isDateTime($date, $format='Y-m-d H:i:s')
|
||||
{
|
||||
$d = \DateTime::createFromFormat($format, $date);
|
||||
return $d && $d->format($format) == $date;
|
||||
}
|
||||
|
||||
|
||||
public function isTimeZone(string $timeZone): string
|
||||
{
|
||||
return array_search($timeZone, timezone_identifiers_list());
|
||||
}
|
||||
|
||||
|
||||
protected function isLanguage(string $language): bool
|
||||
{
|
||||
$result = LanguagesEnum::get(strtoupper($language));
|
||||
|
||||
return empty($result) === true ? false : true;
|
||||
}
|
||||
|
||||
|
||||
protected function isMail(string $mail): bool
|
||||
{
|
||||
return filter_var($mail, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Services\CreateUserService;
|
||||
|
||||
final class CreateUserAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private CreateUserService $createUserService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(User $user): User
|
||||
{
|
||||
return $this->createUserService->__invoke($user);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Services\DeleteUserService;
|
||||
|
||||
final class DeleteUserAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private DeleteUserService $deleteUserService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(User $user): void
|
||||
{
|
||||
$this->deleteUserService->__invoke($user);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Services\GetUserService;
|
||||
|
||||
final class GetUserAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private GetUserService $getUserService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(string $idUser): User
|
||||
{
|
||||
return $this->getUserService->__invoke($idUser);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
use PandoraFMS\Modules\Users\Services\CountUserService;
|
||||
use PandoraFMS\Modules\Users\Services\ListUserService;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Entities\PaginationData;
|
||||
|
||||
final class ListUserAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private ListUserService $listUserService,
|
||||
private CountUserService $countUserService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserFilter $userFilter): array
|
||||
{
|
||||
return (new PaginationData(
|
||||
$userFilter->getPage(),
|
||||
$userFilter->getSizePage(),
|
||||
$this->countUserService->__invoke($userFilter),
|
||||
$this->listUserService->__invoke($userFilter)
|
||||
))->toArray();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Services\UpdateUserService;
|
||||
|
||||
final class UpdateUserAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UpdateUserService $updateUserService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(User $user, User $oldUser): User
|
||||
{
|
||||
return $this->updateUserService->__invoke($user, $oldUser);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Users\Actions\CreateUserAction;
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class CreateUserController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private CreateUserAction $createUserAction,
|
||||
private ValidateAclSystem $acl,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* tags={"Users"},
|
||||
* path="/user",
|
||||
* summary="Creates a new users",
|
||||
* @OA\RequestBody(ref="#/components/requestBodies/requestBodyUser"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/ResponseUser"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
// @var User $user.
|
||||
$user = $this->fromRequest($request, User::class);
|
||||
|
||||
$this->acl->validate(0, 'UM', ' tried to manage user');
|
||||
|
||||
$result = $this->createUserAction->__invoke($user);
|
||||
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Users\Actions\DeleteUserAction;
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class DeleteUserController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private DeleteUserAction $deleteUserAction,
|
||||
private ValidateAclSystem $acl,
|
||||
private GetUserAction $getUserAction
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Delete(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* tags={"Users"},
|
||||
* path="/user/{id}",
|
||||
* summary="Deletes an user object.",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/successfullyDeleted"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$user = $this->getUserAction->__invoke($idUser);
|
||||
|
||||
$this->acl->validate(0, 'UM', ' tried to manage user');
|
||||
|
||||
$result = $this->deleteUserAction->__invoke($user);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class GetUserController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private GetUserAction $getUserAction,
|
||||
private ValidateAclSystem $acl
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* path="/user/{id}",
|
||||
* tags={"Users"},
|
||||
* summary="show users",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/ResponseUser"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$result = $this->getUserAction->__invoke($idUser);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Users\Actions\ListUserAction;
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class ListUserController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private ListUserAction $listUserAction,
|
||||
private ValidateAclSystem $acl,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* tags={"Users"},
|
||||
* path="/user/list",
|
||||
* summary="List user",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterPage"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterSizePage"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterSortField"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterSortDirection"),
|
||||
* @OA\RequestBody(ref="#/components/requestBodies/requestBodyUserFilter"),
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="List Incidence object",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="paginationData",
|
||||
* type="object",
|
||||
* ref="#/components/schemas/paginationData",
|
||||
* description="Page object",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* ref="#/components/schemas/User",
|
||||
* description="Array of user objects"
|
||||
* )
|
||||
* ),
|
||||
* ),
|
||||
* )
|
||||
* }
|
||||
* ),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
// @var UserFilter $userFilter.
|
||||
$userFilter = $this->fromRequest($request, UserFilter::class);
|
||||
|
||||
$result = $this->listUserAction->__invoke($userFilter);
|
||||
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use PandoraFMS\Modules\Users\Actions\UpdateUserAction;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
/**
|
||||
* @OA\Put(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* path="/user/{id}",
|
||||
* tags={"Users"},
|
||||
* summary="Updates an user",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\RequestBody(ref="#/components/requestBodies/requestBodyUser"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/ResponseUser"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
final class UpdateUserController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UpdateUserAction $updateUserAction,
|
||||
private ValidateAclSystem $acl,
|
||||
private GetUserAction $getUserAction
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$user = $this->getUserAction->__invoke($idUser);
|
||||
|
||||
$oldUser = clone $user;
|
||||
$params = $this->extractParams($request);
|
||||
$user->fromArray($params);
|
||||
|
||||
$this->acl->validate(0, 'UM', ' tried to manage user');
|
||||
|
||||
$result = $this->updateUserAction->__invoke($user, $oldUser);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Entities;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Builders\Builder;
|
||||
use PandoraFMS\Modules\Shared\Core\DataMapperAbstract;
|
||||
use PandoraFMS\Modules\Shared\Core\MappeableInterface;
|
||||
use PandoraFMS\Modules\Shared\Enums\LanguagesEnum;
|
||||
use PandoraFMS\Modules\Shared\Repositories\Repository;
|
||||
use PandoraFMS\Modules\Users\Enums\UserHomeScreenEnum;
|
||||
use PandoraFMS\Modules\Users\Enums\UserMetaconsoleAccessEnum;
|
||||
|
||||
final class UserDataMapper extends DataMapperAbstract
|
||||
{
|
||||
public const TABLE_NAME = 'tusuario';
|
||||
public const ID_USER = 'id_user';
|
||||
public const FULLNAME = 'fullname';
|
||||
public const FIRSTNAME = 'firstname';
|
||||
public const LASTNAME = 'lastname';
|
||||
public const MIDDLENAME = 'middlename';
|
||||
public const PASSWORD = 'password';
|
||||
public const COMMENTS = 'comments';
|
||||
public const LAST_CONNECT = 'last_connect';
|
||||
public const REGISTERED = 'registered';
|
||||
public const EMAIL = 'email';
|
||||
public const PHONE = 'phone';
|
||||
public const IS_ADMIN = 'is_admin';
|
||||
public const LANGUAGE = 'language';
|
||||
public const TIMEZONE = 'timezone';
|
||||
public const BLOCK_SIZE = 'block_size';
|
||||
public const ID_SKIN = 'id_skin';
|
||||
public const DISABLED = 'disabled';
|
||||
public const SHORTCUT = 'shortcut';
|
||||
public const SHORTCUT_DATA = 'shortcut_data';
|
||||
public const SECTION = 'section';
|
||||
public const DATA_SECTION = 'data_section';
|
||||
public const METACONSOLE_SECTION = 'metaconsole_section';
|
||||
public const METACONSOLE_DATA_SECTION = 'metaconsole_data_section';
|
||||
public const FORCE_CHANGE_PASS = 'force_change_pass';
|
||||
public const LAST_PASS_CHANGE = 'last_pass_change';
|
||||
public const LAST_FAILED_LOGIN = 'last_failed_login';
|
||||
public const FAILED_ATTEMPT = 'failed_attempt';
|
||||
public const LOGIN_BLOCKED = 'login_blocked';
|
||||
public const METACONSOLE_ACCESS = 'metaconsole_access';
|
||||
public const NOT_LOGIN = 'not_login';
|
||||
public const LOCAL_USER = 'local_user';
|
||||
public const METACONSOLE_AGENTS_MANAGER = 'metaconsole_agents_manager';
|
||||
public const METACONSOLE_ACCESS_NODE = 'metaconsole_access_node';
|
||||
public const STRICT_ACL = 'strict_acl';
|
||||
public const ID_FILTER = 'id_filter';
|
||||
public const SESSION_TIME = 'session_time';
|
||||
public const DEFAULT_EVENT_FILTER = 'default_event_filter';
|
||||
public const METACONSOLE_DEFAULT_EVENT_FILTER = 'metaconsole_default_event_filter';
|
||||
public const SHOW_TIPS_STARTUP = 'show_tips_startup';
|
||||
public const AUTOREFRESH_WHITE_LIST = 'autorefresh_white_list';
|
||||
public const TIME_AUTOREFRESH = 'time_autorefresh';
|
||||
public const DEFAULT_CUSTOM_VIEW = 'default_custom_view';
|
||||
public const EHORUS_USER_LEVEL_USER = 'ehorus_user_level_user';
|
||||
public const EHORUS_USER_LEVEL_PASS = 'ehorus_user_level_pass';
|
||||
public const EHORUS_USER_LEVEL_ENABLED = 'ehorus_user_level_enabled';
|
||||
public const INTEGRIA_USER_LEVEL_USER = 'integria_user_level_user';
|
||||
public const INTEGRIA_USER_LEVEL_PASS = 'integria_user_level_pass';
|
||||
public const API_TOKEN = 'api_token';
|
||||
public const ALLOWED_IP_ACTIVE = 'allowed_ip_active';
|
||||
public const ALLOWED_IP_LIST = 'allowed_ip_list';
|
||||
public const AUTH_TOKEN_SECRET = 'auth_token_secret';
|
||||
public const SESSION_MAX_TIME_EXPIRE = 'session_max_time_expire';
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Repository $repository,
|
||||
private Builder $builder,
|
||||
) {
|
||||
parent::__construct(
|
||||
self::TABLE_NAME,
|
||||
self::ID_USER,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function getClassName(): string
|
||||
{
|
||||
return User::class;
|
||||
}
|
||||
|
||||
|
||||
public function fromDatabase(array $data): User
|
||||
{
|
||||
return $this->builder->build(
|
||||
new User(),
|
||||
[
|
||||
'idUser' => $data[self::ID_USER],
|
||||
'fullName' => $this->repository->safeOutput($data[self::FULLNAME]),
|
||||
'firstName' => $this->repository->safeOutput($data[self::FIRSTNAME]),
|
||||
'lastName' => $this->repository->safeOutput($data[self::LASTNAME]),
|
||||
'middleName' => $this->repository->safeOutput($data[self::MIDDLENAME]),
|
||||
'password' => $data[self::PASSWORD],
|
||||
'comments' => $this->repository->safeOutput($data[self::COMMENTS]),
|
||||
'lastConnect' => $data[self::LAST_CONNECT],
|
||||
'registered' => $data[self::REGISTERED],
|
||||
'email' => $this->repository->safeOutput($data[self::EMAIL]),
|
||||
'phone' => $this->repository->safeOutput($data[self::PHONE]),
|
||||
'isAdmin' => $data[self::IS_ADMIN],
|
||||
'language' => LanguagesEnum::get($data[self::LANGUAGE]),
|
||||
'timezone' => $data[self::TIMEZONE],
|
||||
'blockSize' => $data[self::BLOCK_SIZE],
|
||||
'idSkin' => $data[self::ID_SKIN],
|
||||
'disabled' => $data[self::DISABLED],
|
||||
'shortcut' => $data[self::SHORTCUT],
|
||||
'shortcutData' => $this->repository->safeOutput($data[self::SHORTCUT_DATA]),
|
||||
'section' => UserHomeScreenEnum::get($data[self::SECTION]),
|
||||
'dataSection' => $this->repository->safeOutput($data[self::DATA_SECTION]),
|
||||
'metaconsoleSection' => UserHomeScreenEnum::get($data[self::METACONSOLE_SECTION]),
|
||||
'metaconsoleDataSection' => $this->repository->safeOutput($data[self::METACONSOLE_DATA_SECTION]),
|
||||
'forceChangePass' => $data[self::FORCE_CHANGE_PASS],
|
||||
'lastPassChange' => $data[self::LAST_PASS_CHANGE],
|
||||
'lastFailedLogin' => $data[self::LAST_FAILED_LOGIN],
|
||||
'failedAttempt' => $data[self::FAILED_ATTEMPT],
|
||||
'loginBlocked' => $data[self::LOGIN_BLOCKED],
|
||||
'metaconsoleAccess' => UserMetaconsoleAccessEnum::get($data[self::METACONSOLE_ACCESS]),
|
||||
'notLogin' => $data[self::NOT_LOGIN],
|
||||
'localUser' => $data[self::LOCAL_USER],
|
||||
'metaconsoleAgentsManager' => $data[self::METACONSOLE_AGENTS_MANAGER],
|
||||
'metaconsoleAccessNode' => $data[self::METACONSOLE_ACCESS_NODE],
|
||||
'strictAcl' => $data[self::STRICT_ACL],
|
||||
'idFilter' => $data[self::ID_FILTER],
|
||||
'sessionTime' => $data[self::SESSION_TIME],
|
||||
'defaultEventFilter' => $data[self::DEFAULT_EVENT_FILTER],
|
||||
'metaconsoleDefaultEventFilter' => $data[self::METACONSOLE_DEFAULT_EVENT_FILTER],
|
||||
'showTipsStartup' => $data[self::SHOW_TIPS_STARTUP],
|
||||
'autorefreshWhiteList' => json_decode($this->repository->safeOutput($data[self::AUTOREFRESH_WHITE_LIST])),
|
||||
'timeAutorefresh' => $data[self::TIME_AUTOREFRESH],
|
||||
'defaultCustomView' => $data[self::DEFAULT_CUSTOM_VIEW],
|
||||
'ehorusUserLevelUser' => $this->repository->safeOutput($data[self::EHORUS_USER_LEVEL_USER]),
|
||||
'ehorusUserLevelPass' => $this->repository->safeOutput($data[self::EHORUS_USER_LEVEL_PASS]),
|
||||
'ehorusUserLevelEnabled' => $data[self::EHORUS_USER_LEVEL_ENABLED],
|
||||
'itsmUserLevelUser' => $this->repository->safeOutput($data[self::INTEGRIA_USER_LEVEL_USER]),
|
||||
'itsmUserLevelPass' => $this->repository->safeOutput($data[self::INTEGRIA_USER_LEVEL_PASS]),
|
||||
'apiToken' => $data[self::API_TOKEN],
|
||||
'allowedIpActive' => $data[self::ALLOWED_IP_ACTIVE],
|
||||
'allowedIpList' => $this->repository->safeOutput($data[self::ALLOWED_IP_LIST]),
|
||||
'authTokenSecret' => $data[self::AUTH_TOKEN_SECRET],
|
||||
'sessionMaxTimeExpire' => $data[self::SESSION_MAX_TIME_EXPIRE],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function toDatabase(MappeableInterface $data): array
|
||||
{
|
||||
/*
|
||||
@var User $data
|
||||
*/
|
||||
return [
|
||||
self::ID_USER => $data->getIdUser(),
|
||||
self::FULLNAME => $this->repository->safeInput($data->getFullName()),
|
||||
self::FIRSTNAME => $this->repository->safeInput($data->getFirstName()),
|
||||
self::LASTNAME => $this->repository->safeInput($data->getLastName()),
|
||||
self::MIDDLENAME => $this->repository->safeInput($data->getMiddleName()),
|
||||
self::PASSWORD => $data->getPassword(),
|
||||
self::COMMENTS => $this->repository->safeInput($data->getComments()),
|
||||
self::LAST_CONNECT => $data->getLastConnect(),
|
||||
self::REGISTERED => $data->getRegistered(),
|
||||
self::EMAIL => $this->repository->safeInput($data->getEmail()),
|
||||
self::PHONE => $this->repository->safeInput($data->getPhone()),
|
||||
self::IS_ADMIN => $data->getIsAdmin(),
|
||||
self::LANGUAGE => $data->getLanguage()?->value,
|
||||
self::TIMEZONE => $data->getTimezone(),
|
||||
self::BLOCK_SIZE => $data->getBlockSize(),
|
||||
self::ID_SKIN => $data->getIdSkin(),
|
||||
self::DISABLED => $data->getDisabled(),
|
||||
self::SHORTCUT => $data->getShortcut(),
|
||||
self::SHORTCUT_DATA => $this->repository->safeInput($data->getShortcutData()),
|
||||
self::SECTION => $data->getSection()?->value,
|
||||
self::DATA_SECTION => $this->repository->safeInput($data->getDataSection()),
|
||||
self::METACONSOLE_SECTION => $data->getMetaconsoleSection()?->value,
|
||||
self::METACONSOLE_DATA_SECTION => $this->repository->safeInput($data->getMetaconsoleDataSection()),
|
||||
self::FORCE_CHANGE_PASS => $data->getForceChangePass(),
|
||||
self::LAST_PASS_CHANGE => $data->getLastPassChange(),
|
||||
self::LAST_FAILED_LOGIN => $data->getLastFailedLogin(),
|
||||
self::FAILED_ATTEMPT => $data->getFailedAttempt(),
|
||||
self::LOGIN_BLOCKED => $data->getLoginBlocked(),
|
||||
self::METACONSOLE_ACCESS => $data->getMetaconsoleAccess()?->value,
|
||||
self::NOT_LOGIN => $data->getNotLogin(),
|
||||
self::LOCAL_USER => $data->getLocalUser(),
|
||||
self::METACONSOLE_AGENTS_MANAGER => $data->getMetaconsoleAgentsManager(),
|
||||
self::METACONSOLE_ACCESS_NODE => $data->getMetaconsoleAccessNode(),
|
||||
self::STRICT_ACL => $data->getStrictAcl(),
|
||||
self::ID_FILTER => $data->getIdFilter(),
|
||||
self::SESSION_TIME => $data->getSessionTime(),
|
||||
self::DEFAULT_EVENT_FILTER => $data->getDefaultEventFilter(),
|
||||
self::METACONSOLE_DEFAULT_EVENT_FILTER => $data->getMetaconsoleDefaultEventFilter(),
|
||||
self::SHOW_TIPS_STARTUP => $data->getShowTipsStartup(),
|
||||
self::AUTOREFRESH_WHITE_LIST => $this->repository->safeInput(json_encode($data->getAutorefreshWhiteList())),
|
||||
self::TIME_AUTOREFRESH => $data->getTimeAutorefresh(),
|
||||
self::DEFAULT_CUSTOM_VIEW => $data->getDefaultCustomView(),
|
||||
self::EHORUS_USER_LEVEL_USER => $this->repository->safeInput($data->getEhorusUserLevelUser()),
|
||||
self::EHORUS_USER_LEVEL_PASS => $this->repository->safeInput($data->getEhorusUserLevelPass()),
|
||||
self::EHORUS_USER_LEVEL_ENABLED => $data->getEhorusUserLevelEnabled(),
|
||||
self::INTEGRIA_USER_LEVEL_USER => $this->repository->safeInput($data->getItsmUserLevelUser()),
|
||||
self::INTEGRIA_USER_LEVEL_PASS => $this->repository->safeInput($data->getItsmUserLevelPass()),
|
||||
self::API_TOKEN => $data->getApiToken(),
|
||||
self::ALLOWED_IP_ACTIVE => $data->getAllowedIpActive(),
|
||||
self::ALLOWED_IP_LIST => $this->repository->safeInput($data->getAllowedIpList()),
|
||||
self::AUTH_TOKEN_SECRET => $data->getAuthTokenSecret(),
|
||||
self::SESSION_MAX_TIME_EXPIRE => $data->getSessionMaxTimeExpire(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Entities;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Core\FilterAbstract;
|
||||
use PandoraFMS\Modules\Users\Validators\UserValidator;
|
||||
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="UserFilter",
|
||||
* type="object",
|
||||
* allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/User"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="freeSearch",
|
||||
* type="string",
|
||||
* nullable=true,
|
||||
* default=null,
|
||||
* description="Find word in fullname and comments fields."
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="multipleSearchString",
|
||||
* type="string",
|
||||
* nullable=true,
|
||||
* default=null,
|
||||
* description="search string in field."
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\RequestBody(
|
||||
* request="requestBodyUserFilter",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(ref="#/components/schemas/UserFilter")
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
final class UserFilter extends FilterAbstract
|
||||
{
|
||||
|
||||
private ?string $freeSearch = null;
|
||||
|
||||
private ?array $multipleSearchString = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setDefaultFieldOrder(UserDataMapper::ID_USER);
|
||||
$this->setDefaultDirectionOrder($this::ASC);
|
||||
$this->setEntityFilter(new User());
|
||||
}
|
||||
|
||||
|
||||
public function fieldsTranslate(): array
|
||||
{
|
||||
return [
|
||||
'idUser' => UserDataMapper::TABLE_NAME.'.'.UserDataMapper::ID_USER,
|
||||
'fullName' => UserDataMapper::TABLE_NAME.'.'.UserDataMapper::FULLNAME,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function fieldsReadOnly(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'freeSearch' => $this->getFreeSearch(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getValidations(): array
|
||||
{
|
||||
$validations = [];
|
||||
if ($this->getEntityFilter() !== null) {
|
||||
$validations = $this->getEntityFilter()->getValidations();
|
||||
}
|
||||
|
||||
$validations['freeSearch'] = UserValidator::STRING;
|
||||
return $validations;
|
||||
}
|
||||
|
||||
|
||||
public function validateFields(array $filters): array
|
||||
{
|
||||
return (new UserValidator())->validate($filters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of freeSearch.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getFreeSearch(): ?string
|
||||
{
|
||||
return $this->freeSearch;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of freeSearch.
|
||||
*
|
||||
* @param string $freeSearch
|
||||
*/
|
||||
public function setFreeSearch(?string $freeSearch): self
|
||||
{
|
||||
$this->freeSearch = $freeSearch;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of fieldsFreeSearch.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getFieldsFreeSearch(): ?array
|
||||
{
|
||||
return [
|
||||
UserDataMapper::TABLE_NAME.'.'.UserDataMapper::FULLNAME,
|
||||
UserDataMapper::TABLE_NAME.'.'.UserDataMapper::ID_USER,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of multipleSearchString.
|
||||
*
|
||||
* @return ?array
|
||||
*/
|
||||
public function getMultipleSearchString(): ?array
|
||||
{
|
||||
return $this->multipleSearchString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of multipleSearchString.
|
||||
*
|
||||
* @param array $multipleSearchString
|
||||
*/
|
||||
public function setMultipleSearchString(?array $multipleSearchString): self
|
||||
{
|
||||
$this->multipleSearchString = $multipleSearchString;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Enums;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Traits\EnumTrait;
|
||||
|
||||
enum UserHomeScreenEnum: string
|
||||
{
|
||||
use EnumTrait;
|
||||
|
||||
case default = 'default';
|
||||
case VISUAL_CONSOLE = 'visual_console';
|
||||
case EVENT_LIST = 'event_list';
|
||||
case GROUP_VIEW = 'group_view';
|
||||
case TACTICAL_VIEW = 'tactical_view';
|
||||
case ALERT_DETAIL = 'alert_detail';
|
||||
case EXTERNAL_LINK = 'external_link';
|
||||
case OTHER = 'other';
|
||||
case DASHBOARD = 'dashboard';
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Enums;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Traits\EnumTrait;
|
||||
|
||||
enum UserMetaconsoleAccessEnum: string
|
||||
{
|
||||
use EnumTrait;
|
||||
|
||||
case BASIC = 'basic';
|
||||
case ADVANCED = 'advanced';
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Repositories;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
|
||||
interface UserRepository
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return User[],
|
||||
*/
|
||||
public function list(UserFilter $userFilter): array;
|
||||
|
||||
|
||||
public function count(UserFilter $userFilter): int;
|
||||
|
||||
|
||||
public function getOne(UserFilter $userFilter): User;
|
||||
|
||||
|
||||
public function create(User $user): User;
|
||||
|
||||
|
||||
public function update(User $user): User;
|
||||
|
||||
|
||||
public function delete(string $id): void;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Repositories;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Core\DataMapperAbstract;
|
||||
use PandoraFMS\Modules\Shared\Core\FilterAbstract;
|
||||
use PandoraFMS\Modules\Shared\Enums\HttpCodesEnum;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\NotFoundException;
|
||||
use PandoraFMS\Modules\Shared\Repositories\RepositoryMySQL;
|
||||
use PandoraFMS\Modules\Shared\Services\Config;
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Entities\UserDataMapper;
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
use PandoraFMS\Modules\Users\Enums\UserLevelEnum;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class UserRepositoryMySQL extends RepositoryMySQL implements UserRepository
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UserDataMapper $userDataMapper
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return User[],
|
||||
*/
|
||||
public function list(UserFilter $userFilter): array
|
||||
{
|
||||
try {
|
||||
$sql = $this->getUsersQuery($userFilter, $this->userDataMapper);
|
||||
$list = $this->dbGetAllRowsSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
if (is_array($list) === false) {
|
||||
throw new NotFoundException(__('%s not found', $this->userDataMapper->getStringNameClass()));
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach ($list as $fields) {
|
||||
$result[] = $this->userDataMapper->fromDatabase($fields);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function count(UserFilter $userFilter): int
|
||||
{
|
||||
$sql = $this->getUsersQuery($userFilter, $this->userDataMapper, true);
|
||||
try {
|
||||
hd($sql, true);
|
||||
$count = $this->dbGetValueSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
return (int) $count;
|
||||
}
|
||||
|
||||
|
||||
public function getOne(UserFilter $userFilter): User
|
||||
{
|
||||
try {
|
||||
$sql = $this->getUsersQuery($userFilter, $this->userDataMapper);
|
||||
$result = $this->dbGetRowSql($sql);
|
||||
} catch (\Throwable $th) {
|
||||
// Capture errors mysql.
|
||||
throw new InvalidArgumentException(
|
||||
strip_tags($th->getMessage()),
|
||||
HttpCodesEnum::INTERNAL_SERVER_ERROR
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($result) === true) {
|
||||
throw new NotFoundException(__('%s not found', $this->userDataMapper->getStringNameClass()));
|
||||
}
|
||||
|
||||
return $this->userDataMapper->fromDatabase($result);
|
||||
}
|
||||
|
||||
|
||||
public function create(User $user): User
|
||||
{
|
||||
$this->__create($user, $this->userDataMapper);
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
public function update(User $user): User
|
||||
{
|
||||
return $this->__update(
|
||||
$user,
|
||||
$this->userDataMapper,
|
||||
$user->getIdUser()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function delete(string $id): void
|
||||
{
|
||||
$this->__delete($id, $this->userDataMapper);
|
||||
}
|
||||
|
||||
|
||||
private function getUsersQuery(
|
||||
FilterAbstract $filter,
|
||||
DataMapperAbstract $mapper,
|
||||
bool $count=false
|
||||
): string {
|
||||
$pagination = '';
|
||||
$orderBy = '';
|
||||
$fields = 'COUNT(DISTINCT tusuario.id_user) as count';
|
||||
$filters = $this->buildQueryFilters($filter, $mapper);
|
||||
|
||||
if ($count === false) {
|
||||
$pagination = $this->buildQueryPagination($filter);
|
||||
$orderBy = $this->buildQueryOrderBy($filter);
|
||||
if (empty($filter->getFields()) === true) {
|
||||
$fields = 'DISTINCT tusuario.*';
|
||||
} else {
|
||||
$buildFields = '';
|
||||
foreach ($filter->getFields() as $field) {
|
||||
if (empty($buildFields) === false) {
|
||||
$buildFields .= ' , ';
|
||||
}
|
||||
|
||||
$buildFields .= $field;
|
||||
}
|
||||
|
||||
$fields = $buildFields;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = sprintf(
|
||||
'SELECT %s
|
||||
FROM tusuario
|
||||
LEFT JOIN tusuario_perfil
|
||||
ON tusuario.id_user = tusuario_perfil.id_usuario
|
||||
WHERE %s
|
||||
%s
|
||||
%s',
|
||||
$fields,
|
||||
$filters,
|
||||
$orderBy,
|
||||
$pagination
|
||||
);
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\NotFoundException;
|
||||
use PandoraFMS\Modules\Shared\Repositories\Repository;
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Entities\UserDataMapper;
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
|
||||
final class CheckOldPasswordUserService
|
||||
{
|
||||
public function __construct(
|
||||
private Repository $repository,
|
||||
private UserDataMapper $userDataMapper
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(User $user): void
|
||||
{
|
||||
$userFilter = new UserFilter();
|
||||
$userFilter->setIdUser($user->getIdUser());
|
||||
$userFilter->setPassword($user->getOldPassword());
|
||||
try {
|
||||
$this->repository->__getOne(
|
||||
$userFilter,
|
||||
$this->userDataMapper
|
||||
);
|
||||
} catch (NotFoundException) {
|
||||
throw new BadRequestException(__('User or the old password is not correct'));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
|
||||
final class CountUserService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UserRepository $userRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserFilter $userFilter): int
|
||||
{
|
||||
return $this->userRepository->count($userFilter);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
use PandoraFMS\Modules\Users\Validations\UserValidation;
|
||||
use PandoraFMS\Modules\Shared\Services\Audit;
|
||||
|
||||
final class CreateUserService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Audit $audit,
|
||||
private UserRepository $userRepository,
|
||||
private UserValidation $userValidation
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(User $user): User
|
||||
{
|
||||
$this->userValidation->__invoke($user);
|
||||
|
||||
$user = $this->userRepository->create($user);
|
||||
|
||||
$this->audit->write(
|
||||
'User Management',
|
||||
' Create user #'.$user->getIdUser()
|
||||
);
|
||||
|
||||
// TODO: Campos personalizados.
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Services\Audit;
|
||||
|
||||
final class DeleteUserService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Audit $audit,
|
||||
private UserRepository $userRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(User $user): void
|
||||
{
|
||||
$idUser = $user->getIdUser();
|
||||
|
||||
$this->userRepository->delete($idUser);
|
||||
|
||||
$this->audit->write(
|
||||
'User Management',
|
||||
' Deleted user #'.$idUser
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfileDataMapper;
|
||||
|
||||
final class GetUserService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UserRepository $userRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(string $idUser): User
|
||||
{
|
||||
$userFilter = new UserFilter();
|
||||
|
||||
/*
|
||||
@var User $entityFilter
|
||||
*/
|
||||
$entityFilter = $userFilter->getEntityFilter();
|
||||
$entityFilter->setIdUser($idUser);
|
||||
|
||||
return $this->userRepository->getOne($userFilter);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Users\Entities\UserFilter;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
|
||||
final class ListUserService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UserRepository $userRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserFilter $userFilter): array
|
||||
{
|
||||
return $this->userRepository->list($userFilter);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\Services;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Services\Audit;
|
||||
use PandoraFMS\Modules\Users\Entities\User;
|
||||
use PandoraFMS\Modules\Users\Repositories\UserRepository;
|
||||
use PandoraFMS\Modules\Users\Validations\UserValidation;
|
||||
|
||||
final class UpdateUserService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Audit $audit,
|
||||
private UserRepository $userRepository,
|
||||
private UserValidation $userValidation
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(User $user, User $oldUser): User
|
||||
{
|
||||
$this->userValidation->__invoke($user, $oldUser);
|
||||
|
||||
$user = $this->userRepository->update($user);
|
||||
|
||||
$this->audit->write(
|
||||
'User Management',
|
||||
' Update user #'.$user->getIdUser()
|
||||
);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfile;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Services\CreateUserProfileService;
|
||||
|
||||
final class CreateUserProfileAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private CreateUserProfileService $createUserProfileService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserProfile $userProfile): UserProfile
|
||||
{
|
||||
return $this->createUserProfileService->__invoke($userProfile);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfile;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Services\DeleteUserProfileService;
|
||||
|
||||
final class DeleteUserProfileAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private DeleteUserProfileService $deleteService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserProfile $userProfile): void
|
||||
{
|
||||
$this->deleteService->__invoke($userProfile);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfile;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Services\GetUserProfileService;
|
||||
|
||||
final class GetUserProfileAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private GetUserProfileService $getUserProfileService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(string $idUser, int $idProfile): UserProfile
|
||||
{
|
||||
return $this->getUserProfileService->__invoke($idUser, $idProfile);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Actions;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfileFilter;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Services\CountUserProfileService;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Services\ListUserProfileService;
|
||||
use PandoraFMS\Modules\Shared\Entities\PaginationData;
|
||||
|
||||
final class ListUserProfileAction
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private ListUserProfileService $listUserProfileService,
|
||||
private CountUserProfileService $countUserProfileService
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserProfileFilter $userProfileFilter): array
|
||||
{
|
||||
return (new PaginationData(
|
||||
$userProfileFilter->getPage(),
|
||||
$userProfileFilter->getSizePage(),
|
||||
$this->countUserProfileService->__invoke($userProfileFilter),
|
||||
$this->listUserProfileService->__invoke($userProfileFilter)
|
||||
))->toArray();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Actions\CreateUserProfileAction;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfile;
|
||||
use PandoraFMS\Modules\Profiles\Actions\GetProfileAction;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class CreateUserProfileController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private CreateUserProfileAction $createUserProfileAction,
|
||||
private ValidateAclSystem $acl,
|
||||
private GetUserAction $getUserAction,
|
||||
private GetProfileAction $getProfileAction
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* tags={"Users"},
|
||||
* path="/user/{id}/profile/{idProfile}",
|
||||
* summary="Create user profile",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterProfileId"),
|
||||
* @OA\RequestBody(ref="#/components/requestBodies/requestBodyUserProfile"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/ResponseUserProfile"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$user = $this->getUserAction->__invoke($idUser);
|
||||
|
||||
$this->acl->validate(0, 'UM', ' tried to manage user');
|
||||
|
||||
$idProfile = $this->getParam($request, 'idProfile');
|
||||
$profile = $this->getProfileAction->__invoke($idProfile);
|
||||
|
||||
// @var UserProfile $userProfile.
|
||||
$userProfile = $this->fromRequest($request, UserProfile::class);
|
||||
$userProfile->setIdUser($idUser);
|
||||
$userProfile->setIdProfile($idProfile);
|
||||
|
||||
$result = $this->createUserProfileAction->__invoke($userProfile);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Profiles\Actions\GetProfileAction;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Actions\DeleteUserProfileAction;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Actions\GetUserProfileAction;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class DeleteUserProfileController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private DeleteUserProfileAction $deleteUserProfileAction,
|
||||
private ValidateAclSystem $acl,
|
||||
private GetUserAction $getUserAction,
|
||||
private GetProfileAction $getProfileAction,
|
||||
private GetUserProfileAction $getUserProfileAction
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Delete(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* tags={"Users"},
|
||||
* path="/user/{id}/profile/{idProfile}",
|
||||
* summary="Deletes user profile.",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterProfileId"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/successfullyDeleted"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$user = $this->getUserAction->__invoke($idUser);
|
||||
|
||||
$idProfile = $this->getParam($request, 'idProfile');
|
||||
$profile = $this->getProfileAction->__invoke($idProfile);
|
||||
|
||||
$userProfile = $this->getUserProfileAction->__invoke($idUser, $idProfile);
|
||||
$result = $this->deleteUserProfileAction->__invoke($userProfile);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Profiles\Actions\GetProfileAction;
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Actions\GetUserProfileAction;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class GetUserProfileController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private GetUserProfileAction $getUserProfileAction,
|
||||
private GetUserAction $getUserAction,
|
||||
private GetProfileAction $getProfileAction,
|
||||
private ValidateAclSystem $acl
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* path="/user/{id}/profile/{idProfile}",
|
||||
* tags={"Users"},
|
||||
* summary="show data field user profile",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterProfileId"),
|
||||
* @OA\Response(response=200, ref="#/components/responses/ResponseUserProfile"),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$user = $this->getUserAction->__invoke($idUser);
|
||||
|
||||
$idProfile = $this->getParam($request, 'idProfile');
|
||||
$this->getProfileAction->__invoke($idProfile);
|
||||
|
||||
$result = $this->getUserProfileAction->__invoke($idUser, $idProfile);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Controllers;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Controllers\Controller;
|
||||
use PandoraFMS\Modules\Shared\Services\ValidateAclSystem;
|
||||
use PandoraFMS\Modules\Users\Actions\GetUserAction;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Actions\ListUserProfileAction;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfileFilter;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
final class ListUserProfileController extends Controller
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private ListUserProfileAction $listUserProfileAction,
|
||||
private GetUserAction $getUserAction,
|
||||
private ValidateAclSystem $acl,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @OA\Post(
|
||||
* security={{ "bearerAuth": {}}},
|
||||
* tags={"Users"},
|
||||
* path="/user/{id}/profiles",
|
||||
* summary="List user profiles",
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterIdUser"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterPage"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterSizePage"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterSortField"),
|
||||
* @OA\Parameter(ref="#/components/parameters/parameterSortDirection"),
|
||||
* @OA\RequestBody(ref="#/components/requestBodies/requestBodyUserProfile"),
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="List data profiles user object",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="paginationData",
|
||||
* type="object",
|
||||
* ref="#/components/schemas/paginationData",
|
||||
* description="Page object",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* ref="#/components/schemas/UserProfile",
|
||||
* description="Array of profiles"
|
||||
* )
|
||||
* ),
|
||||
* ),
|
||||
* )
|
||||
* }
|
||||
* ),
|
||||
* @OA\Response(response=400, ref="#/components/responses/BadRequest"),
|
||||
* @OA\Response(response=401, ref="#/components/responses/Unauthorized"),
|
||||
* @OA\Response(response=403, ref="#/components/responses/Forbidden"),
|
||||
* @OA\Response(response=404, ref="#/components/responses/NotFound"),
|
||||
* @OA\Response(response=500, ref="#/components/responses/InternalServerError")
|
||||
* )
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): Response
|
||||
{
|
||||
$idUser = $this->getParam($request, 'id');
|
||||
$user = $this->getUserAction->__invoke($idUser);
|
||||
|
||||
// @var UserProfileFilter $userProfileFilter.
|
||||
$userProfileFilter = $this->fromRequest($request, UserProfileFilter::class);
|
||||
$userProfileFilter->getEntityFilter()->setIdUser($idUser);
|
||||
|
||||
$result = $this->listUserProfileAction->__invoke($userProfileFilter);
|
||||
return $this->getResponse($response, $result);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Entities;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Entities\Entity;
|
||||
use PandoraFMS\Modules\Shared\Validators\Validator;
|
||||
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="UserProfile",
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="idUserProfile",
|
||||
* type="integer",
|
||||
* nullable=false,
|
||||
* description="Id user profile",
|
||||
* readOnly=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="idUser",
|
||||
* type="string",
|
||||
* nullable=false,
|
||||
* readOnly=true,
|
||||
* description="Id User"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="idProfile",
|
||||
* type="integer",
|
||||
* nullable=false,
|
||||
* readOnly=true,
|
||||
* description="Id Profile"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="idGroup",
|
||||
* type="integer",
|
||||
* nullable=false,
|
||||
* description="Id Group"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="assignedBy",
|
||||
* type="string",
|
||||
* nullable=false,
|
||||
* default=null,
|
||||
* readOnly=true,
|
||||
* description="Create user profile by"
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="ResponseUserProfile",
|
||||
* description="User Profile type object",
|
||||
* content={
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(
|
||||
* type="object",
|
||||
* ref="#/components/schemas/UserProfile",
|
||||
* description="User Profile type object"
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* parameter="parameterProfileId",
|
||||
* name="idProfile",
|
||||
* in="path",
|
||||
* description="Profile id",
|
||||
* required=true,
|
||||
* @OA\Schema(
|
||||
* type="integer",
|
||||
* default=1
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* @OA\RequestBody(
|
||||
* request="requestBodyUserProfile",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(ref="#/components/schemas/UserProfile")
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
final class UserProfile extends Entity
|
||||
{
|
||||
|
||||
private ?int $idUserProfile = null;
|
||||
|
||||
private ?string $idUser = null;
|
||||
|
||||
private ?int $idProfile = null;
|
||||
|
||||
private ?int $idGroup = null;
|
||||
|
||||
private ?string $assignedBy = null;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function fieldsReadOnly(): array
|
||||
{
|
||||
return ['idUserProfile' => 1];
|
||||
}
|
||||
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'idUserProfile' => $this->getIdUserProfile(),
|
||||
'idUser' => $this->getIdUser(),
|
||||
'idProfile' => $this->getIdProfile(),
|
||||
'idGroup' => $this->getIdGroup(),
|
||||
'assignedBy' => $this->getAssignedBy(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getValidations(): array
|
||||
{
|
||||
return [
|
||||
'idUserProfile' => [
|
||||
Validator::INTEGER,
|
||||
Validator::GREATEREQUALTHAN,
|
||||
],
|
||||
'idUser' => Validator::STRING,
|
||||
'idProfile' => [
|
||||
Validator::INTEGER,
|
||||
Validator::GREATEREQUALTHAN,
|
||||
],
|
||||
'idGroup' => [
|
||||
Validator::INTEGER,
|
||||
Validator::GREATEREQUALTHAN,
|
||||
],
|
||||
'assignedBy' => Validator::STRING,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function validateFields(array $filters): array
|
||||
{
|
||||
return (new Validator())->validate($filters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of idUserProfile.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getIdUserProfile(): ?int
|
||||
{
|
||||
return $this->idUserProfile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of idUserProfile.
|
||||
*
|
||||
* @param integer $idUserProfile
|
||||
*/
|
||||
public function setIdUserProfile(?int $idUserProfile): self
|
||||
{
|
||||
$this->idUserProfile = $idUserProfile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of idUser.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getIdUser(): ?string
|
||||
{
|
||||
return $this->idUser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of idUser.
|
||||
*
|
||||
* @param string $idUser
|
||||
*/
|
||||
public function setIdUser(?string $idUser): self
|
||||
{
|
||||
$this->idUser = $idUser;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of idProfile.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getIdProfile(): ?int
|
||||
{
|
||||
return $this->idProfile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of idProfile.
|
||||
*
|
||||
* @param integer $idProfile
|
||||
*/
|
||||
public function setIdProfile(?int $idProfile): self
|
||||
{
|
||||
$this->idProfile = $idProfile;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of idGroup.
|
||||
*
|
||||
* @return ?int
|
||||
*/
|
||||
public function getIdGroup(): ?int
|
||||
{
|
||||
return $this->idGroup;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of idGroup.
|
||||
*
|
||||
* @param integer $idGroup
|
||||
*/
|
||||
public function setIdGroup(?int $idGroup): self
|
||||
{
|
||||
$this->idGroup = $idGroup;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the value of assignedBy.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getAssignedBy(): ?string
|
||||
{
|
||||
return $this->assignedBy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the value of assignedBy.
|
||||
*
|
||||
* @param string $assignedBy
|
||||
*/
|
||||
public function setAssignedBy(?string $assignedBy): self
|
||||
{
|
||||
$this->assignedBy = $assignedBy;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Entities;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Builders\Builder;
|
||||
use PandoraFMS\Modules\Shared\Core\DataMapperAbstract;
|
||||
use PandoraFMS\Modules\Shared\Core\MappeableInterface;
|
||||
use PandoraFMS\Modules\Shared\Repositories\Repository;
|
||||
|
||||
final class UserProfileDataMapper extends DataMapperAbstract
|
||||
{
|
||||
public const TABLE_NAME = 'tusuario_perfil';
|
||||
public const ID_USER_PROFILE = 'id_up';
|
||||
public const ID_USER = 'id_usuario';
|
||||
public const ID_PROFILE = 'id_perfil';
|
||||
public const ID_GROUP = 'id_grupo';
|
||||
public const ASSIGNED_BY = 'assigned_by';
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Repository $repository,
|
||||
private Builder $builder,
|
||||
) {
|
||||
parent::__construct(
|
||||
self::TABLE_NAME,
|
||||
self::ID_USER_PROFILE,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function getClassName(): string
|
||||
{
|
||||
return UserProfile::class;
|
||||
}
|
||||
|
||||
|
||||
public function fromDatabase(array $data): UserProfile
|
||||
{
|
||||
return $this->builder->build(
|
||||
new UserProfile(),
|
||||
[
|
||||
'idUserProfile' => $data[self::ID_USER_PROFILE],
|
||||
'idUser' => $data[self::ID_USER],
|
||||
'idProfile' => $data[self::ID_PROFILE],
|
||||
'idGroup' => $data[self::ID_GROUP],
|
||||
'assignedBy' => $data[self::ASSIGNED_BY],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function toDatabase(MappeableInterface $data): array
|
||||
{
|
||||
/*
|
||||
@var UserProfile $data
|
||||
*/
|
||||
return [
|
||||
self::ID_USER_PROFILE => $data->getIdUserProfile(),
|
||||
self::ID_USER => $data->getIdUser(),
|
||||
self::ID_PROFILE => $data->getIdProfile(),
|
||||
self::ID_GROUP => $data->getIdGroup(),
|
||||
self::ASSIGNED_BY => $data->getAssignedBy(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Entities;
|
||||
|
||||
use PandoraFMS\Modules\Shared\Core\FilterAbstract;
|
||||
use PandoraFMS\Modules\Shared\Validators\Validator;
|
||||
|
||||
/**
|
||||
* @OA\Schema(
|
||||
* schema="UserProfileFilter",
|
||||
* type="object",
|
||||
* allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/UserProfile"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="idUserProfile",
|
||||
* default=null,
|
||||
* readOnly=false
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* )
|
||||
*
|
||||
* @OA\RequestBody(
|
||||
* request="requestBodyUserProfileFilter",
|
||||
* required=true,
|
||||
* @OA\MediaType(
|
||||
* mediaType="application/json",
|
||||
* @OA\Schema(ref="#/components/schemas/UserProfileFilter")
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
final class UserProfileFilter extends FilterAbstract
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->setDefaultFieldOrder(UserProfileDataMapper::ID_USER_PROFILE);
|
||||
$this->setDefaultDirectionOrder($this::ASC);
|
||||
$this->setEntityFilter(new UserProfile());
|
||||
}
|
||||
|
||||
|
||||
public function fieldsTranslate(): array
|
||||
{
|
||||
return [
|
||||
'idUserProfile' => UserProfileDataMapper::ID_USER_PROFILE,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function fieldsReadOnly(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
public function getValidations(): array
|
||||
{
|
||||
$validations = [];
|
||||
if ($this->getEntityFilter() !== null) {
|
||||
$validations = $this->getEntityFilter()->getValidations();
|
||||
}
|
||||
|
||||
return $validations;
|
||||
}
|
||||
|
||||
|
||||
public function validateFields(array $filters): array
|
||||
{
|
||||
return (new Validator())->validate($filters);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Repositories;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfile;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfileDataMapper;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfileFilter;
|
||||
use PandoraFMS\Modules\Shared\Exceptions\BadRequestException;
|
||||
use PandoraFMS\Modules\Shared\Repositories\Repository;
|
||||
|
||||
class UserProfileRepository
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private Repository $repository,
|
||||
private UserProfileDataMapper $userProfileDataMapper
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return UserProfile[],
|
||||
*/
|
||||
public function list(UserProfileFilter $userProfileFilter): array
|
||||
{
|
||||
return $this->repository->__list(
|
||||
$userProfileFilter,
|
||||
$this->userProfileDataMapper
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function count(UserProfileFilter $userProfileFilter): int
|
||||
{
|
||||
return $this->repository->__count(
|
||||
$userProfileFilter,
|
||||
$this->userProfileDataMapper
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function getOne(UserProfileFilter $userProfileFilter): UserProfile
|
||||
{
|
||||
return $this->repository->__getOne(
|
||||
$userProfileFilter,
|
||||
$this->userProfileDataMapper
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function create(UserProfile $userProfile): UserProfile
|
||||
{
|
||||
try {
|
||||
$id = $this->repository->__create($userProfile, $this->userProfileDataMapper);
|
||||
return $userProfile->setIdUserProfile($id);
|
||||
} catch (\Throwable $th) {
|
||||
throw new BadRequestException(__('User profile already exists in the bbdd:'.$th->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function update(UserProfile $userProfile): UserProfile
|
||||
{
|
||||
return $this->repository->__update(
|
||||
$userProfile,
|
||||
$this->userProfileDataMapper,
|
||||
$userProfile->getIdUserProfile()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function delete(int $id, ?string $key=null): void
|
||||
{
|
||||
$this->repository->__delete($id, $this->userProfileDataMapper, $key);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace PandoraFMS\Modules\Users\UserProfiles\Services;
|
||||
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Entities\UserProfileFilter;
|
||||
use PandoraFMS\Modules\Users\UserProfiles\Repositories\UserProfileRepository;
|
||||
|
||||
final class CountUserProfileService
|
||||
{
|
||||
|
||||
|
||||
public function __construct(
|
||||
private UserProfileRepository $userProfileRepository,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
public function __invoke(UserProfileFilter $userProfileFilter): int
|
||||
{
|
||||
return $this->userProfileRepository->count($userProfileFilter);
|
||||
}
|
||||
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue