Config class overhaul.

This commit is contained in:
flash 2023-07-18 21:48:44 +00:00
parent 2b92d00b4b
commit 8339892559
30 changed files with 838 additions and 396 deletions

View file

@ -2,7 +2,6 @@
namespace Misuzu;
use Misuzu\AuthToken;
use Misuzu\Config\IConfig;
use Misuzu\Users\User;
use Misuzu\Users\UserNotFoundException;
use Misuzu\Users\UserAuthSession;
@ -43,11 +42,28 @@ if(!empty($_GET['resolve'])) {
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';
$siteIsPrivate = $cfg->getValue('private.enable', IConfig::T_BOOL);
$loginPermCat = $siteIsPrivate ? $cfg->getValue('private.perm.cat', IConfig::T_STR) : '';
$loginPermVal = $siteIsPrivate ? $cfg->getValue('private.perm.val', IConfig::T_INT) : 0;
$remainingAttempts = UserLoginAttempt::remaining($ipAddress);
$siteIsPrivate = $cfg->getBoolean('private.enable');
if($siteIsPrivate) {
[
'private.perm.cat' => $loginPermCat,
'private.perm.val' => $loginPermVal,
'private.msg' => $sitePrivateMessage,
'private.allow_password_reset' => $canResetPassword,
] = $cfg->getValues([
'private.perm.cat:s',
'private.perm.val:i',
'private.msg:s',
['private.allow_password_reset:b', true],
]);
} else {
$loginPermCat = '';
$loginPermVal = 0;
$sitePrivateMessage = '';
$canResetPassword = true;
}
while(!empty($_POST['login']) && is_array($_POST['login'])) {
if(!CSRF::validateRequest()) {
$notices[] = 'Was unable to verify the request, please try again!';
@ -134,8 +150,6 @@ $loginUsername = !empty($_POST['login']['username']) && is_string($_POST['login'
!empty($_GET['username']) && is_string($_GET['username']) ? $_GET['username'] : ''
);
$loginRedirect = $welcomeMode ? url('index') : (!empty($_GET['redirect']) && is_string($_GET['redirect']) ? $_GET['redirect'] : null) ?? $_SERVER['HTTP_REFERER'] ?? url('index');
$sitePrivateMessage = $siteIsPrivate ? $cfg->getValue('private.msg', IConfig::T_STR) : '';
$canResetPassword = $siteIsPrivate ? $cfg->getValue('private.allow_password_reset', IConfig::T_BOOL, true) : true;
$canRegisterAccount = !$siteIsPrivate;
Template::render('auth.login', [

View file

@ -1,7 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Config\IConfig;
use Misuzu\Users\User;
use Misuzu\Users\UserNotFoundException;
use Misuzu\Users\UserLoginAttempt;
@ -33,8 +32,8 @@ if($userId > 0)
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$siteIsPrivate = $cfg->getValue('private.enable', IConfig::T_BOOL);
$canResetPassword = $siteIsPrivate ? $cfg->getValue('private.allow_password_reset', IConfig::T_BOOL, true) : true;
$siteIsPrivate = $cfg->getBoolean('private.enable');
$canResetPassword = $siteIsPrivate ? $cfg->getBoolean('private.allow_password_reset', true) : true;
$remainingAttempts = UserLoginAttempt::remaining($ipAddress);
while($canResetPassword) {

View file

@ -1,7 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Config\IConfig;
use Misuzu\Users\User;
require_once '../../misuzu.php';
@ -21,8 +20,16 @@ $leaderboardIdLength = strlen($leaderboardId);
$leaderboardYear = $leaderboardIdLength === 4 || $leaderboardIdLength === 6 ? substr($leaderboardId, 0, 4) : null;
$leaderboardMonth = $leaderboardIdLength === 6 ? substr($leaderboardId, 4, 2) : null;
$unrankedForums = !empty($_GET['allow_unranked']) ? [] : $cfg->getValue('forum_leader.unranked.forum', IConfig::T_ARR);
$unrankedTopics = !empty($_GET['allow_unranked']) ? [] : $cfg->getValue('forum_leader.unranked.topic', IConfig::T_ARR);
if(empty($_GET['allow_unranked'])) {
[
'forum_leader.unranked.forum' => $unrankedForums,
'forum_leader.unranked.topic' => $unrankedTopics,
] = $cfg->getValues([
'forum_leader.unranked.forum:a',
'forum_leader.unranked.topic:a',
]);
} else $unrankedForums = $unrankedTopics = [];
$leaderboards = forum_leaderboard_categories();
$leaderboard = forum_leaderboard_listing($leaderboardYear, $leaderboardMonth, $unrankedForums, $unrankedTopics);
@ -31,9 +38,8 @@ $leaderboardName = 'All Time';
if($leaderboardYear) {
$leaderboardName = "Leaderboard {$leaderboardYear}";
if($leaderboardMonth) {
if($leaderboardMonth)
$leaderboardName .= "-{$leaderboardMonth}";
}
}
if($leaderboardMode === 'markdown') {

View file

@ -1,7 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Config;
use Misuzu\Config\CfgTools;
use Misuzu\Users\User;
@ -13,25 +12,21 @@ if(!User::hasCurrent()
return;
}
$sName = (string)filter_input(INPUT_GET, 'name');
if(!CfgTools::validateName($sName) || !$cfg->hasValue($sName))
throw new \Exception("Config value does not exist.");
if($_SERVER['REQUEST_METHOD'] === 'POST') {
if(!CSRF::validateRequest())
throw new \Exception("Request verification failed.");
$msz->createAuditLog('CONFIG_DELETE', [$sName]);
$cfg->removeValue($sName);
url_redirect('manage-general-settings');
} else {
$sValue = $cfg->getValue($sName);
Template::render('manage.general.setting-delete', [
'conf_var' => [
'name' => $sName,
'type' => CfgTools::type($sValue),
'value' => $sValue,
],
]);
$valueName = (string)filter_input(INPUT_GET, 'name');
$valueInfo = $cfg->getValueInfo($valueName);
if($valueInfo === null) {
echo render_error(404);
return;
}
if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
$valueName = $valueInfo->getName();
$msz->createAuditLog('CONFIG_DELETE', [$valueName]);
$cfg->removeValues($valueName);
url_redirect('manage-general-settings');
return;
}
Template::render('manage.general.setting-delete', [
'config_value' => $valueInfo,
]);

View file

@ -1,9 +1,7 @@
<?php
namespace Misuzu;
use Misuzu\Config;
use Misuzu\Config\CfgTools;
use Misuzu\Config\IConfig;
use Misuzu\Config\DbConfig;
use Misuzu\Users\User;
require_once '../../../misuzu.php';
@ -14,105 +12,84 @@ if(!User::hasCurrent()
return;
}
$sVar = [
'name' => '',
'type' => '',
'value' => null,
'new' => true,
];
$isNew = true;
$sName = (string)filter_input(INPUT_GET, 'name');
$sType = (string)filter_input(INPUT_GET, 'type');
$sValue = null;
$loadValueInfo = fn() => $cfg->getValueInfo($sName);
if(!empty($sName)) {
if(!CfgTools::validateName($sName))
throw new \Exception("Config key name has invalid format.");
$sVar['name'] = $sName;
$sInfo = $loadValueInfo();
if($sInfo !== null) {
$isNew = false;
$sName = $sInfo->getName();
$sType = $sInfo->getType();
$sValue = $sInfo->getValue();
}
}
$sType = (string)filter_input(INPUT_GET, 'type');
if(!empty($sType)) {
if(!CfgTools::isValidType($sType))
throw new \Exception("Specified type is invalid.");
while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
if($isNew) {
$sName = trim((string)filter_input(INPUT_POST, 'conf_name'));
if(!DbConfig::validateName($sName)) {
echo 'Name contains invalid characters.';
break;
}
$sVar['type'] = $sType;
$sVar['value'] = CfgTools::default($sType);
}
if($_SERVER['REQUEST_METHOD'] === 'POST') {
if(!CSRF::validateRequest())
throw new \Exception("Request verification failed.");
if(empty($sName)) {
$sName = (string)filter_input(INPUT_POST, 'conf_name');
if(empty($sName) || !CfgTools::validateName($sName))
throw new \Exception("Config key name has invalid format.");
$sVar['name'] = $sName;
$sType = trim((string)filter_input(INPUT_POST, 'conf_type'));
if(!in_array($sType, ['string', 'int', 'float', 'bool', 'array'])) {
echo 'Invalid type specified.';
break;
}
}
$sLogAction = 'CONFIG_CREATE';
if($cfg->hasValue($sName)) {
$sType = CfgTools::type($cfg->getValue($sName));
$sVar['new'] = false;
$sLogAction = 'CONFIG_UPDATE';
} elseif(empty($sType)) {
$sType = (string)filter_input(INPUT_POST, 'conf_type');
if(empty($sType) || !CfgTools::isValidType($sType))
throw new \Exception("Specified type is invalid.");
}
$sVar['type'] = $sType;
$sValue = CfgTools::default($sType);
if($sType === 'array') {
if(!empty($_POST['conf_value']) && is_array($_POST['conf_value'])) {
foreach($_POST['conf_value'] as $fv) {
$fv = (string)$fv;
if(str_starts_with($fv, 's:')) {
$fv = substr($fv, 2);
} elseif(str_starts_with($fv, 'i:')) {
$fv = (int)substr($fv, 2);
} elseif(str_starts_with($fv, 'b:')) {
$fv = strtolower(substr($fv, 2));
$fv = $fv !== 'false' && $fv !== '0' && $fv !== '';
}
$sValue[] = $fv;
}
$applyFunc = $cfg->setArray(...);
$sValue = [];
$sRaw = filter_input(INPUT_POST, 'conf_value', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
foreach($sRaw as $rValue) {
if(strpos($rValue, ':') === 1) {
$rType = $rValue[0];
$rValue = substr($rValue, 2);
$sValue[] = match($rType) {
's' => $rValue,
'i' => (int)$rValue,
'd' => (float)$rValue,
'f' => (float)$rValue,
'b' => $rValue !== 'false' && $rValue !== '0' && $rValue !== '',
default => '',
};
} else
$sValue[] = $rValue;
}
} elseif($sType === 'boolean') {
} elseif($sType === 'bool') {
$sValue = !empty($_POST['conf_value']);
$applyFunc = $cfg->setBoolean(...);
} else {
$sValue = (string)filter_input(INPUT_POST, 'conf_value');
if($sType === 'integer')
$sValue = filter_input(INPUT_POST, 'conf_value');
if($sType === 'int') {
$applyFunc = $cfg->setInteger(...);
$sValue = (int)$sValue;
} elseif($sType === 'float') {
$applyFunc = $cfg->setFloat(...);
$sValue = (float)$sValue;
} else
$applyFunc = $cfg->setString(...);
}
$sVar['value'] = $sValue;
$msz->createAuditLog($sLogAction, [$sName]);
$cfg->setValue($sName, $sValue);
$msz->createAuditLog($isNew ? 'CONFIG_CREATE' : 'CONFIG_UPDATE', [$sName]);
$applyFunc($sName, $sValue);
url_redirect('manage-general-settings');
return;
}
if($cfg->hasValue($sName)) {
$sVar['new'] = false;
$sValue = $cfg->getValue($sName);
$sVar['type'] = $sType = CfgTools::type($sValue);
if($sType === IConfig::T_ARR)
foreach($sValue as $fk => $fv)
$sValue[$fk] = ['integer' => 'i', 'string' => 's', 'boolean' => 'b'][gettype($fv)] . ':' . $fv;
$sVar['value'] = $sValue;
}
if($sType === 'array' && !empty($sValue))
foreach($sValue as $key => $value)
$sValue[$key] = gettype($value)[0] . ':' . $value;
Template::render('manage.general.setting', [
'conf_var' => $sVar,
'config_new' => $isNew,
'config_name' => $sName,
'config_type' => $sType,
'config_value' => $sValue,
]);

View file

@ -1,9 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Config;
use Misuzu\Config\CfgTools;
use Misuzu\Config\IConfig;
use Misuzu\Users\User;
require_once '../../../misuzu.php';
@ -14,18 +11,10 @@ if(!User::hasCurrent()
return;
}
$hidden = $cfg->getValue('settings.hidden', IConfig::T_ARR, []);
$vars = [];
foreach($cfg->getNames() as $key) {
$var = $cfg->getValue($key);
$vars[] = [
'key' => $key,
'type' => CfgTools::type($var),
'value' => in_array($key, $hidden) ? '*** hidden ***' : json_encode($var),
];
}
$hidden = $cfg->getArray('settings.hidden');
$vars = $cfg->getAllValueInfos();
Template::render('manage.general.settings', [
'conf_vars' => $vars,
'config_vars' => $vars,
'config_hidden' => $hidden,
]);

View file

@ -1,8 +1,6 @@
<?php
namespace Misuzu;
use Misuzu\Config;
use Misuzu\Config\IConfig;
use Misuzu\Users\User;
use Misuzu\Users\UserRole;
use Misuzu\Users\UserRoleNotFoundException;
@ -49,7 +47,7 @@ if(!$isRestricted && $isVerifiedRequest && !empty($_POST['role'])) {
if($isVerifiedRequest && isset($_POST['tfa']['enable']) && $currentUser->hasTOTP() !== (bool)$_POST['tfa']['enable']) {
if((bool)$_POST['tfa']['enable']) {
$tfaKey = TOTP::generateKey();
$tfaIssuer = $cfg->getValue('site.name', IConfig::T_STR, 'Misuzu');
$tfaIssuer = $cfg->getString('site.name', 'Misuzu');
$tfaQrcode = (new QRCode(new QROptions([
'version' => 5,
'outputType' => QRCode::OUTPUT_IMAGE_JPG,