Files
dafuweng-buildadmin/dafuweng-webman/extend/ba/Auth.php
2026-03-07 19:42:22 +08:00

179 lines
5.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace ba;
use Throwable;
use support\think\Db;
/**
* 权限规则类Webman 迁移版)
*/
class Auth
{
protected array $config = [
'auth_group' => 'admin_group',
'auth_group_access' => 'admin_group_access',
'auth_rule' => 'admin_rule',
];
protected array $children = [];
public function __construct(array $config = [])
{
$this->config = array_merge($this->config, $config);
}
public function __get($name): mixed
{
return $this->config[$name] ?? null;
}
public function getMenus(int $uid): array
{
$this->children = [];
$originAuthRules = $this->getOriginAuthRules($uid);
foreach ($originAuthRules as $rule) {
$this->children[$rule['pid']][] = $rule;
}
if (!isset($this->children[0])) {
return [];
}
return $this->getChildren($this->children[0]);
}
private function getChildren(array $rules): array
{
foreach ($rules as $key => $rule) {
if (array_key_exists($rule['id'], $this->children)) {
$rules[$key]['children'] = $this->getChildren($this->children[$rule['id']]);
}
}
return $rules;
}
public function check(string $name, int $uid, string $relation = 'or', string $mode = 'url'): bool
{
$ruleList = $this->getRuleList($uid);
if (in_array('*', $ruleList)) {
return true;
}
if ($name) {
$name = strtolower($name);
$name = str_contains($name, ',') ? explode(',', $name) : [$name];
}
$list = [];
$requestParams = [];
if ($mode === 'url' && function_exists('request')) {
$req = request();
$requestParams = $req ? array_merge($req->get(), $req->post()) : [];
$requestParams = json_decode(strtolower(json_encode($requestParams, JSON_UNESCAPED_UNICODE)), true) ?? [];
}
foreach ($ruleList as $rule) {
$query = preg_replace('/^.+\?/U', '', $rule);
if ($mode === 'url' && $query !== $rule) {
parse_str($query, $param);
$intersect = array_intersect_assoc($requestParams, $param);
$rule = preg_replace('/\?.*$/U', '', $rule);
if (in_array($rule, $name) && $intersect == $param) {
$list[] = $rule;
}
} elseif (in_array($rule, $name)) {
$list[] = $rule;
}
}
if ($relation === 'or' && !empty($list)) {
return true;
}
$diff = array_diff($name, $list);
if ($relation === 'and' && empty($diff)) {
return true;
}
return false;
}
public function getRuleList(int $uid): array
{
$ids = $this->getRuleIds($uid);
if (empty($ids)) {
return [];
}
$originAuthRules = $this->getOriginAuthRules($uid);
$rules = [];
if (in_array('*', $ids)) {
$rules[] = '*';
}
foreach ($originAuthRules as $rule) {
$rules[$rule['id']] = strtolower($rule['name']);
}
return array_unique($rules);
}
public function getOriginAuthRules(int $uid): array
{
$ids = $this->getRuleIds($uid);
if (empty($ids)) {
return [];
}
$where = [['status', '=', '1']];
if (!in_array('*', $ids)) {
$where[] = ['id', 'in', $ids];
}
$rules = Db::name($this->config['auth_rule'])
->withoutField(['remark', 'status', 'weigh', 'update_time', 'create_time'])
->where($where)
->order('weigh desc,id asc')
->select()
->toArray();
foreach ($rules as $key => $rule) {
if (!empty($rule['keepalive'])) {
$rules[$key]['keepalive'] = $rule['name'];
}
}
return $rules;
}
public function getRuleIds(int $uid): array
{
$groups = $this->getGroups($uid);
$ids = [];
foreach ($groups as $g) {
$ids = array_merge($ids, explode(',', trim($g['rules'] ?? '', ',')));
}
return array_unique($ids);
}
public function getGroups(int $uid): array
{
$dbName = $this->config['auth_group_access'] ?: 'user';
if ($this->config['auth_group_access']) {
$userGroups = Db::name($dbName)
->alias('aga')
->join($this->config['auth_group'] . ' ag', 'aga.group_id = ag.id', 'LEFT')
->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules')
->where("aga.uid='$uid' and ag.status='1'")
->select()
->toArray();
} else {
$userGroups = Db::name($dbName)
->alias('u')
->join($this->config['auth_group'] . ' ag', 'u.group_id = ag.id', 'LEFT')
->field('u.id as uid,u.group_id,ag.id,ag.name,ag.rules')
->where("u.id='$uid' and ag.status='1'")
->select()
->toArray();
}
return $userGroups;
}
}