MRBS 1.12.2 等保2.0二级整改完整提交
包含:登录失败锁定、90天密码有效期、30分钟会话超时、 强制改密、登录审计日志、屏幕水印、企业背景图、 备案信息固定底部、favicon、JS空集合保护、 会话过期体验优化(403 JSON)、display_errors 关闭、 固定 key 根治 Integrity check failed 等全部改动 注意:config.inc.php/.htaccess/.user.ini 含敏感信息, 通过 .gitignore 排除,勿推送到公开仓库。
This commit is contained in:
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace MRBS;
|
||||
|
||||
|
||||
// A class for managing the optional message that is displayed at the top of the calendar
|
||||
class Message
|
||||
{
|
||||
private const FORMAT_DATE = 'Y-m-d';
|
||||
private const FORMAT_DATETIME = 'Y-m-d\TH:i:s';
|
||||
private static $instance = null;
|
||||
private $text = '';
|
||||
private $from = '';
|
||||
private $until = '';
|
||||
|
||||
|
||||
private function __construct(string $text = '', string $from_date = '', string $until_date = '')
|
||||
{
|
||||
assert(version_compare(MRBS_MIN_PHP_VERSION, '7.4.0', '<'), "The __wakeup() method is now redundant.");
|
||||
$this->setText($text);
|
||||
$this->setFromDate($from_date);
|
||||
$this->setUntilDate($until_date);
|
||||
}
|
||||
|
||||
|
||||
private function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public function __unserialize(array $data) : void
|
||||
{
|
||||
// __unserialize() must have public visibility
|
||||
throw new \Exception("Cannot unserialize a singleton.");
|
||||
}
|
||||
|
||||
|
||||
// __wakeup() is deprecated from PHP 8.5.
|
||||
// "The __wakeup() serialization magic method has been deprecated. Implement __unserialize()
|
||||
// instead (or in addition, if support for old PHP versions is necessary)".
|
||||
// __unserialize() is only available from PHP 7.4.0
|
||||
public function __wakeup()
|
||||
{
|
||||
// __wakeup() must have public visibility
|
||||
throw new \Exception("Cannot unserialize a singleton.");
|
||||
}
|
||||
|
||||
|
||||
public static function getInstance(string $text = '', string $from_date = '', string $until_date = ''): Message
|
||||
{
|
||||
if (!isset(self::$instance))
|
||||
{
|
||||
self::$instance = new self($text, $from_date, $until_date);
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
// Loads a message from the database
|
||||
public function load() : void
|
||||
{
|
||||
$sql = "SELECT variable_content
|
||||
FROM " . _tbl('variables') . "
|
||||
WHERE variable_name='message'
|
||||
LIMIT 1";
|
||||
$res = db()->query_array($sql);
|
||||
|
||||
$message = (count($res) === 0) ? [] : json_decode($res[0], true);
|
||||
|
||||
$this->setText($message['text'] ?? '');
|
||||
$this->setFrom($message['from'] ?? '');
|
||||
$this->setUntil($message['until'] ?? '');
|
||||
}
|
||||
|
||||
|
||||
// Saves a message to the database
|
||||
public function save() : bool
|
||||
{
|
||||
$sql_params = array();
|
||||
$data = array(
|
||||
'variable_name' => 'message',
|
||||
'variable_content' => json_encode([
|
||||
'text' => $this->text,
|
||||
'from' => $this->from,
|
||||
'until' => $this->until
|
||||
])
|
||||
);
|
||||
$sql = db()->syntax_upsert($data, _tbl('variables'), $sql_params, 'variable_name', ['id'], true);
|
||||
|
||||
return (0 < db()->command($sql, $sql_params));
|
||||
}
|
||||
|
||||
|
||||
// Gets the message text
|
||||
public function getText() : string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
|
||||
public function getEscapedText() : string
|
||||
{
|
||||
global $message_allowed_tags;
|
||||
|
||||
if (empty($message_allowed_tags))
|
||||
{
|
||||
return escape_html($this->text);
|
||||
}
|
||||
|
||||
return self::stripTags($this->text, $message_allowed_tags);
|
||||
}
|
||||
|
||||
// Gets the message end date
|
||||
public function getFromDate() : string
|
||||
{
|
||||
if ($this->from === '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
if (false === ($date = DateTime::createFromFormat(self::FORMAT_DATETIME, $this->from)))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return $date->format(self::FORMAT_DATE);
|
||||
}
|
||||
|
||||
|
||||
// Gets the message end date
|
||||
public function getUntilDate() : string
|
||||
{
|
||||
if ($this->until === '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
if (false === ($date = DateTime::createFromFormat(self::FORMAT_DATETIME, $this->until)))
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
return $date->modify('-1 day')->format(self::FORMAT_DATE);
|
||||
}
|
||||
|
||||
|
||||
// Gets the message start timestamp
|
||||
public function getFromTimestamp() : ?int
|
||||
{
|
||||
if ($this->from === '')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (false === ($date = DateTime::createFromFormat(self::FORMAT_DATETIME, $this->from)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $date->getTimestamp();
|
||||
}
|
||||
|
||||
|
||||
// Gets the message end timestamp
|
||||
public function getUntilTimestamp() : ?int
|
||||
{
|
||||
if ($this->until === '')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (false === ($date = DateTime::createFromFormat(self::FORMAT_DATETIME, $this->until)))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $date->getTimestamp();
|
||||
}
|
||||
|
||||
|
||||
// Get the message start time as a string in the user's locale
|
||||
public function getFromLocalString() : ?string
|
||||
{
|
||||
global $datetime_formats;
|
||||
|
||||
$timestamp = $this->getFromTimestamp();
|
||||
|
||||
if (!isset($timestamp))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return datetime_format($datetime_formats['date_and_time'], $timestamp);
|
||||
}
|
||||
|
||||
|
||||
// Get the message end time as a string in the user's locale
|
||||
public function getUntilLocalString() : ?string
|
||||
{
|
||||
global $datetime_formats;
|
||||
|
||||
$timestamp = $this->getUntilTimestamp();
|
||||
|
||||
if (!isset($timestamp))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return datetime_format($datetime_formats['date_and_time'], $timestamp);
|
||||
}
|
||||
|
||||
|
||||
// Sets the message text
|
||||
public function setText(string $text) : void
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
|
||||
// Sets the message end date
|
||||
public function setFromDate(string $from_date) : void
|
||||
{
|
||||
if ($from_date !== '')
|
||||
{
|
||||
// Set the date to the beginning of the day and save it with a time.
|
||||
// This allows a time to be added to the form in the future.
|
||||
// Note that the time is without timezone, so will be the time in the
|
||||
// timezone of the area that the message will be displayed in.
|
||||
$date = DateTime::createFromFormat(self::FORMAT_DATE, $from_date);
|
||||
if ($date === false)
|
||||
{
|
||||
trigger_error("Could not create date from '$from_date'; expecting format '" . self::FORMAT_DATE . "'.", E_USER_WARNING);
|
||||
$this->setFrom('');
|
||||
}
|
||||
else
|
||||
{
|
||||
$date->setTime(0, 0);
|
||||
$this->setFrom($date->format(self::FORMAT_DATETIME));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sets the message end date
|
||||
public function setUntilDate(string $until_date) : void
|
||||
{
|
||||
if ($until_date !== '')
|
||||
{
|
||||
// Set the date to the beginning of the next day and save it with a time.
|
||||
// This allows a time to be added to the form in the future.
|
||||
// Note that the time is without timezone, so will be the time in the
|
||||
// timezone of the area that the message will be displayed in.
|
||||
$date = DateTime::createFromFormat(self::FORMAT_DATE, $until_date);
|
||||
if ($date === false)
|
||||
{
|
||||
trigger_error("Could not create date from '$until_date'; expecting format '" . self::FORMAT_DATE . "'.", E_USER_WARNING);
|
||||
$this->setUntil('');
|
||||
}
|
||||
else
|
||||
{
|
||||
$date->setTime(0, 0)->modify('+1 day');
|
||||
$this->setUntil($date->format(self::FORMAT_DATETIME));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Determines whether there is a message that should be displayed, ie
|
||||
// the message exists and the expiry date hasn't passed.
|
||||
public function hasSomethingToDisplay() : bool
|
||||
{
|
||||
$text = $this->getText();
|
||||
|
||||
if ($text === '')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$from_timestamp = $this->getFromTimestamp();
|
||||
$until_timestamp = $this->getUntilTimestamp();
|
||||
|
||||
// Check to see whether we're in the time interval in which to display the message
|
||||
return ((!isset($from_timestamp) || (time() >= $from_timestamp)) &&
|
||||
(!isset($until_timestamp) || (time() < $until_timestamp)));
|
||||
}
|
||||
|
||||
|
||||
private function setFrom(string $date_time_string) : void
|
||||
{
|
||||
$this->from = $date_time_string;
|
||||
}
|
||||
|
||||
|
||||
private function setUntil(string $date_time_string) : void
|
||||
{
|
||||
$this->until = $date_time_string;
|
||||
}
|
||||
|
||||
|
||||
// Wrapper for PHP's strip_tags() function which converts $allowed tags to a string
|
||||
// if PHP < 7.4.0
|
||||
private static function stripTags(string $string, array $allowed_tags) : string
|
||||
{
|
||||
assert(version_compare(MRBS_MIN_PHP_VERSION, '7.4.0', '<'), "This method is now redundant.");
|
||||
|
||||
if (version_compare(PHP_VERSION, '7.4.0', '>='))
|
||||
{
|
||||
return strip_tags($string, $allowed_tags);
|
||||
}
|
||||
|
||||
$tag_string = '';
|
||||
foreach ($allowed_tags as $tag)
|
||||
{
|
||||
$tag_string .= "<$tag>";
|
||||
}
|
||||
|
||||
return strip_tags($string, $tag_string);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user