Skip to content
Snippets Groups Projects
Verified Commit c5b5b41f authored by Dominik Frantisek Bucik's avatar Dominik Frantisek Bucik Committed by Dominik František Bučík
Browse files

fix: :bug: Fix possible exceptions and refactor code

Refactored code to include more logging. Also fixed some possible
exception places.
parent 7e001acf
Branches
Tags
1 merge request!82fix: 🐛 Fix possible exceptions
...@@ -5,11 +5,17 @@ declare(strict_types=1); ...@@ -5,11 +5,17 @@ declare(strict_types=1);
namespace SimpleSAML\Module\proxystatistics\Auth\Process; namespace SimpleSAML\Module\proxystatistics\Auth\Process;
use DateTime; use DateTime;
use Exception;
use SimpleSAML\Auth\ProcessingFilter; use SimpleSAML\Auth\ProcessingFilter;
use SimpleSAML\Logger;
use SimpleSAML\Module\proxystatistics\DatabaseCommand; use SimpleSAML\Module\proxystatistics\DatabaseCommand;
class Statistics extends ProcessingFilter class Statistics extends ProcessingFilter
{ {
private const STAGE = 'proxystatistics:Statistics';
private const DEBUG_PREFIX = self::STAGE . ' - ';
public function __construct($config, $reserved) public function __construct($config, $reserved)
{ {
parent::__construct($config, $reserved); parent::__construct($config, $reserved);
...@@ -19,6 +25,12 @@ class Statistics extends ProcessingFilter ...@@ -19,6 +25,12 @@ class Statistics extends ProcessingFilter
{ {
$dateTime = new DateTime(); $dateTime = new DateTime();
$dbCmd = new DatabaseCommand(); $dbCmd = new DatabaseCommand();
$dbCmd->insertLogin($request, $dateTime); try {
$dbCmd->insertLogin($request, $dateTime);
} catch (Exception $ex) {
Logger::error(
self::DEBUG_PREFIX . 'Caught exception while inserting login into statistics: ' . $ex->getMessage()
);
}
} }
} }
...@@ -20,6 +20,8 @@ class Config ...@@ -20,6 +20,8 @@ class Config
public const MODE_PROXY = 'PROXY'; public const MODE_PROXY = 'PROXY';
private const KNOWN_MODES = ['PROXY', 'IDP', 'SP', 'MULTI_IDP'];
private const STORE = 'store'; private const STORE = 'store';
private const MODE = 'mode'; private const MODE = 'mode';
...@@ -40,22 +42,33 @@ class Config ...@@ -40,22 +42,33 @@ class Config
private $sourceIdpEntityIdAttribute; private $sourceIdpEntityIdAttribute;
private $tables;
private $keepPerUser;
private $requiredAuthSource;
private $idAttribute;
private static $instance; private static $instance;
private function __construct() private function __construct()
{ {
$this->config = Configuration::getConfig(self::CONFIG_FILE_NAME); $this->config = Configuration::getConfig(self::CONFIG_FILE_NAME);
$this->store = $this->config->getConfigItem(self::STORE, null); $this->store = $this->config->getConfigItem(self::STORE, null);
$this->tables = $this->config->getArray('tables', []); $this->tables = $this->config->getArray('tables', []);;
$this->mode = $this->config->getValueValidate(self::MODE, ['PROXY', 'IDP', 'SP', 'MULTI_IDP'], 'PROXY');
$this->sourceIdpEntityIdAttribute = $this->config->getString(self::SOURCE_IDP_ENTITY_ID_ATTRIBUTE, ''); $this->sourceIdpEntityIdAttribute = $this->config->getString(self::SOURCE_IDP_ENTITY_ID_ATTRIBUTE, '');
$this->mode = $this->config->getValueValidate(self::MODE, self::KNOWN_MODES, self::MODE_PROXY);
$this->keepPerUser = $this->config->getIntegerRange(self::KEEP_PER_USER, 31, 1827, 31);
$this->requiredAuthSource = $this->config->getString(self::REQUIRE_AUTH_SOURCE, '');
$this->idAttribute = $this->config->getString(self::USER_ID_ATTRIBUTE, 'uid');
} }
private function __clone() private function __clone()
{ {
} }
public static function getInstance() public static function getInstance(): self
{ {
if (null === self::$instance) { if (null === self::$instance) {
self::$instance = new self(); self::$instance = new self();
...@@ -81,7 +94,7 @@ class Config ...@@ -81,7 +94,7 @@ class Config
public function getIdAttribute() public function getIdAttribute()
{ {
return $this->config->getString(self::USER_ID_ATTRIBUTE, 'uid'); return $this->idAttribute;
} }
public function getSourceIdpEntityIdAttribute() public function getSourceIdpEntityIdAttribute()
...@@ -89,9 +102,11 @@ class Config ...@@ -89,9 +102,11 @@ class Config
return $this->sourceIdpEntityIdAttribute; return $this->sourceIdpEntityIdAttribute;
} }
public function getSideInfo($side) public function getSideInfo(string $side)
{ {
assert(in_array($side, [self::SIDES], true)); if (!in_array($side, self::SIDES, true)) {
throw new \Exception('Unrecognized side parameter value passed \'' . $side . '\'.');
}
return array_merge([ return array_merge([
'name' => '', 'name' => '',
...@@ -101,11 +116,11 @@ class Config ...@@ -101,11 +116,11 @@ class Config
public function getRequiredAuthSource() public function getRequiredAuthSource()
{ {
return $this->config->getString(self::REQUIRE_AUTH_SOURCE, ''); return$this->requiredAuthSource;
} }
public function getKeepPerUser() public function getKeepPerUser()
{ {
return $this->config->getIntegerRange(self::KEEP_PER_USER, 31, 1827, 31); return $this->keepPerUser;
} }
} }
...@@ -4,13 +4,16 @@ declare(strict_types=1); ...@@ -4,13 +4,16 @@ declare(strict_types=1);
namespace SimpleSAML\Module\proxystatistics; namespace SimpleSAML\Module\proxystatistics;
use Exception;
use PDO; use PDO;
use PDOStatement;
use SimpleSAML\Database; use SimpleSAML\Database;
use SimpleSAML\Logger; use SimpleSAML\Logger;
class DatabaseCommand class DatabaseCommand
{ {
public const TABLE_SUM = 'statistics_sums'; public const TABLE_SUM = 'statistics_sums';
private const DEBUG_PREFIX = 'proxystatistics:DatabaseCommand - ';
private const TABLE_PER_USER = 'statistics_per_user'; private const TABLE_PER_USER = 'statistics_per_user';
...@@ -18,6 +21,10 @@ class DatabaseCommand ...@@ -18,6 +21,10 @@ class DatabaseCommand
private const TABLE_SP = 'statistics_sp'; private const TABLE_SP = 'statistics_sp';
private const KEY_ID = 'id';
private const KEY_NAME = 'name';
private const TABLE_SIDES = [ private const TABLE_SIDES = [
Config::MODE_IDP => self::TABLE_IDP, Config::MODE_IDP => self::TABLE_IDP,
Config::MODE_SP => self::TABLE_SP, Config::MODE_SP => self::TABLE_SP,
...@@ -47,25 +54,26 @@ class DatabaseCommand ...@@ -47,25 +54,26 @@ class DatabaseCommand
{ {
$this->config = Config::getInstance(); $this->config = Config::getInstance();
$this->conn = Database::getInstance($this->config->getStore()); $this->conn = Database::getInstance($this->config->getStore());
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$this->escape_char = '"'; $this->escape_char = '"';
} elseif ($this->isMysql()) {
$this->escape_char = '`';
} else {
$this->unknownDriver();
} }
$this->tables = array_merge($this->tables, $this->config->getTables()); $this->tables = array_merge($this->tables, $this->config->getTables());
$this->mode = $this->config->getMode(); $this->mode = $this->config->getMode();
} }
public static function prependColon($str) public function insertLogin($request, &$date)
{
return ':' . $str;
}
public function insertLogin(&$request, &$date)
{ {
$entities = $this->getEntities($request); $entities = $this->prepareEntitiesData($request);
foreach (Config::SIDES as $side) { foreach (Config::SIDES as $side) {
if (empty($entities[$side]['id'])) { if (empty($entities[$side][self::KEY_ID])) {
Logger::error('idpEntityId or spEntityId is empty and login log was not inserted into the database.'); Logger::error(
self::DEBUG_PREFIX . 'idpEntityId or spEntityId is empty and login log was not inserted into the database.'
);
return; return;
} }
...@@ -76,15 +84,19 @@ class DatabaseCommand ...@@ -76,15 +84,19 @@ class DatabaseCommand
$ids = []; $ids = [];
foreach (self::TABLE_SIDES as $side => $table) { foreach (self::TABLE_SIDES as $side => $table) {
$tableId = self::TABLE_IDS[$table]; $tableId = self::TABLE_IDS[$table];
$ids[$tableId] = $this->getIdFromIdentifier($table, $entities[$side], $tableId); $ids[$tableId] = $this->getEntityDbIdFromEntityIdentifier($table, $entities[$side], $tableId);
} }
if (false === $this->writeLogin($date, $ids, $userId)) { if (false === $this->writeLogin($date, $ids, $userId)) {
Logger::error('The login log was not inserted.'); Logger::error(self::DEBUG_PREFIX . 'login record has not been inserted (data \'' . json_encode([
'user' => $userId,
'ids' => $ids,
'date' => $date,
]) . '\'.');
} }
} }
public function getNameById($side, $id) public function getEntityNameByEntityIdentifier($side, $id)
{ {
$table = self::TABLE_SIDES[$side]; $table = self::TABLE_SIDES[$side];
...@@ -101,10 +113,12 @@ class DatabaseCommand ...@@ -101,10 +113,12 @@ class DatabaseCommand
public function getLoginCountPerDay($days, $where = []) public function getLoginCountPerDay($days, $where = [])
{ {
$params = []; $params = [];
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$query = "SELECT EXTRACT(epoch FROM TO_DATE(CONCAT(year,'-',month,'-',day), 'YYYY-MM-DD')) AS day, "; $query = "SELECT EXTRACT(epoch FROM TO_DATE(CONCAT(year,'-',month,'-',day), 'YYYY-MM-DD')) AS day, ";
} else { } elseif ($this->isMysql()) {
$query = "SELECT UNIX_TIMESTAMP(STR_TO_DATE(CONCAT(year,'-',month,'-',day), '%Y-%m-%d')) AS day, "; $query = "SELECT UNIX_TIMESTAMP(STR_TO_DATE(CONCAT(year,'-',month,'-',day), '%Y-%m-%d')) AS day, ";
} else {
$this->unknownDriver();
} }
$query .= 'logins AS count, users ' . $query .= 'logins AS count, users ' .
'FROM ' . $this->tables[self::TABLE_SUM] . ' ' . 'FROM ' . $this->tables[self::TABLE_SUM] . ' ' .
...@@ -148,7 +162,7 @@ class DatabaseCommand ...@@ -148,7 +162,7 @@ class DatabaseCommand
foreach ([self::TABLE_IDS[self::TABLE_SP], null] as $sp_id) { foreach ([self::TABLE_IDS[self::TABLE_SP], null] as $sp_id) {
$ids = [$idp_id, $sp_id]; $ids = [$idp_id, $sp_id];
$msg = 'Aggregating daily statistics per ' . implode(' and ', array_filter($ids)); $msg = 'Aggregating daily statistics per ' . implode(' and ', array_filter($ids));
Logger::info($msg); Logger::info(self::DEBUG_PREFIX . $msg);
$query = 'INSERT INTO ' . $this->tables[self::TABLE_SUM] . ' ' $query = 'INSERT INTO ' . $this->tables[self::TABLE_SUM] . ' '
. '(' . $this->escape_cols(['year', 'month', 'day', 'idp_id', 'sp_id', 'logins', 'users']) . ') ' . '(' . $this->escape_cols(['year', 'month', 'day', 'idp_id', 'sp_id', 'logins', 'users']) . ') '
. 'SELECT EXTRACT(YEAR FROM ' . $this->escape_col( . 'SELECT EXTRACT(YEAR FROM ' . $this->escape_col(
...@@ -163,16 +177,18 @@ class DatabaseCommand ...@@ -163,16 +177,18 @@ class DatabaseCommand
. 'FROM ' . $this->tables[self::TABLE_PER_USER] . ' ' . 'FROM ' . $this->tables[self::TABLE_PER_USER] . ' '
. 'WHERE day<DATE(NOW()) ' . 'WHERE day<DATE(NOW()) '
. 'GROUP BY ' . $this->getAggregateGroupBy($ids) . ' '; . 'GROUP BY ' . $this->getAggregateGroupBy($ids) . ' ';
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$query .= 'ON CONFLICT (' . $this->escape_cols( $query .= 'ON CONFLICT (' . $this->escape_cols(
['year', 'month', 'day', 'idp_id', 'sp_id'] ['year', 'month', 'day', 'idp_id', 'sp_id']
) . ') DO NOTHING;'; ) . ') DO NOTHING;';
} else { } elseif ($this->isMysql()) {
$query .= 'ON DUPLICATE KEY UPDATE id=id;'; $query .= 'ON DUPLICATE KEY UPDATE id=id;';
} else {
$this->unknownDriver();
} }
// do nothing if row already exists // do nothing if row already exists
if (!$this->conn->write($query)) { if (!$this->conn->write($query)) {
Logger::warning($msg . ' failed'); Logger::warning(self::DEBUG_PREFIX . $msg . ' failed');
} }
} }
} }
...@@ -180,12 +196,12 @@ class DatabaseCommand ...@@ -180,12 +196,12 @@ class DatabaseCommand
$keepPerUserDays = $this->config->getKeepPerUser(); $keepPerUserDays = $this->config->getKeepPerUser();
$msg = 'Deleting detailed statistics'; $msg = 'Deleting detailed statistics';
Logger::info($msg); Logger::info(self::DEBUG_PREFIX . $msg);
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$make_date = 'MAKE_DATE(' . $this->escape_cols(['year', 'month', 'day']) . ')'; $make_date = 'MAKE_DATE(' . $this->escape_cols(['year', 'month', 'day']) . ')';
$date_clause = sprintf('CURRENT_DATE - INTERVAL \'%s DAY\' ', $keepPerUserDays); $date_clause = sprintf('CURRENT_DATE - INTERVAL \'%s DAY\' ', $keepPerUserDays);
$params = []; $params = [];
} else { } elseif ($this->isMysql()) {
$make_date = 'STR_TO_DATE(CONCAT(' . $this->escape_col('year') . ",'-'," . $this->escape_col( $make_date = 'STR_TO_DATE(CONCAT(' . $this->escape_col('year') . ",'-'," . $this->escape_col(
'month' 'month'
) . ",'-'," . $this->escape_col('day') . "), '%Y-%m-%d')"; ) . ",'-'," . $this->escape_col('day') . "), '%Y-%m-%d')";
...@@ -193,6 +209,8 @@ class DatabaseCommand ...@@ -193,6 +209,8 @@ class DatabaseCommand
$params = [ $params = [
'days' => $keepPerUserDays, 'days' => $keepPerUserDays,
]; ];
} else {
$this->unknownDriver();
} }
$query = 'DELETE FROM ' . $this->tables[self::TABLE_PER_USER] . ' WHERE ' . $this->escape_col( $query = 'DELETE FROM ' . $this->tables[self::TABLE_PER_USER] . ' WHERE ' . $this->escape_col(
'day' 'day'
...@@ -200,56 +218,33 @@ class DatabaseCommand ...@@ -200,56 +218,33 @@ class DatabaseCommand
. ' AND ' . $this->escape_col( . ' AND ' . $this->escape_col(
'day' 'day'
) . ' IN (SELECT ' . $make_date . ' FROM ' . $this->tables[self::TABLE_SUM] . ')'; ) . ' IN (SELECT ' . $make_date . ' FROM ' . $this->tables[self::TABLE_SUM] . ')';
if ( $written = $this->conn->write($query, $params);
!$this->conn->write($query, $params) if (is_bool($written) && !$written) {
) { Logger::warning(self::DEBUG_PREFIX . $msg . ' failed');
Logger::warning($msg . ' failed'); } elseif (0 === $written) {
Logger::warning(self::DEBUG_PREFIX . $msg . ' completed, but updated 0 rows.');
} else {
Logger::info(self::DEBUG_PREFIX . $msg . ' completed and updated ' . $written . ' rows.');
} }
} }
private function escape_col($col_name) public static function prependColon($str): string
{ {
return $this->escape_char . $col_name . $this->escape_char; return ':' . $str;
}
private function escape_cols($col_names)
{
return $this->escape_char . implode(
$this->escape_char . ',' . $this->escape_char,
$col_names
) . $this->escape_char;
} }
private function read($query, $params) private function writeLogin($date, $ids, $user): bool
{ {
return $this->conn->read($query, $params); if (empty($user)) {
} Logger::warning(self::DEBUG_PREFIX . 'user is unknown, cannot insert login. Ending prematurely.');
private function addWhereId($where, &$query, &$params) return false;
{
$parts = [];
foreach ($where as $side => $value) {
$table = self::TABLE_SIDES[$side];
$column = self::TABLE_IDS[$table];
$part = $column;
if (null === $value) {
$part .= '=0';
} else {
$part .= '=:id';
$params['id'] = $value;
}
$parts[] = $part;
}
if (empty($parts)) {
$parts[] = '1=1';
} }
$query .= implode(' AND ', $parts); if (empty($ids[self::TABLE_IDS[self::TABLE_IDP]]) || empty($ids[self::TABLE_IDS[self::TABLE_SP]])) {
$query .= ' '; Logger::warning(
} self::DEBUG_PREFIX . 'no IDP_ID or SP_ID has been provided, cannot insert login. Ending prematurely.'
);
private function writeLogin($date, $ids, $user)
{
if (empty($user)) {
return false; return false;
} }
$params = array_merge($ids, [ $params = array_merge($ids, [
...@@ -260,59 +255,75 @@ class DatabaseCommand ...@@ -260,59 +255,75 @@ class DatabaseCommand
$fields = array_keys($params); $fields = array_keys($params);
$placeholders = array_map(['self', 'prependColon'], $fields); $placeholders = array_map(['self', 'prependColon'], $fields);
$query = 'INSERT INTO ' . $this->tables[self::TABLE_PER_USER] . ' (' . $this->escape_cols($fields) . ')' . $query = 'INSERT INTO ' . $this->tables[self::TABLE_PER_USER] . ' (' . $this->escape_cols($fields) . ')' .
' VALUES (' . implode(', ', $placeholders) . ') '; ' VALUES (' . implode(', ', $placeholders) . ') ';
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$query .= 'ON CONFLICT (' . $this->escape_cols( $query .= 'ON CONFLICT (' . $this->escape_cols(
['day', 'idp_id', 'sp_id', 'user'] ['day', 'idp_id', 'sp_id', 'user']
) . ') DO UPDATE SET "logins" = ' . $this->tables[self::TABLE_PER_USER] . '.logins + 1;'; ) . ') DO UPDATE SET "logins" = ' . $this->tables[self::TABLE_PER_USER] . '.logins + 1;';
} else { } elseif ($this->isMysql()) {
$query .= 'ON DUPLICATE KEY UPDATE logins = logins + 1;'; $query .= 'ON DUPLICATE KEY UPDATE logins = logins + 1;';
} else {
$this->unknownDriver();
}
$written = $this->conn->write($query, $params);
if (is_bool($written) && !$written) {
Logger::debug(self::DEBUG_PREFIX . 'login entry write has failed.');
return false;
} }
if (0 === $written) {
Logger::debug(self::DEBUG_PREFIX . 'login entry has been inserted, but has updated 0 rows.');
return $this->conn->write($query, $params); return false;
}
return true;
} }
private function getEntities($request): array private function prepareEntitiesData($request): array
{ {
$entities = [ $entities = [
Config::MODE_IDP => [], Config::MODE_IDP => [],
Config::MODE_SP => [], Config::MODE_SP => [],
]; ];
if (Config::MODE_IDP !== $this->mode && Config::MODE_MULTI_IDP !== $this->mode) { if (Config::MODE_IDP !== $this->mode && Config::MODE_MULTI_IDP !== $this->mode) {
$entities[Config::MODE_IDP]['id'] = $this->getIdpIdentifier($request); $entities[Config::MODE_IDP][self::KEY_ID] = $this->getIdpIdentifier($request);
$entities[Config::MODE_IDP]['name'] = $this->getIdpName($request); $entities[Config::MODE_IDP][self::KEY_NAME] =$this->getIdpName($request);
} }
if (Config::MODE_SP !== $this->mode) { if (Config::MODE_SP !== $this->mode) {
$entities[Config::MODE_SP]['id'] = $this->getSpIdentifier($request); $entities[Config::MODE_SP][self::KEY_ID] = $this->getSpIdentifier($request);
$entities[Config::MODE_SP]['name'] = $this->getSpName($request); $entities[Config::MODE_SP][self::KEY_NAME] =$this->getSpName($request);
} }
if (Config::MODE_PROXY !== $this->mode && Config::MODE_MULTI_IDP !== $this->mode) { if (Config::MODE_PROXY !== $this->mode && Config::MODE_MULTI_IDP !== $this->mode) {
$entities[$this->mode] = $this->config->getSideInfo($this->mode); $entities[$this->mode] = $this->config->getSideInfo($this->mode);
if (empty($entities[$this->mode]['id']) || empty($entities[$this->mode]['name'])) { if (empty($entities[$this->mode][self::KEY_ID]) || empty($entities[$this->mode][self::KEY_NAME])) {
Logger::error('Invalid configuration (id, name) for ' . $this->mode); Logger::error(self::DEBUG_PREFIX . 'Invalid configuration (id, name) for ' . $this->mode);
} }
} }
if (Config::MODE_MULTI_IDP === $this->mode) { if (Config::MODE_MULTI_IDP === $this->mode) {
$entities[Config::MODE_IDP] = $this->config->getSideInfo(Config::MODE_IDP); $entities[Config::MODE_IDP] = $this->config->getSideInfo(Config::MODE_IDP);
if (empty($entities[Config::MODE_IDP]['id']) || empty($entities[Config::MODE_IDP]['name'])) { if (empty($entities[Config::MODE_IDP][self::KEY_ID]) || empty($entities[Config::MODE_IDP][self::KEY_NAME])) {
Logger::error('Invalid configuration (id, name) for ' . $this->mode); Logger::error(self::DEBUG_PREFIX . 'Invalid configuration (id, name) for ' . $this->mode);
} }
} }
return $entities; return $entities;
} }
private function getIdFromIdentifier($table, $entity, $idColumn) private function getEntityDbIdFromEntityIdentifier($table, $entity, $idColumn)
{ {
$identifier = $entity['id']; $identifier = $entity[self::KEY_ID];
$name = $entity['name']; $name = $entity[self::KEY_NAME];
$query = 'INSERT INTO ' . $this->tables[$table] . '(identifier, name) VALUES (:identifier, :name1) '; $query = 'INSERT INTO ' . $this->tables[$table] . '(identifier, name) VALUES (:identifier, :name1) ';
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$query .= 'ON CONFLICT (identifier) DO UPDATE SET name = :name2;'; $query .= 'ON CONFLICT (identifier) DO UPDATE SET name = :name2;';
} else { } else if ($this->isMysql()) {
$query .= 'ON DUPLICATE KEY UPDATE name = :name2'; $query .= 'ON DUPLICATE KEY UPDATE name = :name2';
} else {
$this->unknownDriver();
} }
$this->conn->write($query, [ $this->conn->write($query, [
'identifier' => $identifier, 'identifier' => $identifier,
...@@ -323,9 +334,31 @@ class DatabaseCommand ...@@ -323,9 +334,31 @@ class DatabaseCommand
return $this->read('SELECT ' . $idColumn . ' FROM ' . $this->tables[$table] return $this->read('SELECT ' . $idColumn . ' FROM ' . $this->tables[$table]
. ' WHERE identifier=:identifier', [ . ' WHERE identifier=:identifier', [
'identifier' => $identifier, 'identifier' => $identifier,
]) ])->fetchColumn();
->fetchColumn() }
;
// Query construction helper methods
private function addWhereId($where, &$query, &$params)
{
$parts = [];
foreach ($where as $side => $value) {
$table = self::TABLE_SIDES[$side];
$column = self::TABLE_IDS[$table];
$part = $column;
if (null === $value) {
$part .= '=0';
} else {
$part .= '=:id';
$params['id'] = $value;
}
$parts[] = $part;
}
if (empty($parts)) {
$parts[] = '1=1';
}
$query .= implode(' AND ', $parts);
$query .= ' ';
} }
private function addDaysRange($days, &$query, &$params, $not = false) private function addDaysRange($days, &$query, &$params, $not = false)
...@@ -336,17 +369,19 @@ class DatabaseCommand ...@@ -336,17 +369,19 @@ class DatabaseCommand
} else { } else {
$query .= 'AND'; $query .= 'AND';
} }
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
$query .= ' MAKE_DATE(year,month,day) '; $query .= ' MAKE_DATE(year,month,day) ';
} else { } elseif ($this->isMysql()) {
$query .= " CONCAT(year,'-',LPAD(month,2,'00'),'-',LPAD(day,2,'00')) "; $query .= " CONCAT(year,'-',LPAD(month,2,'00'),'-',LPAD(day,2,'00')) ";
} else {
$this->unknownDriver();
} }
if ($not) { if ($not) {
$query .= 'NOT '; $query .= 'NOT ';
} }
if ('pgsql' === $this->conn->getDriver()) { if ($this->isPgsql()) {
if (!is_int($days) && !ctype_digit($days)) { if (!is_int($days) && !ctype_digit($days)) {
throw new \Exception('days have to be an integer'); throw new Exception('days have to be an integer');
} }
$query .= sprintf('BETWEEN CURRENT_DATE - INTERVAL \'%s DAY\' AND CURRENT_DATE ', $days); $query .= sprintf('BETWEEN CURRENT_DATE - INTERVAL \'%s DAY\' AND CURRENT_DATE ', $days);
} else { } else {
...@@ -356,7 +391,20 @@ class DatabaseCommand ...@@ -356,7 +391,20 @@ class DatabaseCommand
} }
} }
private function getAggregateGroupBy($ids) private function escape_col($col_name): string
{
return $this->escape_char . $col_name . $this->escape_char;
}
private function escape_cols($col_names): string
{
return $this->escape_char . implode(
$this->escape_char . ',' . $this->escape_char,
$col_names
) . $this->escape_char;
}
private function getAggregateGroupBy($ids): string
{ {
$columns = ['day']; $columns = ['day'];
foreach ($ids as $id) { foreach ($ids as $id) {
...@@ -402,6 +450,27 @@ class DatabaseCommand ...@@ -402,6 +450,27 @@ class DatabaseCommand
$displayName = $request['Destination']['name']['en'] ?? ''; $displayName = $request['Destination']['name']['en'] ?? '';
} }
return$displayName; return $displayName;
}
private function read($query, $params): PDOStatement
{
return $this->conn->read($query, $params);
}
private function isPgsql(): bool
{
return 'pgsql' === $this->conn->getDriver();
}
private function isMysql(): bool
{
return 'mysql' === $this->conn->getDriver();
}
private function unknownDriver()
{
Logger::error(self::DEBUG_PREFIX . 'unsupported DB driver \'' . $this->conn->getDriver());
throw new Exception('Unsupported DB driver');
} }
} }
...@@ -10,6 +10,8 @@ use SimpleSAML\XHTML\Template; ...@@ -10,6 +10,8 @@ use SimpleSAML\XHTML\Template;
class Templates class Templates
{ {
private const DEBUG_PREFIX = 'proxystatistics:Templates - ';
private const INSTANCE_NAME = 'instance_name'; private const INSTANCE_NAME = 'instance_name';
public static function showProviders($side, $tab) public static function showProviders($side, $tab)
...@@ -95,7 +97,7 @@ class Templates ...@@ -95,7 +97,7 @@ class Templates
} }
$t->data['head'] .= Utils::metaData('translations', $translations); $t->data['head'] .= Utils::metaData('translations', $translations);
$name = $dbCmd->getNameById($side, $id); $name = $dbCmd->getEntityNameByEntityIdentifier($side, $id);
$t->data['header'] = $t->t('{proxystatistics:stats:' . $side . 'Detail_header_name}') . $name; $t->data['header'] = $t->t('{proxystatistics:stats:' . $side . 'Detail_header_name}') . $name;
$t->data['htmlinject']['htmlContentPost'][] $t->data['htmlinject']['htmlContentPost'][]
...@@ -148,7 +150,9 @@ class Templates ...@@ -148,7 +150,9 @@ class Templates
if (null !== $instanceName) { if (null !== $instanceName) {
$t->data['header'] = $instanceName . ' ' . $t->data['header']; $t->data['header'] = $instanceName . ' ' . $t->data['header'];
} else { } else {
Logger::warning('Missing configuration: config.php - instance_name is not set.'); Logger::warning(
self::DEBUG_PREFIX . 'missing configuration option in config.php - instance_name is not set.'
);
} }
self::headIncludes($t); self::headIncludes($t);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment