This commit is contained in:
2021-12-25 23:17:15 -03:00
parent bbee033a8a
commit 3580738273
23 changed files with 755 additions and 81 deletions

View File

@ -90,7 +90,7 @@ abstract class Model extends BaseModel implements ModelInterface {
protected static function parseInput($input): array {
return array_intersect_key((array) $input, array_combine(static::$fields, static::$fields));
}
public static function add(ModelFactory $factory, $input): ?ModelInterface {
public static function add(ModelFactory $factory, $input): bool|ModelInterface {
$data = static::parseInput($input);
$class = get_called_class();
if (method_exists($class, 'find')) {
@ -103,7 +103,7 @@ abstract class Model extends BaseModel implements ModelInterface {
$where = array_values($where);
$obj = $factory->find($class)->where($where)->one();
}
if ($obj === null) {
if ($obj === false or $obj === null) {
$obj = $factory->create($class, $data);
}
return $obj;

View File

@ -0,0 +1,82 @@
<?php
namespace Incoviba\API\Common\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Incoviba\API\Common\Define\Controller\Json;
use Incoviba\API\Common\Service\Auth as Service;
use Incoviba\API\Common\Factory\Model as Factory;
use Incoviba\Auth\User;
use Incoviba\Auth\Login;
class Auth {
use Json;
public function generate(Request $request, Response $response, Service $service): Response {
$key = $service->generate();
return $this->withJson($response, compact('key'));
}
public function login(Request $request, Response $response, Service $service, Factory $factory): Response {
$post = json_decode($request->getBody());
$user = $factory->find(User::class)->where([['name', $post->name]])->one();
$output = [
'login' => false,
'token' => ''
];
if ($user->enabled == 0) {
$this->withJson($response, $output);
}
if ($user->validate($post->password)) {
$token = $service->generateToken();
$status = $user->setToken($token->selector, $token->token);
if ($status['logged_in']) {
$output['login'] = true;
$output['token'] = $token->full;
$output['expires'] = $status['expires'];
}
}
return $this->withJson($response, $output);
}
protected function getLogin(object $post, Factory $factory): bool|Login {
list($selector, $token) = explode(':', $post->token); //Token from the cookie
$login = $factory->find(Login::class)->where([['selector', $selector]])->one();
if ($login === false or !password_verify($token, $login->token) or !$login->isValid()) {
return false;
}
return $login;
}
public function validate(Request $request, Response $response, Factory $factory): Response {
$post = json_decode($request->getBody());
if (!$this->getLogin($post, $factory)) {
return $this->withJson($response, ['token' => $post->token, 'error' => 'Not authorized'], 401);
}
return $this->withJson($response, ['token' => $post->token, 'status' => 'Authorized']);
}
public function user(Request $request, Response $response, Factory $factory): Response {
$post = json_decode($request->getBody());
$login = $this->getLogin($post, $factory);
if (!$login) {
return $this->withJson($response, ['token' => $post->token, 'error' => 'Not authorized'], 401);
}
$output = [
'token' => $post->token,
'user' => $login->user()->name
];
return $this->withJson($response, $output);
}
public function logout(Request $request, Response $response, Factory $factory): Response {
$post = json_decode($request->getBody());
list($selector, $token) = explode(':', $post->token); //Token from the cookie
$login = $factory->find(Login::class)->where([['selector', $selector]])->one();
$output = [
'token' => $post->token,
'logout' => false
];
if ($login !== false) {
$output['logout'] = $login->user()->logout();
} else {
$output['logout'] = true;
}
return $this->withJson($response, $output);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace Incoviba\API\Common\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Incoviba\API\Common\Factory\Model as Factory;
use Incoviba\API\Common\Define\Controller\Json;
use Incoviba\Admin\Config;
class Configs {
use Json;
public function get(Request $request, Response $response, Factory $factory, $config_name): Response {
$config = $factory->find(Config::class)->where((['name', $config_name]))->one();
$output = [
'name' => $config_name,
'valid' => $config !== false,
'value' => $config->value
];
return $this->withJson($response, $output);
}
public function set(Request $request, Response $response, Factory $factory): Response {
$post = $request->getParsedBody();
$config = $factory->find(Config::class)->where([['name', $post['name']]])->one();
if (!$config) {
$config = Config::add($factory, $post);
} else {
$config->edit($post);
}
$output = [
'input' => $post,
'config' => null
];
if ($config !== false) {
$config->save();
$output['config'] = [
'name' => $config->name,
'value' => $config->value
];
}
return $this->withJson($response, $output);
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace Incoviba\API\Common\Controller\Proyectos;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Incoviba\API\Common\Factory\Model as Factory;
use Incoviba\API\Common\Define\Controller\Json;
use Incoviba\Proyecto\Proyecto;
class Cierres {
use Json;
public function __invoke(Request $request, Response $response, Factory $factory): Response {
$proyectos = $factory->find(Proyecto::class)->many();
$cierres = [];
foreach ($proyectos as $proyecto) {
if (count($proyecto->cierres()) == 0) {
continue;
}
$cierres[$proyecto->descripcion] = [
'proyecto' => $proyecto->descripcion,
'total' => count($proyecto->cierres()),
'promesados' => count($proyecto->cierres(3)),
'rechazados' => count($proyecto->cierres(-1)),
'pendientes' => count($proyecto->cierres(2)),
'ultimo_pendiente' => (count($proyecto->cierres(2)) > 0) ? $proyecto->cierres(2)[0]->periodo() : 0
];
}
return $this->withJson($response, compact('cierres'));
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace Incoviba\API\Common\Controller\Proyectos;
use Incoviba\Proyecto\Proyecto;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Incoviba\API\Common\Define\Controller\Json;
use Incoviba\API\Common\Factory\Model as Factory;
class Cuotas {
use Json;
public function __invoke(Request $request, Response $response, Factory $factory): Response {
$proyectos = $factory->find(Proyecto::class)->many();
$cuotas = [];
foreach ($proyectos as $proyecto) {
foreach ($proyecto->cuotas() as $cuota) {
$cuotas []= $cuota->toArray();
}
}
return $this->withJson($response, ['cuotas' => $cuotas]);
}
public function mes(Request $request, Response $response, Factory $factory): Response {
$proyectos = $factory->find(Proyecto::class)->many();
$dias = [];
foreach ($proyectos as $proyecto) {
foreach ($proyecto->cuotasMes() as $cuota) {
$f = $cuota->pago()->fecha();
if ($f->isoWeekday() == 6 or $f->isoWeekDay() == 7) {
$f = $f->copy()->addDays(2)->startOfWeek();
}
$dia = $f->format('Y-m-d');
if (!isset($dias[$dia])) {
$dias[$dia] = ['dia' => $dia, 'proyectos' => [$proyecto->descripcion => ['proyecto' => $proyecto->descripcion, 'cantidad' => 0]]];
}
if (!isset($dias[$dia]['proyectos'][$proyecto->descripcion])) {
$dias[$dia]['proyectos'][$proyecto->descripcion] = ['proyecto' => $proyecto->descripcion, 'cantidad' => 0];
}
$dias[$dia]['proyectos'][$proyecto->descripcion]['cantidad'] ++;
}
}
uksort($dias, function($a, $b) {
return strcmp($a, $b);
});
return $this->withJson($response, ['proyecto' => $proyecto->toArray(), 'dias' => $dias]);
}
public function hoy(Request $request, Response $response, Factory $factory): Response {
$proyectos = $factory->find(Proyecto::class)->many();
$hoy = 0;
foreach ($proyectos as $proyecto) {
$hoy += count($proyecto->cuotasHoy());
}
return $this->withJson($response, ['hoy' => $hoy]);
}
public function pendientes(Request $request, Response $response, Factory $factory): Response {
$proyectos = $factory->find(Proyecto::class)->many();
$pendientes = 0;
foreach ($proyectos as $proyecto) {
$pendientes += count($proyecto->cuotasPendientes());
}
return $this->withJson($response, ['pendientes' => $pendientes]);
}
}

View File

@ -51,7 +51,7 @@ interface Model {
* @param array $input Input data
* @return Model|null
*/
public static function add(ModelFactory $factory, array $input): ?Model;
public static function add(ModelFactory $factory, array $input): bool|Model;
/**
* Edit current model parsing {$input} data

View File

@ -1,7 +1,7 @@
<?php
namespace Incoviba\API\Common\Factory;
use http\Exception\InvalidArgumentException;
use InvalidArgumentException;
use ORM;
use Incoviba\API\Common\Alias\Model as BaseModel;
use Incoviba\API\Common\Define\Model as ModelInterface;
@ -27,7 +27,7 @@ class Model {
$model = $model->where([[$f, $v]]);
}
$model = $model->one();
if ($model !== null) {
if ($model !== false and $model !== null) {
return $model;
}
}
@ -142,13 +142,20 @@ class Model {
'full', 'full outer', 'full_outer', 'fullouter', 'outer' => 'fullOuterJoin'
};
if (strtolower($join->type) == 'raw') {
if (isset($join->alias)) {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to], $join->alias, $join->params);
if (isset($join->params)) {
if (isset($join->alias)) {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to], $join->alias, $join->params);
} else {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to], $join->params);
}
} else {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to], $join->params);
if (isset($join->alias)) {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to], $join->alias);
} else {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to]);
}
}
}
if (isset($join->alias)) {
} elseif (isset($join->alias)) {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to], $join->alias);
} else {
$orm = $orm->{$method}($join->table, [$join->from, $join->operator, $join->to]);
@ -267,14 +274,34 @@ class Model {
return $this;
}
protected function addOrder($order) {
$map = [
'column' => ['column', 'col', 'c', 0],
'direction' => ['direction', 'dir', 'd', 1]
];
if (!is_array($order)) {
$order = [$order];
}
$defaults = ['direction' => 'asc'];
$required = ['column', 'direction'];
$o = [];
foreach ($order as $key => $val) {
$k = match (strtolower($key)) {
/*$k = match (strtolower($key)) {
'column', 'col', 'c', 0 => 'column',
'direction', 'dir', 'd', 1 => 'direction'
};
};*/
$k = -1;
foreach ($map as $i => $m) {
if (is_array($m)) {
if (in_array($key, $m)) {
$k = $i;
break;
}
continue;
}
if ($key == $m) {
$k = $i;
}
}
$o[$k] = $val;
}
foreach ($defaults as $key => $val) {

View File

@ -4,48 +4,57 @@ namespace Incoviba\API\Common\Service;
use Psr\Http\Message\ServerRequestInterface as Request;
class Auth {
protected string $key;
public function __construct(string $key) {
$this->key = $key;
}
public function isValid(Request $request): bool {
$api_key = '';
if ($request->hasHeader('Authorization')) {
$api_key = $request->getHeader('Authorization');
if (is_array($api_key)) {
$api_key = $api_key[0];
}
if (str_contains($api_key, 'Bearer')) {
$api_key = explode(' ', $api_key)[1];
}
} elseif ($request->getParsedBody() !== null and in_array('API_KEY', $request->getParsedBody())) {
$api_key = $request->getParsedBody()['API_KEY'];
} elseif ($request->getQueryParams() !== null and in_array('API_KEY', array_keys($request->getQueryParams()))) {
$api_key = $request->getQueryParams()['API_KEY'];
protected string $key;
public function __construct(string $key) {
$this->key = $key;
}
if ($this->key == $api_key) {
return true;
public function isValid(Request $request): bool {
$api_key = $this->getRequestKey($request);
if ($this->key == $api_key) {
return true;
}
return false;
}
return false;
}
public function generate(int $length = 32, bool $removeSimilarCharacters = true): string {
$token = "";
try {
$bytesWithMargin = random_bytes($length*3);
$base64 = base64_encode($bytesWithMargin);
$purified = preg_replace("/[+=\/.]/", "", $base64);
if ($removeSimilarCharacters){
$purified = preg_replace("/[I1l0Oo]/", "", $purified);
protected function getRequestKey(Request $request) {
if ($request->hasHeader('Authorization')) {
return $this->getKeyFromHeader($request);
} elseif ($request->getParsedBody() !== null and in_array('API_KEY', $request->getParsedBody())) {
return $request->getParsedBody()['API_KEY'];
} elseif ($request->getQueryParams() !== null and in_array('API_KEY', array_keys($request->getQueryParams()))) {
return $request->getQueryParams()['API_KEY'];
}
return '';
}
protected function getKeyFromHeader(Request $request) {
$api_key = $request->getHeader('Authorization');
if (is_array($api_key)) {
$api_key = $api_key[0];
}
if (str_contains($api_key, 'Bearer')) {
$api_key = explode(' ', $api_key)[1];
}
return $api_key;
}
public function generate(int $length = 32, bool $removeSimilarCharacters = true): string {
$token = "";
try {
$bytesWithMargin = random_bytes($length*3);
$base64 = base64_encode($bytesWithMargin);
$purified = preg_replace("/[+=\/.]/", "", $base64);
if ($removeSimilarCharacters) {
$purified = preg_replace("/[I1l0Oo]/", "", $purified);
}
$token = substr($purified, 0, $length);
} catch (\Exception $e){
error_log(var_export($e, true));
}
return $token;
}
$token = substr($purified, 0, $length);
} catch (\Exception $e){
echo $e->getMessage();
public function generateToken(): object {
$selector = bin2hex(\random_bytes(12));
$token = bin2hex(\random_bytes(20));
$full = "{$selector}:{$token}";
$token = password_hash($token, \PASSWORD_DEFAULT);
return (object) compact('selector', 'token', 'full');
}
return $token;
}
}