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:
人事系统开发
2026-09-09 16:55:02 +08:00
commit 1ba6efd8ed
2151 changed files with 528780 additions and 0 deletions
+168
View File
@@ -0,0 +1,168 @@
<?php
declare(strict_types=1);
namespace MRBS;
use Countable;
use Iterator;
// Holds information about table columns
// Implemented as a singleton class for performance reasons: it is
// expensive getting the field info in the constructor.
class Columns implements Countable, Iterator
{
private static $instances = array();
private $data;
private $index = 0;
private $table_name;
private function __construct($table_name)
{
assert(version_compare(MRBS_MIN_PHP_VERSION, '7.4.0', '<'), "The __wakeup() method is now redundant.");
$this->table_name = $table_name;
// Get the column info
$this->data = db()->field_info($table_name);
}
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 $table_name) : Columns
{
if (!isset(self::$instances[$table_name]))
{
self::$instances[$table_name] = new self($table_name);
}
return self::$instances[$table_name];
}
public function getNames() : array
{
$result = array();
foreach ($this as $column)
{
$result[] = $column->name;
}
return $result;
}
public function hasIdColumn() : bool
{
$column = $this->getColumnByName('id');
return isset($column);
}
public function getColumnByName(string $name) : ?Column
{
foreach ($this as $column)
{
if ($column->name == $name)
{
return $column;
}
}
return null;
}
public function current() : Column
{
$info = $this->data[$this->index];
$column = new Column($this->table_name, $info['name']);
$column->setLength($info['length']);
$column->setDefault($info['default']);
$column->setIsNullable($info['is_nullable']);
$column->setType($info['type']);
switch ($info['nature'])
{
case 'binary':
$column->setNature(Column::NATURE_BINARY);
break;
case 'boolean':
$column->setNature(Column::NATURE_BOOLEAN);
break;
case 'character':
$column->setNature(Column::NATURE_CHARACTER);
break;
case 'decimal':
$column->setNature(Column::NATURE_DECIMAL);
break;
case 'integer':
$column->setNature(Column::NATURE_INTEGER);
break;
case 'json':
$column->setNature(Column::NATURE_JSON);
break;
case 'real':
$column->setNature(Column::NATURE_REAL);
break;
case 'timestamp':
$column->setNature(Column::NATURE_TIMESTAMP);
break;
default:
throw new \Exception("Unknown nature '" . $info['nature'] . "'");
break;
}
return $column;
}
public function next() : void
{
$this->index++;
}
public function key() : int
{
return $this->index;
}
public function valid() : bool
{
return isset($this->data[$this->key()]);
}
public function rewind() : void
{
$this->index = 0;
}
public function count() : int
{
return count($this->data);
}
}