feat(cloudron): add tirreno package artifacts
- Add CloudronStack/output/CloudronPackages-Artifacts/tirreno/ directory and its contents - Includes package manifest, Dockerfile, source code, documentation, and build artifacts - Add tirreno-1761840148.tar.gz as a build artifact - Add tirreno-cloudron-package-1761841304.tar.gz as the Cloudron package - Include all necessary files for the tirreno Cloudron package This adds the complete tirreno Cloudron package artifacts to the repository.
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Base;
|
||||
|
||||
class Grid extends \Models\BaseSql {
|
||||
use \Traits\Enrichment\TimeZones;
|
||||
use \Traits\DateRange;
|
||||
|
||||
protected $DB_TABLE_NAME = 'event';
|
||||
|
||||
protected $idsModel = null;
|
||||
protected $apiKey = null;
|
||||
protected $query = null;
|
||||
|
||||
protected function getGrid(?string $ids = null, array $idsParams = []): array {
|
||||
$this->setIds($ids, $idsParams);
|
||||
|
||||
$draw = $this->f3->get('REQUEST.draw');
|
||||
|
||||
$draw = $draw ?? 1;
|
||||
$data = $this->getData();
|
||||
$total = $this->getTotal();
|
||||
|
||||
$params = $this->f3->get('GET');
|
||||
$dateRange = $this->getDatesRange($params);
|
||||
|
||||
return [
|
||||
'data' => $data,
|
||||
'draw' => $draw,
|
||||
'recordsTotal' => $total,
|
||||
'recordsFiltered' => $total,
|
||||
'dateRange' => $dateRange,
|
||||
];
|
||||
}
|
||||
|
||||
public function setIds(?string $ids, array $idsParams): void {
|
||||
$this->query->setIds($ids, $idsParams);
|
||||
}
|
||||
|
||||
protected function getData(): array {
|
||||
[$query, $params] = $this->query->getData();
|
||||
|
||||
$results = $this->execQuery($query, $params);
|
||||
|
||||
$this->convertTimeToUserTimezone($results);
|
||||
$this->calculateCustomParams($results);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected function getTotal(): int {
|
||||
[$query, $params] = $this->query->getTotal();
|
||||
|
||||
$results = $this->execQuery($query, $params);
|
||||
|
||||
return $results[0]['count'];
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$this->translateTimeZones($result);
|
||||
}
|
||||
|
||||
protected function calculateCustomParams(array &$result): void {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Base;
|
||||
|
||||
class Ids extends \Models\BaseSql {
|
||||
protected $DB_TABLE_NAME = 'event';
|
||||
|
||||
private $apiKey = null;
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
}
|
||||
|
||||
public function execute(string $query, array $params): array {
|
||||
$params[':api_key'] = $this->apiKey;
|
||||
|
||||
$data = $this->execQuery($query, $params);
|
||||
$results = array_column($data, 'itemid');
|
||||
|
||||
return count($results) ? $results : [-1];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Base;
|
||||
|
||||
class Query {
|
||||
use \Traits\Debug;
|
||||
use \Traits\DateRange;
|
||||
|
||||
protected $f3 = null;
|
||||
protected $apiKey = null;
|
||||
protected $ids = null;
|
||||
protected $idsParams = [];
|
||||
protected $itemKey = null;
|
||||
protected $itemId = null;
|
||||
|
||||
protected $defaultOrder = null;
|
||||
protected $dateRangeField = 'event_country.lastseen';
|
||||
|
||||
protected $allowedColumns = [];
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
$this->f3 = \Base::instance();
|
||||
$this->apiKey = $apiKey;
|
||||
}
|
||||
|
||||
public function setIds(?string $ids, array $idsParams): void {
|
||||
$this->ids = $ids;
|
||||
$this->idsParams = $idsParams;
|
||||
if (count($this->idsParams)) {
|
||||
$this->itemKey = array_keys($this->idsParams)[0];
|
||||
$this->itemId = $this->idsParams[$this->itemKey];
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyOrder(string &$query): void {
|
||||
$request = $this->f3->get('REQUEST');
|
||||
|
||||
$order = $request['order'] ?? [];
|
||||
$columns = $request['columns'] ?? [];
|
||||
|
||||
$orderCondition = $this->defaultOrder;
|
||||
|
||||
if (count($order) && count($columns)) {
|
||||
$orderClauses = [];
|
||||
foreach ($order as $orderData) {
|
||||
$sortDirection = $orderData['dir'] === 'asc' ? 'ASC' : 'DESC';
|
||||
$columnIndex = $orderData['column'];
|
||||
$sortColumn = $columns[$columnIndex]['data'];
|
||||
if (in_array($sortColumn, $this->allowedColumns)) {
|
||||
$orderClauses[] = sprintf('%s %s', $sortColumn, $sortDirection);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($orderClauses)) {
|
||||
$orderCondition = implode(', ', $orderClauses);
|
||||
}
|
||||
}
|
||||
|
||||
if ($orderCondition) {
|
||||
$query .= sprintf(' ORDER BY %s', $orderCondition);
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyDateRange(string &$query, array &$queryParams): void {
|
||||
$params = $this->f3->get('GET');
|
||||
$dateRange = $this->getDatesRange($params);
|
||||
|
||||
if ($dateRange) {
|
||||
$searchConditions = (
|
||||
"AND {$this->dateRangeField} >= :start_time
|
||||
AND {$this->dateRangeField} <= :end_time
|
||||
%s"
|
||||
);
|
||||
|
||||
$query = sprintf($query, $searchConditions);
|
||||
$queryParams[':end_time'] = $dateRange['endDate'];
|
||||
$queryParams[':start_time'] = $dateRange['startDate'];
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyLimit(string &$query, array &$queryParams): void {
|
||||
$request = $this->f3->get('REQUEST');
|
||||
|
||||
$start = $request['start'] ?? null;
|
||||
$length = $request['length'] ?? null;
|
||||
|
||||
if (isset($start) && isset($length)) {
|
||||
$query .= ' LIMIT :length OFFSET :start';
|
||||
|
||||
$queryParams[':start'] = $start;
|
||||
$queryParams[':length'] = $length;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getQueryParams(): array {
|
||||
return [':api_key' => $this->apiKey];
|
||||
}
|
||||
|
||||
public function injectIdQuery(string $field, &$params): string {
|
||||
$idsQuery = $this->ids;
|
||||
if ($idsQuery === null || $idsQuery === '') {
|
||||
return '';
|
||||
}
|
||||
$idsParams = $this->idsParams;
|
||||
|
||||
foreach ($idsParams as $key => $value) {
|
||||
if (!array_key_exists($key, $params) || $params[$key] === null) {
|
||||
$params[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return " AND $field IN ($idsQuery)";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Blacklist;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getAllBlacklistedItems(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['created', 'score_updated_at'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Blacklist;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Blacklist;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'created DESC, type ASC, value ASC';
|
||||
protected $dateRangeField = 'blacklist.created';
|
||||
|
||||
protected $allowedColumns = ['score', 'created', 'type', 'value'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = ("
|
||||
SELECT DISTINCT
|
||||
blacklist.is_important,
|
||||
blacklist.accountid,
|
||||
blacklist.accounttitle,
|
||||
blacklist.created,
|
||||
blacklist.score_updated_at,
|
||||
blacklist.score,
|
||||
blacklist.account_email AS email,
|
||||
extra.type,
|
||||
TRUE AS fraud,
|
||||
CASE extra.type
|
||||
WHEN 'ip' THEN blacklist.ip
|
||||
WHEN 'email' THEN blacklist.email
|
||||
WHEN 'phone' THEN blacklist.phone
|
||||
END AS value,
|
||||
CASE extra.type
|
||||
WHEN 'ip' THEN blacklist.ip_id
|
||||
WHEN 'email' THEN blacklist.email_id
|
||||
WHEN 'phone' THEN blacklist.phone_id
|
||||
END AS entity_id
|
||||
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
event_account.is_important,
|
||||
event_account.id AS accountid,
|
||||
event_account.userid AS accounttitle,
|
||||
event_account.latest_decision AS created,
|
||||
event_account.score_updated_at,
|
||||
event_account.score,
|
||||
|
||||
account_email.email AS account_email,
|
||||
|
||||
CASE WHEN event_ip.fraud_detected THEN split_part(event_ip.ip::text, '/', 1) ELSE NULL END AS ip,
|
||||
CASE WHEN event_ip.fraud_detected THEN event_ip.id ELSE NULL END AS ip_id,
|
||||
event_ip.fraud_detected AS ip_fraud,
|
||||
|
||||
CASE WHEN event_email.fraud_detected THEN event_email.email ELSE NULL END AS email,
|
||||
CASE WHEN event_email.fraud_detected THEN event_email.id ELSE NULL END AS email_id,
|
||||
event_email.fraud_detected AS email_fraud,
|
||||
|
||||
CASE WHEN event_phone.fraud_detected THEN event_phone.phone_number ELSE NULL END AS phone,
|
||||
CASE WHEN event_phone.fraud_detected THEN event_phone.id ELSE NULL END AS phone_id,
|
||||
event_phone.fraud_detected AS phone_fraud
|
||||
|
||||
FROM event
|
||||
|
||||
LEFT JOIN event_account
|
||||
ON event_account.id = event.account
|
||||
|
||||
LEFT JOIN event_email AS account_email
|
||||
ON event_account.lastemail = account_email.id
|
||||
|
||||
LEFT JOIN event_ip
|
||||
ON event_ip.id = event.ip
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON event_email.id = event.email
|
||||
|
||||
LEFT JOIN event_phone
|
||||
ON event_phone.id = event.phone
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key AND
|
||||
event_account.fraud IS TRUE AND
|
||||
(
|
||||
event_email.fraud_detected IS TRUE OR
|
||||
event_ip.fraud_detected IS TRUE OR
|
||||
event_phone.fraud_detected IS TRUE
|
||||
)
|
||||
) AS blacklist,
|
||||
LATERAL (
|
||||
VALUES
|
||||
(CASE WHEN ip_fraud = true THEN 'ip' END),
|
||||
(CASE WHEN email_fraud = true THEN 'email' END),
|
||||
(CASE WHEN phone_fraud = true THEN 'phone' END)
|
||||
) AS extra(type)
|
||||
|
||||
WHERE
|
||||
extra.type IS NOT NULL
|
||||
%s
|
||||
");
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyEntityTypes($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = ("
|
||||
SELECT COUNT(*)
|
||||
FROM (
|
||||
SELECT DISTINCT
|
||||
blacklist.accountid,
|
||||
blacklist.accounttitle,
|
||||
blacklist.created,
|
||||
extra.type,
|
||||
CASE extra.type
|
||||
WHEN 'ip' THEN blacklist.ip
|
||||
WHEN 'email' THEN blacklist.email
|
||||
WHEN 'phone' THEN blacklist.phone
|
||||
END AS value
|
||||
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
event_account.id AS accountid,
|
||||
event_account.userid AS accounttitle,
|
||||
event_account.latest_decision AS created,
|
||||
CASE WHEN event_ip.fraud_detected THEN split_part(event_ip.ip::text, '/', 1) ELSE NULL END AS ip,
|
||||
event_ip.fraud_detected AS ip_fraud,
|
||||
CASE WHEN event_email.fraud_detected THEN event_email.email ELSE NULL END AS email,
|
||||
event_email.fraud_detected AS email_fraud,
|
||||
CASE WHEN event_phone.fraud_detected THEN event_phone.phone_number ELSE NULL END AS phone,
|
||||
event_phone.fraud_detected AS phone_fraud
|
||||
FROM event
|
||||
|
||||
LEFT JOIN event_account
|
||||
ON event_account.id = event.account
|
||||
|
||||
LEFT JOIN event_ip
|
||||
ON event_ip.id = event.ip
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON event_email.id = event.email
|
||||
|
||||
LEFT JOIN event_phone
|
||||
ON event_phone.id = event.phone
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key AND
|
||||
event_account.fraud IS TRUE AND
|
||||
(
|
||||
event_email.fraud_detected IS TRUE OR
|
||||
event_ip.fraud_detected IS TRUE OR
|
||||
event_phone.fraud_detected IS TRUE
|
||||
)
|
||||
) AS blacklist,
|
||||
LATERAL (
|
||||
VALUES
|
||||
(CASE WHEN ip_fraud = true THEN 'ip' END),
|
||||
(CASE WHEN email_fraud = true THEN 'email' END),
|
||||
(CASE WHEN phone_fraud = true THEN 'phone' END)
|
||||
) AS extra(type)
|
||||
|
||||
WHERE
|
||||
extra.type IS NOT NULL
|
||||
%s
|
||||
) AS tbl
|
||||
");
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyEntityTypes($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$searchConditions = '';
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
" AND (
|
||||
LOWER(blacklist.accounttitle) LIKE LOWER(:search_value) OR
|
||||
LOWER(extra.type) LIKE LOWER(:search_value) OR
|
||||
LOWER(CASE extra.type
|
||||
WHEN 'ip' THEN blacklist.ip
|
||||
WHEN 'email' THEN blacklist.email
|
||||
WHEN 'phone' THEN blacklist.phone
|
||||
END) LIKE LOWER(:search_value) OR
|
||||
TO_CHAR(blacklist.created::timestamp without time zone, 'dd/mm/yyyy hh24:mi:ss') LIKE :search_value
|
||||
)"
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search into request
|
||||
$query = sprintf($query, $searchConditions . ' %s');
|
||||
}
|
||||
|
||||
private function applyEntityTypes(string &$query, array &$queryParams): void {
|
||||
$searchCondition = '';
|
||||
|
||||
$entityTypeIds = $this->f3->get('REQUEST.entityTypeIds');
|
||||
if ($entityTypeIds !== null && count($entityTypeIds)) {
|
||||
$clauses = [];
|
||||
|
||||
foreach ($entityTypeIds as $key => $entityTypeId) {
|
||||
$clauses[] = 'extra.type = :entity_type_' . $key;
|
||||
$queryParams[':entity_type_' . $key] = strtolower(\Utils\Constants::get('ENTITY_TYPES')[$entityTypeId]);
|
||||
}
|
||||
|
||||
$searchCondition = ' AND (' . implode(' OR ', $clauses) . ')';
|
||||
}
|
||||
|
||||
$query = sprintf($query, $searchCondition);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Bots;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
use \Traits\Enrichment\Devices;
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getAllBots(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
protected function calculateCustomParams(array &$result): void {
|
||||
$this->applyDeviceParams($result);
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['lastseen'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Bots;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Bots;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'ed.lastseen DESC';
|
||||
protected $dateRangeField = 'ed.lastseen';
|
||||
|
||||
protected $allowedColumns = ['id', 'device', 'os_name', 'modified'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_ua_parsed.id,
|
||||
event_ua_parsed.device,
|
||||
event_ua_parsed.browser_name,
|
||||
event_ua_parsed.browser_version,
|
||||
event_ua_parsed.os_name,
|
||||
event_ua_parsed.os_version,
|
||||
event_ua_parsed.ua,
|
||||
event_ua_parsed.modified,
|
||||
ed.lastseen
|
||||
|
||||
FROM
|
||||
event_ua_parsed
|
||||
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
user_agent,
|
||||
MAX(lastseen) AS lastseen
|
||||
FROM event_device
|
||||
WHERE key = :api_key
|
||||
GROUP BY user_agent
|
||||
) AS ed
|
||||
ON event_ua_parsed.id = ed.user_agent
|
||||
|
||||
WHERE
|
||||
event_ua_parsed.key = :api_key AND
|
||||
event_ua_parsed.modified IS TRUE
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(*)
|
||||
|
||||
FROM
|
||||
event_ua_parsed
|
||||
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
user_agent,
|
||||
MAX(lastseen) AS lastseen
|
||||
FROM event_device
|
||||
WHERE key = :api_key
|
||||
GROUP BY user_agent
|
||||
) AS ed
|
||||
ON event_ua_parsed.id = ed.user_agent
|
||||
|
||||
WHERE
|
||||
event_ua_parsed.key = :api_key AND
|
||||
event_ua_parsed.modified IS TRUE
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$searchConditions = '';
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions = (
|
||||
' AND
|
||||
(
|
||||
event_ua_parsed.device LIKE LOWER(:search_value) OR
|
||||
event_ua_parsed.browser_name LIKE LOWER(:search_value) OR
|
||||
event_ua_parsed.os_name LIKE LOWER(:search_value) OR
|
||||
event_ua_parsed.ua LIKE LOWER(:search_value)
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Countries;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getAllCountries(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Countries;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Countries;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = null;
|
||||
protected $dateRangeField = 'event_country.lastseen';
|
||||
|
||||
protected $allowedColumns = ['full_country', 'country', 'total_account', 'total_visit', 'total_ip', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
countries.iso AS country_iso,
|
||||
countries.id AS country_id,
|
||||
countries.value AS full_country,
|
||||
countries.id,
|
||||
|
||||
event_country.total_visit,
|
||||
event_country.total_account,
|
||||
event_country.total_ip
|
||||
|
||||
|
||||
FROM
|
||||
event_country
|
||||
|
||||
LEFT JOIN countries
|
||||
ON event_country.country = countries.id
|
||||
|
||||
WHERE
|
||||
event_country.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(event_country.id)
|
||||
|
||||
FROM
|
||||
event_country
|
||||
|
||||
INNER JOIN countries
|
||||
ON event_country.country = countries.id
|
||||
|
||||
WHERE
|
||||
event_country.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
//Add dates into request
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = '';
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
LOWER(countries.value) LIKE LOWER(:search_value)
|
||||
OR LOWER(countries.iso) LIKE LOWER(:search_value)
|
||||
)'
|
||||
);
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Devices;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
use \Traits\Enrichment\Devices;
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getDevicesByIpId(int $ipId): array {
|
||||
$params = [':ip_id' => $ipId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getDevicesIdsByIpId(), $params);
|
||||
}
|
||||
|
||||
public function getDevicesByUserId(int $userId): array {
|
||||
$params = [':account_id' => $userId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getDevicesIdsByUserId(), $params);
|
||||
}
|
||||
|
||||
public function getDevicesByResourceId(int $resourceId): array {
|
||||
$params = [':resource_id' => $resourceId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getDevicesIdsByResourceId(), $params);
|
||||
}
|
||||
|
||||
public function getAllDevices(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
protected function calculateCustomParams(array &$result): void {
|
||||
$this->applyDeviceParams($result);
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['created'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Devices;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getDevicesIdsByIpId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.device AS itemid
|
||||
FROM event
|
||||
WHERE
|
||||
event.ip = :ip_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getDevicesIdsByUserId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_device.id AS itemid
|
||||
FROM event_device
|
||||
WHERE
|
||||
event_device.account_id = :account_id AND
|
||||
event_device.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getDevicesIdsByResourceId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.device AS itemid
|
||||
FROM event
|
||||
WHERE
|
||||
event.url = :resource_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Devices;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_device.created DESC';
|
||||
protected $dateRangeField = 'event_device.lastseen';
|
||||
|
||||
protected $allowedColumns = ['created', 'device', 'os_name', 'browser_name', 'lang', 'modified', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_device.id,
|
||||
event_device.lang,
|
||||
event_device.created,
|
||||
event_ua_parsed.device,
|
||||
event_ua_parsed.browser_name,
|
||||
event_ua_parsed.browser_version,
|
||||
event_ua_parsed.os_name,
|
||||
event_ua_parsed.os_version,
|
||||
event_ua_parsed.ua,
|
||||
event_ua_parsed.modified
|
||||
FROM
|
||||
event_device
|
||||
LEFT JOIN event_ua_parsed
|
||||
ON (event_device.user_agent = event_ua_parsed.id)
|
||||
|
||||
WHERE
|
||||
event_device.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(DISTINCT event_device.id)
|
||||
|
||||
FROM
|
||||
event_device
|
||||
|
||||
WHERE
|
||||
event_device.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
//$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_device.id', $queryParams);
|
||||
|
||||
//Add ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Domains;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getDomainsBySameIpDomainId(int $domainId): array {
|
||||
$params = [':domain_id' => $domainId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getDomainsIdsBySameIpDomainId(), $params);
|
||||
}
|
||||
|
||||
public function getAllDomains(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Domains;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getDomainsIdsBySameIpDomainId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_domain.id AS itemid
|
||||
FROM event_domain
|
||||
WHERE
|
||||
event_domain.key = :api_key
|
||||
AND event_domain.ip = (
|
||||
SELECT
|
||||
ip
|
||||
FROM event_domain
|
||||
WHERE
|
||||
event_domain.key = :api_key
|
||||
AND event_domain.id = :domain_id
|
||||
LIMIT 1
|
||||
)
|
||||
AND event_domain.id != :domain_id'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Domains;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_domain.id DESC';
|
||||
protected $dateRangeField = 'event_domain.lastseen';
|
||||
|
||||
protected $allowedColumns = ['domain', 'free_email_provider', 'tranco_rank',
|
||||
'disabled', 'disposable_domains', 'creation_date', 'total_account', 'fraud', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_domain.id,
|
||||
event_domain.domain,
|
||||
event_domain.ip,
|
||||
event_domain.total_account,
|
||||
event_domain.total_visit,
|
||||
event_domain.disposable_domains,
|
||||
event_domain.creation_date,
|
||||
event_domain.disabled,
|
||||
event_domain.free_email_provider,
|
||||
event_domain.tranco_rank,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM event_email
|
||||
WHERE
|
||||
event_email.domain = event_domain.id AND
|
||||
event_email.key = :api_key AND
|
||||
event_email.fraud_detected IS TRUE
|
||||
) AS fraud
|
||||
|
||||
FROM
|
||||
event_domain
|
||||
|
||||
WHERE
|
||||
event_domain.key = :api_key
|
||||
%s
|
||||
|
||||
GROUP BY
|
||||
event_domain.id'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT (event_domain.id)
|
||||
|
||||
FROM
|
||||
event_domain
|
||||
|
||||
WHERE
|
||||
event_domain.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_domain.id', $queryParams);
|
||||
|
||||
if (isset($search) && $search['value'] !== null) {
|
||||
$searchConditions .= (
|
||||
' AND (
|
||||
LOWER(event_domain.domain) LIKE LOWER(:search_value)
|
||||
OR TEXT(event_domain.creation_date) LIKE LOWER(:search_value)
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Emails;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
use \Traits\Enrichment\Emails;
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getEmailsByUserId(int $userId): array {
|
||||
$params = [':account_id' => $userId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getEmailsIdsByUserId(), $params);
|
||||
}
|
||||
|
||||
protected function calculateCustomParams(array &$result): void {
|
||||
$this->calculateEmailReputation($result);
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['lastseen'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Emails;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getEmailsIdsByUserId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_email.id AS itemid
|
||||
FROM event_email
|
||||
WHERE
|
||||
event_email.key = :api_key AND
|
||||
event_email.account_id = :account_id'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Emails;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_email.lastseen DESC';
|
||||
protected $dateRangeField = 'event_email.lastseen';
|
||||
|
||||
protected $allowedColumns = ['email', 'reputation', 'free_email_provider', 'data_breach',
|
||||
'data_breaches', 'disposable_domains', 'blockemails', 'fraud_detected'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_email.id,
|
||||
event_email.email,
|
||||
event_email.data_breach,
|
||||
event_email.data_breaches,
|
||||
event_email.fraud_detected,
|
||||
-- event_email.profiles,
|
||||
event_email.blockemails,
|
||||
event_email.lastseen,
|
||||
event_email.alert_list,
|
||||
|
||||
event_domain.domain,
|
||||
event_domain.id AS domain_id,
|
||||
event_domain.free_email_provider,
|
||||
event_domain.disposable_domains
|
||||
|
||||
FROM
|
||||
event_email
|
||||
|
||||
LEFT JOIN event_domain
|
||||
ON (event_email.domain = event_domain.id)
|
||||
|
||||
WHERE
|
||||
event_email.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(*)
|
||||
|
||||
FROM
|
||||
event_email
|
||||
|
||||
WHERE
|
||||
event_email.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_email.id', $queryParams);
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
event_email.email LIKE :search_value
|
||||
OR TEXT(event_email.lastseen) LIKE :search_value
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Events;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
use \Traits\Enrichment\Ips;
|
||||
use \Traits\Enrichment\Devices;
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getEventsByUserId(int $userId): array {
|
||||
$ids = ['userId' => $userId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getEventsByIspId(int $ispId): array {
|
||||
$ids = ['ispId' => $ispId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getEventsByDomainId(int $domainId): array {
|
||||
$ids = ['domainId' => $domainId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getEventsByDeviceId(int $deviceId): array {
|
||||
$ids = ['deviceId' => $deviceId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getEventsByResourceId(int $resourceId): array {
|
||||
$ids = ['resourceId' => $resourceId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getEventsByCountryId(int $countryId): array {
|
||||
$ids = ['countryId' => $countryId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getEventsByIpId(int $ipId): array {
|
||||
$ids = ['ipId' => $ipId];
|
||||
|
||||
return $this->getGrid(null, $ids);
|
||||
}
|
||||
|
||||
public function getAllEvents() {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
protected function calculateCustomParams(array &$result): void {
|
||||
$this->calculateIpType($result);
|
||||
$this->applyDeviceParams($result);
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['time', 'lastseen', 'session_max_t', 'session_min_t', 'score_updated_at'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Events;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Events;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event.time DESC, event.id DESC';
|
||||
protected $dateRangeField = 'event.time';
|
||||
|
||||
protected $allowedColumns = ['userid', 'time', 'type', 'ip', 'ip_type', 'device', 'session_id', 'time', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event.id,
|
||||
event.time,
|
||||
|
||||
event_type.value AS event_type,
|
||||
event_type.name AS event_type_name,
|
||||
|
||||
event_account.is_important,
|
||||
event_account.id AS accountid,
|
||||
event_account.userid AS accounttitle,
|
||||
event_account.score_updated_at,
|
||||
event_account.score,
|
||||
event_account.fraud,
|
||||
|
||||
event_url.url,
|
||||
event_url.id as url_id,
|
||||
event_url_query.query,
|
||||
event_url.title,
|
||||
|
||||
event_ip.ip,
|
||||
event_ip.data_center,
|
||||
event_ip.vpn,
|
||||
event_ip.tor,
|
||||
event_ip.relay,
|
||||
event_ip.starlink,
|
||||
event_ip.blocklist,
|
||||
event_ip.fraud_detected,
|
||||
event_ip.checked,
|
||||
|
||||
event_isp.name AS isp_name,
|
||||
|
||||
countries.iso AS country_iso,
|
||||
countries.id AS country_id,
|
||||
countries.value AS full_country,
|
||||
|
||||
event_ua_parsed.ua,
|
||||
event_ua_parsed.device,
|
||||
event_ua_parsed.os_name,
|
||||
|
||||
event_email.email,
|
||||
event.http_code,
|
||||
event.session_id,
|
||||
event_session.total_visit AS session_cnt,
|
||||
event_session.lastseen AS session_max_t,
|
||||
event_session.created AS session_min_t,
|
||||
event_session.lastseen - event_session.created AS session_duration
|
||||
|
||||
FROM
|
||||
event
|
||||
|
||||
INNER JOIN event_account
|
||||
ON (event.account = event_account.id)
|
||||
|
||||
INNER JOIN event_url
|
||||
ON (event.url = event_url.id)
|
||||
|
||||
FULL OUTER JOIN event_url_query
|
||||
ON (event.query = event_url_query.id)
|
||||
|
||||
LEFT JOIN event_device
|
||||
ON (event.device = event_device.id)
|
||||
|
||||
LEFT JOIN event_type
|
||||
ON (event.type = event_type.id)
|
||||
|
||||
LEFT JOIN event_ua_parsed
|
||||
ON (event_device.user_agent = event_ua_parsed.id)
|
||||
|
||||
LEFT JOIN event_ip
|
||||
ON (event.ip = event_ip.id)
|
||||
|
||||
LEFT JOIN event_isp
|
||||
ON (event_ip.isp = event_isp.id)
|
||||
|
||||
INNER JOIN countries
|
||||
ON (event_ip.country = countries.id)
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON (event.email = event_email.id)
|
||||
|
||||
LEFT JOIN event_session
|
||||
ON (event.time = event_session.lastseen AND event.session_id = event_session.id)
|
||||
|
||||
WHERE
|
||||
event.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyEventTypes($query, $queryParams);
|
||||
$this->applyDeviceTypes($query, $queryParams);
|
||||
$this->applyRules($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$query = null;
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
if ($this->itemId !== null) {
|
||||
switch ($this->itemKey) {
|
||||
case 'userId':
|
||||
$query = 'SELECT total_visit AS count FROM event_account WHERE key = :api_key AND id = :item_id';
|
||||
break;
|
||||
case 'ispId':
|
||||
$query = 'SELECT total_visit AS count FROM event_isp WHERE key = :api_key AND id = :item_id';
|
||||
break;
|
||||
case 'domainId':
|
||||
$query = 'SELECT total_visit AS count FROM event_domain WHERE key = :api_key AND id = :item_id';
|
||||
break;
|
||||
case 'resourceId':
|
||||
$query = 'SELECT total_visit AS count FROM event_url WHERE key = :api_key AND id = :item_id';
|
||||
break;
|
||||
case 'countryId':
|
||||
$query = 'SELECT total_visit AS count FROM event_country WHERE key = :api_key AND country = :item_id';
|
||||
break;
|
||||
case 'ipId':
|
||||
$query = 'SELECT total_visit AS count FROM event_ip WHERE key = :api_key AND id = :item_id';
|
||||
break;
|
||||
case 'deviceId':
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(event.id) AS count
|
||||
FROM event
|
||||
INNER JOIN event_device
|
||||
ON (event.device = event_device.id)
|
||||
WHERE
|
||||
event_device.key = :api_key AND
|
||||
event_device.user_agent = :item_id'
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$query) {
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(event.id) AS count
|
||||
|
||||
FROM
|
||||
event
|
||||
|
||||
INNER JOIN event_account
|
||||
ON (event.account = event_account.id)
|
||||
|
||||
INNER JOIN event_url
|
||||
ON (event.url = event_url.id)
|
||||
|
||||
INNER JOIN event_ip
|
||||
ON (event.ip = event_ip.id)
|
||||
|
||||
INNER JOIN countries
|
||||
ON (event_ip.country = countries.id)
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON (event.email = event_email.id)
|
||||
|
||||
LEFT JOIN event_device
|
||||
ON (event.device = event_device.id)
|
||||
|
||||
LEFT JOIN event_type
|
||||
ON (event.type = event_type.id)
|
||||
|
||||
LEFT JOIN event_ua_parsed
|
||||
ON (event_device.user_agent = event_ua_parsed.id)
|
||||
|
||||
WHERE
|
||||
event.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyEventTypes($query, $queryParams);
|
||||
$this->applyDeviceTypes($query, $queryParams);
|
||||
$this->applyRules($query, $queryParams);
|
||||
}
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
//Add dates into request
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
//Apply itemId into request
|
||||
$this->applyRelatedToIdSearchConitions($query);
|
||||
|
||||
$searchConditions = '';
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
//TODO: user isIp function here
|
||||
if (filter_var($search['value'], FILTER_VALIDATE_IP) !== false) {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
event_ip.ip = :search_value
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = $search['value'];
|
||||
} else {
|
||||
// https://stackoverflow.com/a/63701098
|
||||
$searchConditions .= (
|
||||
" AND
|
||||
(
|
||||
LOWER(event_email.email) LIKE LOWER(:search_value) OR
|
||||
LOWER(event_account.userid) LIKE LOWER(:search_value) OR
|
||||
event.http_code::text LIKE LOWER(:search_value) OR
|
||||
|
||||
CASE WHEN event.http_code >= 400 THEN
|
||||
CONCAT('error ', event.http_code)
|
||||
ELSE
|
||||
'' END LIKE LOWER(:search_value) OR
|
||||
|
||||
TO_CHAR(event.time::timestamp without time zone, 'dd/mm/yyyy hh24:mi:ss') LIKE :search_value
|
||||
)"
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
|
||||
protected function getQueryParams(): array {
|
||||
$params = [':api_key' => $this->apiKey];
|
||||
if ($this->itemId !== null) {
|
||||
$params[':item_id'] = $this->itemId;
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
private function applyRelatedToIdSearchConitions(string &$query): void {
|
||||
$searchConditions = null;
|
||||
|
||||
if ($this->itemId !== null) {
|
||||
switch ($this->itemKey) {
|
||||
case 'userId':
|
||||
$searchConditions = ' AND event.account = :item_id %s';
|
||||
break;
|
||||
case 'ispId':
|
||||
$searchConditions = ' AND event_isp.id = :item_id %s';
|
||||
break;
|
||||
case 'domainId':
|
||||
$searchConditions = ' AND event_email.domain = :item_id %s';
|
||||
break;
|
||||
case 'resourceId':
|
||||
$searchConditions = ' AND event.url = :item_id %s';
|
||||
break;
|
||||
case 'countryId':
|
||||
$searchConditions = ' AND countries.id = :item_id %s';
|
||||
break;
|
||||
case 'ipId':
|
||||
$searchConditions = ' AND event_ip.id = :item_id %s';
|
||||
break;
|
||||
case 'deviceId':
|
||||
$searchConditions = ' AND event_ua_parsed.id = :item_id %s';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
if ($searchConditions !== null) {
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
|
||||
private function applyEventTypes(string &$query, array &$queryParams): void {
|
||||
$eventTypeIds = $this->f3->get('REQUEST.eventTypeIds');
|
||||
if ($eventTypeIds === null || !count($eventTypeIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clauses = [];
|
||||
foreach ($eventTypeIds as $key => $eventTypeId) {
|
||||
$clauses[] = 'event.type = :event_type_id_' . $key;
|
||||
$queryParams[':event_type_id_' . $key] = $eventTypeId;
|
||||
}
|
||||
|
||||
$query .= ' AND (' . implode(' OR ', $clauses) . ')';
|
||||
}
|
||||
|
||||
private function applyDeviceTypes(string &$query, array &$queryParams): void {
|
||||
$deviceTypes = $this->f3->get('REQUEST.deviceTypes');
|
||||
if ($deviceTypes === null || !count($deviceTypes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clauses = [];
|
||||
foreach ($deviceTypes as $key => $deviceType) {
|
||||
if ($deviceType === 'other') {
|
||||
$placeholders = [];
|
||||
|
||||
foreach (\Utils\Constants::get('DEVICE_TYPES') as $device) {
|
||||
if ($device !== 'unknown' && $device !== 'other') {
|
||||
$param = ':device_exclude_' . $device;
|
||||
$placeholders[] = $param;
|
||||
$queryParams[$param] = $device;
|
||||
}
|
||||
}
|
||||
|
||||
$params = implode(', ', $placeholders);
|
||||
|
||||
$clauses[] = '(event_ua_parsed.device NOT IN (' . $params . ') AND event_ua_parsed.device IS NOT NULL)';
|
||||
} elseif ($deviceType === 'unknown') {
|
||||
$clauses[] = 'event_ua_parsed.device IS NULL';
|
||||
} else {
|
||||
$param = ':device_' . $key;
|
||||
$clauses[] = 'event_ua_parsed.device = ' . $param;
|
||||
$queryParams[$param] = $deviceType;
|
||||
}
|
||||
}
|
||||
|
||||
$query .= ' AND (' . implode(' OR ', $clauses) . ')';
|
||||
}
|
||||
|
||||
private function applyRules(string &$query, array &$queryParams): void {
|
||||
$ruleUids = $this->f3->get('REQUEST.ruleUids');
|
||||
if ($ruleUids === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uids = [];
|
||||
foreach ($ruleUids as $ruleUid) {
|
||||
$uids[] = ['uid' => $ruleUid];
|
||||
}
|
||||
|
||||
$query .= ' AND score_details @> :rules_uids::jsonb';
|
||||
$queryParams[':rules_uids'] = json_encode($uids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Ips;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
use \Traits\Enrichment\Ips;
|
||||
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getIpsByUserId(int $userId): array {
|
||||
$params = [':account_id' => $userId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIpsIdsByUserId(), $params);
|
||||
}
|
||||
|
||||
public function getIpsByIspId(int $ispId): array {
|
||||
$params = [':isp_id' => $ispId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIpsIdsByIspId(), $params);
|
||||
}
|
||||
|
||||
public function getIpsByDomainId($domainId) {
|
||||
$params = [':domain_id' => $domainId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIpsIdsByDomainId(), $params);
|
||||
}
|
||||
|
||||
public function getIpsByCountryId(int $countryId): array {
|
||||
$params = [':country_id' => $countryId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIpsIdsByCountryId(), $params);
|
||||
}
|
||||
|
||||
public function getIpsByDeviceId(int $deviceId): array {
|
||||
$params = [':device_id' => $deviceId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIpsIdsByDeviceId(), $params);
|
||||
}
|
||||
|
||||
public function getIpsByResourceId(int $resourceId): array {
|
||||
$params = [':resource_id' => $resourceId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIpsIdsByResourceId(), $params);
|
||||
}
|
||||
|
||||
public function getAllIps() {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
protected function calculateCustomParams(array &$result): void {
|
||||
$this->calculateIpType($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Ips;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getIpsIdsByUserId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.ip AS itemid
|
||||
FROM event
|
||||
WHERE
|
||||
event.key = :api_key
|
||||
AND event.account = :account_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIpsIdsByIspId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_ip.id AS itemid
|
||||
FROM event_ip
|
||||
WHERE
|
||||
event_ip.key = :api_key
|
||||
AND event_ip.isp = :isp_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIpsIdsByDomainId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.ip AS itemid
|
||||
FROM event
|
||||
LEFT JOIN event_email
|
||||
ON (event.email = event_email.id)
|
||||
WHERE
|
||||
event_email.key = :api_key
|
||||
AND event_email.domain = :domain_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIpsIdsByCountryId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_ip.id AS itemid
|
||||
FROM event_ip
|
||||
WHERE
|
||||
event_ip.key = :api_key AND
|
||||
event_ip.country = :country_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIpsIdsByDeviceId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.ip AS itemid
|
||||
FROM event
|
||||
INNER JOIN event_device
|
||||
ON (event.device = event_device.id)
|
||||
WHERE
|
||||
event_device.user_agent = :device_id AND
|
||||
event_device.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIpsIdsByResourceId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.ip AS itemid
|
||||
FROM event
|
||||
WHERE
|
||||
event.url = :resource_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Ips;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_ip.lastseen DESC';
|
||||
protected $dateRangeField = 'event_ip.lastseen';
|
||||
|
||||
protected $allowedColumns = ['ip', 'full_country', 'asn', 'netname', 'ip_type', 'total_visit', 'total_account', 'lastseen', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_ip.id,
|
||||
event_ip.ip,
|
||||
event_ip.fraud_detected,
|
||||
event_ip.alert_list,
|
||||
event_ip.data_center,
|
||||
event_ip.vpn,
|
||||
event_ip.tor,
|
||||
event_ip.relay,
|
||||
event_ip.blocklist,
|
||||
event_ip.starlink,
|
||||
event_ip.shared AS total_account,
|
||||
event_ip.total_visit,
|
||||
event_ip.checked,
|
||||
|
||||
event_ip.lastseen AS lastseen,
|
||||
|
||||
event_isp.name AS netname,
|
||||
event_isp.description,
|
||||
event_isp.asn,
|
||||
|
||||
countries.id AS country_id,
|
||||
countries.iso AS country_iso,
|
||||
countries.value AS full_country
|
||||
|
||||
FROM
|
||||
event_ip
|
||||
|
||||
LEFT JOIN countries
|
||||
ON (event_ip.country = countries.id)
|
||||
|
||||
LEFT JOIN event_isp
|
||||
ON (event_ip.isp = event_isp.id)
|
||||
|
||||
WHERE
|
||||
event_ip.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyIpTypes($query);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT (DISTINCT event_ip.ip)
|
||||
|
||||
FROM
|
||||
event_ip
|
||||
|
||||
LEFT JOIN countries
|
||||
ON (event_ip.country = countries.id)
|
||||
|
||||
LEFT JOIN event_isp
|
||||
ON (event_ip.isp = event_isp.id)
|
||||
|
||||
WHERE
|
||||
event_ip.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyIpTypes($query);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_ip.id', $queryParams);
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
TEXT(event_ip.ip) LIKE LOWER(:search_value)
|
||||
OR LOWER(event_isp.asn::text) LIKE LOWER(:search_value)
|
||||
OR LOWER(event_isp.name) LIKE LOWER(:search_value)
|
||||
OR LOWER(countries.value) LIKE LOWER(:search_value)
|
||||
OR LOWER(countries.iso) LIKE LOWER(:search_value)
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
|
||||
private function applyIpTypes(string &$query): void {
|
||||
$ipTypeIds = $this->f3->get('REQUEST.ipTypeIds');
|
||||
if ($ipTypeIds === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($ipTypeIds as $ipTypeId) {
|
||||
switch ($ipTypeId) {
|
||||
case 0:
|
||||
$query .= ' AND fraud_detected IS TRUE ';
|
||||
break;
|
||||
case 1:
|
||||
$query .= ' AND blocklist IS TRUE ';
|
||||
break;
|
||||
case 2:
|
||||
$query .= ' AND countries.id = 0 AND event_ip.checked IS TRUE ';
|
||||
break;
|
||||
case 3:
|
||||
$query .= ' AND tor IS TRUE ';
|
||||
break;
|
||||
case 4:
|
||||
$query .= ' AND starlink IS TRUE ';
|
||||
break;
|
||||
case 5:
|
||||
$query .= ' AND relay IS TRUE ';
|
||||
break;
|
||||
case 6:
|
||||
$query .= ' AND vpn IS TRUE ';
|
||||
break;
|
||||
case 7:
|
||||
$query .= ' AND data_center IS TRUE ';
|
||||
break;
|
||||
case 8:
|
||||
$query .= ' AND (event_ip.checked IS FALSE OR event_ip.checked IS NULL) ';
|
||||
break;
|
||||
case 9:
|
||||
$query .= ' AND (tor IS FALSE AND vpn IS FALSE AND relay IS FALSE AND data_center IS FALSE AND event_ip.checked IS TRUE) ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Isps;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getIspsByUserId(int $userId): array {
|
||||
$params = [':account_id' => $userId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIspsIdsByUserId(), $params);
|
||||
}
|
||||
|
||||
public function getIspsByDomainId(int $domainId): array {
|
||||
$params = [':domain_id' => $domainId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIspsIdsByDomainId(), $params);
|
||||
}
|
||||
|
||||
public function getIspsByCountryId(int $countryId): array {
|
||||
$params = [':country_id' => $countryId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIspsIdsByCountryId(), $params);
|
||||
}
|
||||
|
||||
public function getIspsByResourceId(int $resourceId): array {
|
||||
$params = [':resource_id' => $resourceId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getIspsIdsByResourceId(), $params);
|
||||
}
|
||||
|
||||
public function getAllIsps(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Isps;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getIspsIdsByUserId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_ip.isp AS itemid
|
||||
FROM event_ip
|
||||
INNER JOIN event
|
||||
ON (event_ip.id = event.ip)
|
||||
WHERE
|
||||
event_ip.key = :api_key AND
|
||||
event.account = :account_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIspsIdsByDomainId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_ip.isp AS itemid
|
||||
FROM event
|
||||
INNER JOIN event_ip
|
||||
ON (event.ip = event_ip.id)
|
||||
LEFT JOIN event_email
|
||||
ON (event.email = event_email.id)
|
||||
WHERE
|
||||
event_email.key = :api_key AND
|
||||
event_email.domain = :domain_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIspsIdsByCountryId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_ip.isp AS itemid
|
||||
FROM event_ip
|
||||
WHERE
|
||||
event_ip.key = :api_key AND
|
||||
event_ip.country = :country_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function getIspsIdsByResourceId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_ip.isp AS itemid
|
||||
FROM event
|
||||
INNER JOIN event_ip
|
||||
ON (event.ip = event_ip.id)
|
||||
WHERE
|
||||
event.url = :resource_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Isps;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_isp.id DESC';
|
||||
protected $dateRangeField = 'event_isp.lastseen';
|
||||
|
||||
protected $allowedColumns = ['asn', 'name', 'total_visit', 'total_ip', 'total_account', 'fraud', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_isp.id,
|
||||
event_isp.asn,
|
||||
event_isp.name,
|
||||
-- event_isp.description,
|
||||
event_isp.total_visit,
|
||||
event_isp.total_account,
|
||||
(
|
||||
SELECT COUNT(DISTINCT event.account)
|
||||
FROM event
|
||||
LEFT JOIN event_ip ON event.ip = event_ip.id
|
||||
LEFT JOIN event_account ON event.account = event_account.id
|
||||
WHERE
|
||||
event_ip.isp = event_isp.id AND
|
||||
event.key = :api_key AND
|
||||
event_account.fraud IS TRUE
|
||||
) AS fraud,
|
||||
(
|
||||
SELECT
|
||||
COUNT ( DISTINCT eip.ip )
|
||||
|
||||
FROM
|
||||
event_ip AS eip
|
||||
|
||||
WHERE
|
||||
eip.isp = event_isp.id
|
||||
AND eip.key = event_isp.key
|
||||
AND eip.isp IS NOT NULL
|
||||
|
||||
) AS total_ip
|
||||
FROM
|
||||
event_isp
|
||||
|
||||
WHERE
|
||||
event_isp.key = :api_key
|
||||
%s
|
||||
|
||||
GROUP BY
|
||||
event_isp.id'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT (event_isp.id)
|
||||
|
||||
FROM
|
||||
event_isp
|
||||
|
||||
WHERE
|
||||
event_isp.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_isp.id', $queryParams);
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
LOWER(event_isp.asn::text) LIKE LOWER(:search_value)
|
||||
OR LOWER(event_isp.name) LIKE LOWER(:search_value)
|
||||
OR LOWER(event_isp.description) LIKE LOWER(:search_value)
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Logbook;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getAllLogbookEvents() {
|
||||
return $this->getGrid();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Logbook;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Logbook;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_logbook.error_type DESC, event_logbook.id DESC';
|
||||
protected $dateRangeField = 'event_logbook.started';
|
||||
|
||||
protected $allowedColumns = ['ip', 'started', 'error_type', 'error_text'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_logbook.id,
|
||||
event_logbook.ip,
|
||||
event_logbook.error_type,
|
||||
event_logbook.error_text,
|
||||
event_logbook.raw,
|
||||
event_logbook.started,
|
||||
event_error_type.name AS error_name,
|
||||
event_error_type.value AS error_value
|
||||
|
||||
FROM
|
||||
event_logbook
|
||||
|
||||
LEFT JOIN event_error_type
|
||||
ON (event_logbook.error_type = event_error_type.id)
|
||||
|
||||
WHERE
|
||||
event_logbook.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(event_logbook.id) AS count
|
||||
|
||||
FROM
|
||||
event_logbook
|
||||
|
||||
LEFT JOIN event_error_type
|
||||
ON (event_logbook.error_type = event_error_type.id)
|
||||
|
||||
WHERE
|
||||
event_logbook.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
//Add dates into request
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = '';
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$extra = '';
|
||||
//TODO: use isIp function here
|
||||
if (filter_var($search['value'], FILTER_VALIDATE_IP) !== false) {
|
||||
$extra = ' event_logbook.ip = :search_ip_value OR ';
|
||||
$queryParams[':search_ip_value'] = $search['value'];
|
||||
}
|
||||
|
||||
$searchConditions .= (
|
||||
" AND
|
||||
(
|
||||
$extra
|
||||
LOWER(event_logbook.raw::text) LIKE LOWER(:search_value) OR
|
||||
LOWER(event_logbook.error_text) LIKE LOWER(:search_value) OR
|
||||
LOWER(event_error_type.name) LIKE LOWER(:search_value)
|
||||
)"
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Payloads\FieldAuditTrail;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getDataByUserId(int $userId): array {
|
||||
$params = [':account_id' => $userId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getDataIdsByUserId(), $params);
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['created'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Payloads\FieldAuditTrail;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getDataIdsByUserId(): string {
|
||||
return (
|
||||
'SELECT
|
||||
event_field_audit_trail.id AS itemid
|
||||
FROM event_field_audit_trail
|
||||
WHERE
|
||||
event_field_audit_trail.key = :api_key AND
|
||||
event_field_audit_trail.account_id = :account_id'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Payloads\FieldAuditTrail;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_field_audit_trail.id DESC';
|
||||
protected $dateRangeField = 'event_field_audit_trail.created';
|
||||
|
||||
protected $allowedColumns = ['id', 'created'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_field_audit_trail.id,
|
||||
event_field_audit_trail.created,
|
||||
event_field_audit_trail.event_id,
|
||||
event_field_audit_trail.field_id,
|
||||
event_field_audit_trail.field_name,
|
||||
event_field_audit_trail.old_value,
|
||||
event_field_audit_trail.new_value,
|
||||
event_field_audit_trail.parent_id,
|
||||
event_field_audit_trail.parent_name
|
||||
|
||||
FROM
|
||||
event_field_audit_trail
|
||||
|
||||
WHERE
|
||||
event_field_audit_trail.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(*)
|
||||
|
||||
FROM
|
||||
event_field_audit_trail
|
||||
|
||||
WHERE
|
||||
event_field_audit_trail.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$searchConditions = $this->injectIdQuery('event_field_audit_trail.id', $queryParams);
|
||||
|
||||
//Add ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Phones;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getPhonesByUserId(int $userId): array {
|
||||
$params = [':account_id' => $userId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getPhonesIdsByUserId(), $params);
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['lastseen'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Phones;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getPhonesIdsByUserId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_phone.id AS itemid
|
||||
FROM event_phone
|
||||
WHERE
|
||||
event_phone.key = :api_key AND
|
||||
event_phone.account_id = :account_id'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Phones;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_phone.lastseen DESC';
|
||||
protected $dateRangeField = 'event_phone.lastseen';
|
||||
|
||||
protected $allowedColumns = ['phonenumber', 'invalid', 'full_country', 'carrier_name', 'type', 'shared', 'fraud_detected'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_phone.id,
|
||||
event_phone.phone_number as phonenumber,
|
||||
event_phone.type,
|
||||
event_phone.carrier_name,
|
||||
event_phone.lastseen,
|
||||
event_phone.invalid,
|
||||
event_phone.shared,
|
||||
event_phone.alert_list,
|
||||
event_phone.fraud_detected,
|
||||
|
||||
countries.id AS country_id,
|
||||
countries.iso AS country_iso,
|
||||
countries.value AS full_country
|
||||
|
||||
FROM
|
||||
event_phone
|
||||
|
||||
LEFT JOIN countries
|
||||
ON (event_phone.country_code = countries.id)
|
||||
|
||||
WHERE
|
||||
event_phone.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(*)
|
||||
|
||||
FROM
|
||||
event_phone
|
||||
|
||||
WHERE
|
||||
event_phone.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_phone.id', $queryParams);
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
event_phone.phone_number LIKE :search_value
|
||||
OR TEXT(event_phone.lastseen) LIKE :search_value
|
||||
)'
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Resources;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getAllResources(): array {
|
||||
$data = $this->getGrid();
|
||||
if (isset($data['data'])) {
|
||||
$data['data'] = $this->extendWithSuspiciousUrl($data['data']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function extendWithSuspiciousUrl(array $result): array {
|
||||
if (is_array($result) && count($result)) {
|
||||
$suspiciousUrlWords = \Utils\WordsLists\Url::getWords();
|
||||
foreach ($result as &$record) {
|
||||
$record['suspicious'] = $this->isUrlSuspicious($suspiciousUrlWords, $record['url']);
|
||||
}
|
||||
unset($record);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function isUrlSuspicious(array $substrings, string $url): bool {
|
||||
foreach ($substrings as $sub) {
|
||||
if (stripos($url, $sub) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Resources;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Resources;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_url.id DESC';
|
||||
protected $dateRangeField = 'event_url.lastseen';
|
||||
|
||||
protected $allowedColumns = ['title', 'http_code', 'total_account', 'total_country', 'total_ip', 'total_visit', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_url.id,
|
||||
event_url.id AS url_id,
|
||||
event_url.key,
|
||||
event_url.url,
|
||||
event_url.title,
|
||||
event_url.http_code,
|
||||
|
||||
event_url.total_visit,
|
||||
event_url.total_ip,
|
||||
event_url.total_account,
|
||||
event_url.total_country
|
||||
|
||||
FROM
|
||||
event_url
|
||||
|
||||
WHERE
|
||||
event_url.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(event_url.id)
|
||||
|
||||
FROM
|
||||
event_url
|
||||
|
||||
WHERE
|
||||
event_url.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_url.id', $queryParams);
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
' AND
|
||||
(
|
||||
LOWER(event_url.title) LIKE LOWER(:search_value)
|
||||
OR LOWER(event_url.url) LIKE LOWER(:search_value)
|
||||
)'
|
||||
);
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\ReviewQueue;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getAllUnderReviewUsers(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
public function getTotalUnderReviewUsers(): int {
|
||||
return $this->getTotal();
|
||||
}
|
||||
|
||||
public function getTotalUnderReviewUsersOverall(): int {
|
||||
[$query, $params] = $this->query->getTotalOverall();
|
||||
$results = $this->execQuery($query, $params);
|
||||
|
||||
return $results[0]['count'];
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['lastseen', 'created', 'score_updated_at', 'added_to_review'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\ReviewQueue;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\ReviewQueue;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = null;
|
||||
protected $dateRangeField = 'event_account.added_to_review';
|
||||
|
||||
protected $allowedColumns = ['score', 'lastseen', 'firstname', 'lastname', 'created', 'added_to_review'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
event_account.id AS accountid,
|
||||
event_account.userid AS accounttitle,
|
||||
event_account.created AS created,
|
||||
event_account.is_important,
|
||||
event_account.score_updated_at,
|
||||
event_account.score,
|
||||
event_account.firstname,
|
||||
event_account.lastname,
|
||||
event_account.lastseen,
|
||||
event_account.added_to_review,
|
||||
|
||||
event_email.email
|
||||
|
||||
FROM
|
||||
event_account
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON (event_account.lastemail = event_email.id)
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key AND
|
||||
event_account.fraud IS NULL AND
|
||||
event_account.added_to_review IS NOT NULL
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyRules($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT (event_account.id)
|
||||
|
||||
FROM
|
||||
event_account
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON (event_account.lastemail = event_email.id)
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key AND
|
||||
event_account.fraud IS NULL AND
|
||||
event_account.added_to_review IS NOT NULL
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyRules($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotalOverall(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT(event_account.id) AS count
|
||||
|
||||
FROM
|
||||
event_account
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key AND
|
||||
event_account.fraud IS NULL AND
|
||||
event_account.added_to_review IS NOT NULL'
|
||||
);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$searchConditions = '';
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
" AND
|
||||
(
|
||||
LOWER(REPLACE(
|
||||
COALESCE(event_account.firstname, '') ||
|
||||
COALESCE(event_account.lastname, '') ||
|
||||
COALESCE(event_account.firstname, ''),
|
||||
' ', '')) LIKE LOWER(REPLACE(:search_value, ' ', '')) OR
|
||||
LOWER(event_email.email) LIKE LOWER(:search_value) OR
|
||||
LOWER(event_account.userid) LIKE LOWER(:search_value) OR
|
||||
|
||||
TO_CHAR(event_account.lastseen::timestamp without time zone, 'dd/mm/yyyy hh24:mi:ss') LIKE :search_value OR
|
||||
TO_CHAR(event_account.created::timestamp without time zone, 'dd/mm/yyyy hh24:mi:ss') LIKE :search_value
|
||||
)"
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
|
||||
private function applyRules(string &$query, array &$queryParams): void {
|
||||
$ruleUids = $this->f3->get('REQUEST.ruleUids');
|
||||
if ($ruleUids === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uids = [];
|
||||
foreach ($ruleUids as $ruleUid) {
|
||||
$uids[] = ['uid' => $ruleUid];
|
||||
}
|
||||
|
||||
$query .= ' AND score_details @> :rules_uids::jsonb';
|
||||
$queryParams[':rules_uids'] = json_encode($uids);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Users;
|
||||
|
||||
class Grid extends \Models\Grid\Base\Grid {
|
||||
public function __construct(int $apiKey) {
|
||||
parent::__construct();
|
||||
|
||||
$this->apiKey = $apiKey;
|
||||
$this->idsModel = new Ids($apiKey);
|
||||
$this->query = new Query($apiKey);
|
||||
}
|
||||
|
||||
public function getUsersByIpId(int $ipId): array {
|
||||
$params = [':ip_id' => $ipId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getUsersIdsByIpId(), $params);
|
||||
}
|
||||
|
||||
public function getUsersByIspId(int $ispId): array {
|
||||
$params = [':isp_id' => $ispId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getUsersIdsByIspId(), $params);
|
||||
}
|
||||
|
||||
public function getUsersByDomainId(int $domainId): array {
|
||||
$params = [':domain_id' => $domainId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getUsersIdsByDomainId(), $params);
|
||||
}
|
||||
|
||||
public function getUsersByCountryId(int $countryId): array {
|
||||
$params = [':country_id' => $countryId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getUsersIdsByCountryId(), $params);
|
||||
}
|
||||
|
||||
public function getUsersByDeviceId(int $deviceId): array {
|
||||
$params = [':device_id' => $deviceId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getUsersIdsByDeviceId(), $params);
|
||||
}
|
||||
|
||||
public function getUsersByResourceId(int $resourceId): array {
|
||||
$params = [':resource_id' => $resourceId];
|
||||
|
||||
return $this->getGrid($this->idsModel->getUsersIdsByResourceId(), $params);
|
||||
}
|
||||
|
||||
public function getAllUsers(): array {
|
||||
return $this->getGrid();
|
||||
}
|
||||
|
||||
protected function convertTimeToUserTimezone(array &$result): void {
|
||||
$fields = ['time', 'lastseen', 'latest_decision', 'created', 'score_updated_at'];
|
||||
|
||||
$this->translateTimeZones($result, $fields);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Users;
|
||||
|
||||
class Ids extends \Models\Grid\Base\Ids {
|
||||
public function getUsersIdsByIpId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.account AS itemid
|
||||
FROM event
|
||||
WHERE
|
||||
event.ip = :ip_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getUsersIdsByIspId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.account AS itemid
|
||||
FROM event_ip
|
||||
INNER JOIN event
|
||||
ON (event_ip.id = event.ip)
|
||||
WHERE
|
||||
event_ip.isp = :isp_id AND
|
||||
event_ip.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getUsersIdsByDomainId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event_email.account_id AS itemid
|
||||
FROM event_domain
|
||||
INNER JOIN event_email
|
||||
ON event_domain.id = event_email.domain
|
||||
WHERE
|
||||
event_domain.id = :domain_id AND
|
||||
event_domain.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getUsersIdsByCountryId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.account AS itemid
|
||||
FROM event_ip
|
||||
INNER JOIN event
|
||||
ON (event_ip.id = event.ip)
|
||||
WHERE
|
||||
event_ip.country = :country_id AND
|
||||
event_ip.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getUsersIdsByDeviceId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.account AS itemid
|
||||
FROM event
|
||||
INNER JOIN event_device
|
||||
ON (event_device.id = event.device)
|
||||
WHERE
|
||||
event_device.user_agent = :device_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
|
||||
public function getUsersIdsByResourceId(): string {
|
||||
return (
|
||||
'SELECT DISTINCT
|
||||
event.account AS itemid
|
||||
FROM event
|
||||
WHERE
|
||||
event.url = :resource_id AND
|
||||
event.key = :api_key'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Tirreno ~ Open source user analytics
|
||||
* Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
*
|
||||
* Licensed under GNU Affero General Public License version 3 of the or any later version.
|
||||
* For full copyright and license information, please see the LICENSE
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
|
||||
* @license https://opensource.org/licenses/AGPL-3.0 AGPL License
|
||||
* @link https://www.tirreno.com Tirreno(tm)
|
||||
*/
|
||||
|
||||
namespace Models\Grid\Users;
|
||||
|
||||
class Query extends \Models\Grid\Base\Query {
|
||||
protected $defaultOrder = 'event_account.id DESC';
|
||||
protected $dateRangeField = 'event_account.lastseen';
|
||||
|
||||
protected $allowedColumns = ['score', 'accounttitle', 'firstname', 'lastname', 'created', 'lastseen', 'fraud', 'id'];
|
||||
|
||||
public function getData(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
"SELECT
|
||||
TEXT(date_trunc('day', event_account.created)::date) AS created_day,
|
||||
|
||||
event_account.id,
|
||||
event_account.is_important,
|
||||
event_account.id AS accountid,
|
||||
event_account.userid AS accounttitle,
|
||||
event_account.score,
|
||||
event_account.score_updated_at,
|
||||
event_account.created,
|
||||
event_account.fraud,
|
||||
event_account.reviewed,
|
||||
event_account.firstname,
|
||||
event_account.lastname,
|
||||
event_account.lastseen,
|
||||
event_account.total_visit,
|
||||
event_account.total_ip,
|
||||
event_account.total_device,
|
||||
event_account.total_country,
|
||||
event_account.latest_decision,
|
||||
event_account.added_to_review,
|
||||
|
||||
event_email.email,
|
||||
event_email.blockemails
|
||||
|
||||
FROM
|
||||
event_account
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON (event_account.lastemail = event_email.id)
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key
|
||||
%s"
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyRules($query, $queryParams);
|
||||
$this->applyScore($query, $queryParams);
|
||||
$this->applyOrder($query);
|
||||
$this->applyLimit($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
public function getTotal(): array {
|
||||
$queryParams = $this->getQueryParams();
|
||||
|
||||
$query = (
|
||||
'SELECT
|
||||
COUNT (event_account.id)
|
||||
|
||||
FROM
|
||||
event_account
|
||||
|
||||
LEFT JOIN event_email
|
||||
ON (event_account.lastemail = event_email.id)
|
||||
|
||||
WHERE
|
||||
event_account.key = :api_key
|
||||
%s'
|
||||
);
|
||||
|
||||
$this->applySearch($query, $queryParams);
|
||||
$this->applyRules($query, $queryParams);
|
||||
$this->applyScore($query, $queryParams);
|
||||
|
||||
return [$query, $queryParams];
|
||||
}
|
||||
|
||||
private function applySearch(string &$query, array &$queryParams): void {
|
||||
$this->applyDateRange($query, $queryParams);
|
||||
|
||||
$search = $this->f3->get('REQUEST.search');
|
||||
$searchConditions = $this->injectIdQuery('event_account.id', $queryParams);
|
||||
|
||||
if (is_array($search) && isset($search['value']) && is_string($search['value']) && $search['value'] !== '') {
|
||||
$searchConditions .= (
|
||||
" AND
|
||||
(
|
||||
LOWER(REPLACE(
|
||||
COALESCE(event_account.firstname, '') ||
|
||||
COALESCE(event_account.lastname, '') ||
|
||||
COALESCE(event_account.firstname, ''),
|
||||
' ', '')) LIKE LOWER(REPLACE(:search_value, ' ', '')) OR
|
||||
LOWER(event_email.email) LIKE LOWER(:search_value) OR
|
||||
LOWER(event_account.userid) LIKE LOWER(:search_value) OR
|
||||
|
||||
TO_CHAR(event_account.created::timestamp without time zone, 'dd/mm/yyyy hh24:mi:ss') LIKE :search_value
|
||||
)"
|
||||
);
|
||||
|
||||
$queryParams[':search_value'] = '%' . $search['value'] . '%';
|
||||
}
|
||||
|
||||
//Add search and ids into request
|
||||
$query = sprintf($query, $searchConditions);
|
||||
}
|
||||
|
||||
private function applyRules(string &$query, array &$queryParams): void {
|
||||
$ruleUids = $this->f3->get('REQUEST.ruleUids');
|
||||
if ($ruleUids === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$uids = [];
|
||||
foreach ($ruleUids as $ruleUid) {
|
||||
$uids[] = ['uid' => $ruleUid];
|
||||
}
|
||||
|
||||
$query .= ' AND score_details @> (:rules_uids)::jsonb';
|
||||
$queryParams[':rules_uids'] = json_encode($uids);
|
||||
}
|
||||
|
||||
private function applyScore(string &$query, array &$queryParams): void {
|
||||
$scoresRanges = $this->f3->get('REQUEST.scoresRange');
|
||||
if ($scoresRanges === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$clauses = [];
|
||||
foreach ($scoresRanges as $key => $scoreBase) {
|
||||
$clauses[] = sprintf('event_account.score >= :score_base_%s AND event_account.score <= :score_base_%s + 10', $key, $key);
|
||||
$queryParams[':score_base_' . $key] = intval($scoreBase);
|
||||
}
|
||||
|
||||
$query .= ' AND (' . implode(' OR ', $clauses) . ')';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
//
|
||||
Reference in New Issue
Block a user