Fun w/ Arrays/JSON

main
Robert 4 hours ago
parent dd22f11bdb
commit 5a2429067a
  1. 135
      src/Framework/Common.php
  2. 25
      src/Framework/Logger.php
  3. 14
      src/Framework/SiteHelper.php
  4. 31
      src/Framework/Trait/Security/CsrfTokenFunctions.php

@ -11,13 +11,14 @@ use IOcornerstone\Framework\{
Enum\ExitOnDump as endDump, Enum\ExitOnDump as endDump,
}; };
final class Common final class Common
{ {
/** /**
* Clear out from memory given variable by Reference! * Clear out from memory given variable by Reference!
* @param type $sensitive_data * @param type $sensitive_data
*/ */
public static function wipe(#[\SensitiveParameter] &$sensitive_data): void public static function wipe(#[\SensitiveParameter] &$sensitive_data): void
{ {
if (function_exists("sodium_memzero")) { if (function_exists("sodium_memzero")) {
sodium_memzero($sensitive_data); sodium_memzero($sensitive_data);
@ -25,29 +26,47 @@ final class Common
unset($sensitive_data); unset($sensitive_data);
} }
public static function getCount($i): int public static function getCount(mixed $i): int
{ {
return (is_array($i) || is_object($i)) ? count($i) : 0; return (is_array($i) || is_object($i)) ? count($i) : 0;
} }
public static function decodeJson(null|string|false $sJson, int $levelsDeep = 100): ?array
{
try {
if ($sJson !== false && $sJson !== null && $sJson !== "" && $sJson !== "[]" && json_validate($sJson, $levelsDeep)) {
$j = json_decode($sJson, associative: true, depth: $levelsDeep);
return $j;
}
} catch (\JsonException $e) {
return null;
}
return null;
}
public static function isArrayWithData(?array $data): bool
{
return (self::getCount($data) > 0) ? true : false;
}
public static function hasKeys(array $array): bool public static function hasKeys(array $array): bool
{ {
return array_keys($array) !== range(0, count($array) - 1); return array_keys($array) !== range(0, count($array) - 1);
} }
public static function combineDataToString(object $o, ...$args): string public static function combineDataToString(object $o, ...$args): string
{ {
$stringArgs = array_map(function($arg) { $stringArgs = array_map(function ($arg) {
if (is_array($arg) || is_object($arg)) { if (is_array($arg) || is_object($arg)) {
$arg = json_encode($arg); $arg = json_encode($arg);
} }
return (string)$arg; return (string) $arg;
}, $args); }, $args);
$seperator = $o->seperator ?? "|"; $seperator = $o->seperator ?? "|";
$combined = implode($seperator, $stringArgs); $combined = implode($seperator, $stringArgs);
$useLogger = $o->useLogger ?? false; $useLogger = $o->useLogger ?? false;
if ($useLogger) { if ($useLogger) {
$logger = new Logger(); $logger = new Logger();
@ -61,34 +80,72 @@ final class Common
return $combined; return $combined;
} }
public static function stringSubPart(string $string, int $offset = 0, ?int $length = null, $encoding = null) { public static function doesAllOfTheArrayHaveData(array $a, array $skipKeys = []): false|array
if ($length === null) { {
return F::substr($string, $offset, strlen($string)); if (self::isArrayWithData($a)) {
} else { foreach ($a as $key => $value) {
return F::substr($string, $offset, $length); if ($value === false) {
if (
self::isArrayWithData($skipKeys) && in_array($key, $skipKeys)
) {
continue; // In List of keys to Skip, so do so...
}
return false; // Input was false, not set..., so bail as false
}
}
return $a; // All is GOOD here, return the Data BACK
} }
return false; // Empty Data..., return false
} }
public static function safeFlipArray(?array $data): array
{
if ($data === null) {
return [];
}
foreach($data as $key => $value) {
if (is_bool($value)) {
$data[$key] = (int) $value;
}
}
$safeData = array_filter($data, function ($value) {
return is_string($value) || is_int($value);
});
return array_flip($safeData);
}
/** /**
* Will get only left part of string by length. * Will get only left part of string by length.
* @param string $str * @param string $str
* @param int $length * @param int $length
* @retval type string or false * @retval type string or false
*/ */
public static function getStringLeft(string $str, int $length): false | string { public static function getStringLeft(string $str, int $length): false|string
{
return self::stringSubPart($str, 0, $length); return self::stringSubPart($str, 0, $length);
} }
/** /**
* Will get only the right part of string by length. * Will get only the right part of string by length.
* @param string $str * @param string $str
* @param int $length * @param int $length
* @retval type string or false * @retval type string or false
*/ */
public static function getStringRight(string $str, int $length): false | string { public static function getStringRight(string $str, int $length): false|string
{
return self::stringSubPart($str, -$length); return self::stringSubPart($str, -$length);
} }
public static function stringSubPart(string $string, int $offset = 0, ?int $length = null, $encoding = null)
{
if ($length === null) {
return F::substr($string, $offset, strlen($string));
} else {
return F::substr($string, $offset, $length);
}
}
/** /**
* Variable Dump and exit * Variable Dump and exit
* Configure of security for show_dumps must be true for debugging. * Configure of security for show_dumps must be true for debugging.
@ -96,14 +153,15 @@ final class Common
* @param bool end - if true ends the script * @param bool end - if true ends the script
*/ */
public static function dump( public static function dump(
$var = 'nothing', $var = 'nothing',
endDump $end = endDump::EXIT_AND_STOP endDump $end = endDump::EXIT_AND_STOP
): void { ): void
{
if (\IOcornerstone\Framework\Configure::get('security', 'show_dumps') !== true) { if (\IOcornerstone\Framework\Configure::get('security', 'show_dumps') !== true) {
return; return;
} }
$isConsole = Console::isConsole(); $isConsole = Console::isConsole();
if (! $isConsole) { if (!$isConsole) {
echo "<details>\r\n<summary>Expand to see Var Dump:</summary>"; echo "<details>\r\n<summary>Expand to see Var Dump:</summary>";
echo "<p>"; echo "<p>";
var_dump($var); var_dump($var);
@ -131,13 +189,13 @@ final class Common
} elseif (is_null($var)) { } elseif (is_null($var)) {
echo 'VAR IS NULL!'; echo 'VAR IS NULL!';
} elseif (is_string($var)) { } elseif (is_string($var)) {
if (! $isConsole) { if (!$isConsole) {
echo 'VAR is a STRING = ' . htmlentities($var); echo 'VAR is a STRING = ' . htmlentities($var);
} else { } else {
echo 'VAR is a STRING = ' . $var; echo 'VAR is a STRING = ' . $var;
} }
} else { } else {
if (! $isConsole) { if (!$isConsole) {
echo "<pre style=\"border: 1px solid green; overflow: auto; margin: 0.5em;\">"; echo "<pre style=\"border: 1px solid green; overflow: auto; margin: 0.5em;\">";
print_r($var); print_r($var);
echo '</pre>'; echo '</pre>';
@ -146,7 +204,7 @@ final class Common
echo PHP_EOL; echo PHP_EOL;
} }
} }
if (! $isConsole) { if (!$isConsole) {
echo '<br><br>'; echo '<br><br>';
} }
@ -160,7 +218,8 @@ final class Common
* So, you need to code more checks! * So, you need to code more checks!
* @retval boolean true if AJAX request by JQuery, etc... * @retval boolean true if AJAX request by JQuery, etc...
*/ */
public static function isAjax(): bool { public static function isAjax(): bool
{
$http_x_requested_with = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? ""; $http_x_requested_with = $_SERVER['HTTP_X_REQUESTED_WITH'] ?? "";
return (strtolower($http_x_requested_with) === 'xmlhttprequest'); return (strtolower($http_x_requested_with) === 'xmlhttprequest');
} }
@ -168,17 +227,19 @@ final class Common
/** /**
* site http://php.net/manual/en/function.base64-encode.php * site http://php.net/manual/en/function.base64-encode.php
*/ */
public static function base64urlEncode(string $data): string { public static function base64urlEncode(string $data): string
return rtrim(strtr(base64_encode($data), '+/', '-_'), '='); {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
public static function base64urlDecode(string $data): string
{
//return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
return base64_decode(strtr($data, '-_', '+/') . str_repeat('=', 3 - (3 + strlen($data)) % 4));
} }
public static function base64urlDecode(string $data): string { public static function nl2br(string $text): string
//return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
return base64_decode( strtr( $data, '-_', '+/') . str_repeat('=', 3 - ( 3 + strlen( $data )) % 4 ));
}
public static function nl2br(string $text): string
{ {
return strtr($text, array("\r\n" => '<br />', "\r" => '<br />', "\n" => '<br />')); return strtr($text, array("\r\n" => '<br />', "\r" => '<br />', "\n" => '<br />'));
} }
} }

@ -159,7 +159,7 @@ final class Logger implements LoggerInterface
} }
if ( if (
self::LEVEL_PRIORITY[$level] < self::LEVEL_PRIORITY[$this->minLevel] self::LEVEL_PRIORITY[$level] < self::LEVEL_PRIORITY[$this->minLevel]
) { ) {
return; return;
} }
@ -185,7 +185,15 @@ final class Logger implements LoggerInterface
} }
/* ---------------- Level Methods ---------------- */ /* ---------------- Level Methods ---------------- */
public function msgWithArray($message, array $content = [], array $myArray = []): void
{
if (count($myArray) >0 ) {
$this->log(LogLevel::ALERT, $message . " :array<br>\r\n " . $this->arrayToString($myArray), $content);
return;
}
$this->log(level: LogLevel::ALERT, message: $message, context: $content);
}
public function emergency($message, array $context = []): void public function emergency($message, array $context = []): void
{ {
$this->log(LogLevel::EMERGENCY, $message, $context); $this->log(LogLevel::EMERGENCY, $message, $context);
@ -252,6 +260,19 @@ final class Logger implements LoggerInterface
return strtr($message, $replace); return strtr($message, $replace);
} }
private function arrayToString(?array $a, string $separator = ", "): string
{
if ($a === null) {
return "";
}
$s = "";
foreach($a as $key=>$value) {
$s .= "key: $key value: $value <br>" . PHP_EOL;
}
return $s;
}
private function getLines(string $file): int private function getLines(string $file): int
{ {

@ -13,6 +13,7 @@ namespace IOcornerstone\Framework;
use IOcornerstone\Framework\{ use IOcornerstone\Framework\{
Security, Security,
Console, Console,
Common,
}; };
/** /**
* Description of SiteHelper * Description of SiteHelper
@ -103,18 +104,9 @@ final class SiteHelper
public static function remoteNotAllowedForceLive(): bool public static function remoteNotAllowedForceLive(): bool
{ {
if (Console::isConsole()) { if (Console::isConsole()) {
return false; // false to show errors and dumps return false; // false to ALWAYs show errors and dumps on CLI
} }
$s = $_SESSION['usersRights'] ?? false;
if ($s !== false && strlen($s) > 4) {
$rights = json_decode($s, associative: true);
$flipped = array_flip($rights);
if (isset($flipped['developer'])) {
return false; // false for Developers to see Errors/Logs
}
}
return (!self::is_allowed()); return (!self::is_allowed());
} }

@ -10,11 +10,15 @@ declare(strict_types=1);
namespace IOcornerstone\Framework\Trait\Security; namespace IOcornerstone\Framework\Trait\Security;
use IOcornerstone\Framework\Configure; use IOcornerstone\Framework\{
Configure,
Common,
};
trait CsrfTokenFunctions trait CsrfTokenFunctions
{ {
const CSRF_TOKEN_POOL_SIZE_LIMIT = 15; // Total Sessions to Keep alive
/** /**
* Set Session to use CSRF Token * Set Session to use CSRF Token
* Useful for JSON data... * Useful for JSON data...
@ -30,16 +34,6 @@ trait CsrfTokenFunctions
return $newToken; return $newToken;
} }
/**
* Keep only last 15 tokens to prevent memory issues.
*/
public static function cleanUp(){
$keepOnly = 15;
if (count($_SESSION['csrf_pool']) > $keepOnly) {
$_SESSION['csrf_pool'] = array_slice($_SESSION['csrf_pool'], -$keepOnly, null, true);
}
}
/** /**
* Get CSRF Token for use with HTML Form * Get CSRF Token for use with HTML Form
* @return string Hidden Form with token set * @return string Hidden Form with token set
@ -97,6 +91,19 @@ trait CsrfTokenFunctions
unset($_SESSION['csrf_pool'][$key]); unset($_SESSION['csrf_pool'][$key]);
} }
} }
self::cleanUp();
}
/**
* Keep only last CSRF_TOKEN_POOL_SIZE_LIMIT tokens to prevent memory issues.
*/
private static function cleanUp(): void
{
if (Common::getCount($_SESSION['csrf_pool']) >
self::CSRF_TOKEN_POOL_SIZE_LIMIT
) {
$_SESSION['csrf_pool'] = array_slice($_SESSION['csrf_pool'], -self::CSRF_TOKEN_POOL_SIZE_LIMIT, null, true);
}
} }
private static function csrfTokenIsValid(string $csrfTokenKeyName = ""): false|int private static function csrfTokenIsValid(string $csrfTokenKeyName = ""): false|int

Loading…
Cancel
Save