This commit is contained in:
2025-11-21 01:42:54 +08:00
parent ff026c6f32
commit f89196c73c
1953 changed files with 9 additions and 15246 deletions
+129
View File
@@ -0,0 +1,129 @@
<?php
namespace plugin\admin\api;
use plugin\admin\app\model\AdminRole;
use plugin\admin\app\model\AdminRule;
use support\exception\BusinessException;
use function admin;
/**
* 对外提供的鉴权接口
*/
class Auth
{
/**
* 判断权限
* 如果没有权限则抛出异常
* @param string $controller
* @param string $action
* @return void
* @throws \ReflectionException|BusinessException
*/
public static function access(string $controller, string $action)
{
$code = 0;
$msg = '';
if (!static::canAccess($controller, $action, $code, $msg)) {
throw new BusinessException($msg, $code);
}
}
/**
* 判断是否有权限
* @param string $controller
* @param string $action
* @param int $code
* @param string $msg
* @return bool
* @throws \ReflectionException|BusinessException
*/
public static function canAccess(string $controller, string $action, int &$code = 0, string &$msg = ''): bool
{
// 无控制器信息说明是函数调用,函数不属于任何控制器,鉴权操作应该在函数内部完成。
if (!$controller) {
return true;
}
// 获取控制器鉴权信息
$class = new \ReflectionClass($controller);
$properties = $class->getDefaultProperties();
$noNeedLogin = $properties['noNeedLogin'] ?? [];
$noNeedAuth = $properties['noNeedAuth'] ?? [];
// 不需要登录
if (in_array($action, $noNeedLogin)) {
return true;
}
// 获取登录信息
$admin = admin();
if (!$admin) {
$msg = '请登录';
// 401是未登录固定的返回码
$code = 401;
return false;
}
// 不需要鉴权
if (in_array($action, $noNeedAuth)) {
return true;
}
// 当前管理员无角色
$roles = $admin['roles'];
if (!$roles) {
$msg = '无权限';
$code = 2;
return false;
}
// 角色没有规则
$rules = AdminRole::whereIn('id', $roles)->column('rules');
$rule_ids = [];
foreach ($rules as $rule_string) {
if (!$rule_string) {
continue;
}
$rule_ids = array_merge($rule_ids, explode(',', $rule_string));
}
if (!$rule_ids) {
$msg = '无权限';
$code = 2;
return false;
}
// 超级管理员
if (in_array('*', $rule_ids)){
return true;
}
//cp($rule_ids);
// 如果action为index,规则里有任意一个以$controller开头的权限即可
if (strtolower($action) === 'index') {
$rule = AdminRule::where(function ($query) use ($controller, $action) {
$controller_like = str_replace('plugin\\admin\\', '', $controller);
$controller_like = str_replace('\\', '\\\\', $controller_like);
$query->where('key', 'like', "$controller_like@%")->whereOr('key', $controller);
})->whereIn('id', $rule_ids)->find();
if ($rule) {
return true;
}
$msg = '无权限';
$code = 2;
return false;
}
// 查询是否有当前控制器的规则
$rule = AdminRule::where(function ($query) use ($controller, $action) {
$controller_like = str_replace('plugin\\admin\\', '', $controller);
$query->where('key', "$controller_like@$action");
})->whereIn('id', $rule_ids)->find();
if (!$rule) {
$msg = '无权限';
$code = 2;
return false;
}
return true;
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
/**
* This file is part of webman.
*
* Licensed under The MIT License
* For full copyright and license information, please see the MIT-LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author walkor<walkor@workerman.net>
* @copyright walkor<walkor@workerman.net>
* @link http://www.workerman.net/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace plugin\admin\api;
use Illuminate\Database\Events\QueryExecuted;
use Workerman\Protocols\Http;
use Workerman\Protocols\Http\Session as SessionBase;
use Workerman\Worker;
use function config;
use function property_exists;
use support\think\Db;
/**
* Class Session
* @package support
*/
class Bootstrap implements \Webman\Bootstrap
{
/**
* @param Worker|null $worker
* @return void
*/
public static function start(?Worker $worker)
{
Db::connection()->listen(function (QueryExecuted $queryExecuted) {
var_dump("[{$queryExecuted->time} ms] {$queryExecuted->sql}");
});
}
}
+150
View File
@@ -0,0 +1,150 @@
<?php
namespace plugin\admin\api;
use plugin\admin\app\model\AdminRole;
use plugin\admin\app\model\AdminRule;
use support\exception\BusinessException;
use function admin;
/**
* 对外提供的菜单接口
*/
class Menu
{
/**
* 根据key获取菜单
* @param $key
* @return array
*/
public static function get($key)
{
$menu = AdminRule::where('key', $key)->find();
return $menu ? $menu->toArray() : null;
}
/**
* 根据id获得菜单
* @param $id
* @return array
*/
public static function find($id): array
{
return AdminRule::find($id)->toArray();
}
/**
* 添加菜单
* @param array $menu
* @return int
*/
public static function add(array $menu)
{
$item = new AdminRule;
foreach ($menu as $key => $value) {
$item->$key = $value;
}
$item->save();
return $item->id;
}
/**
* 导入菜单
* @param array $menu_tree
* @return void
*/
public static function import(array $menu_tree)
{
if (is_numeric(key($menu_tree)) && !isset($menu_tree['key'])) {
foreach ($menu_tree as $item) {
static::import($item);
}
return;
}
$children = $menu_tree['children'] ?? [];
unset($menu_tree['children']);
if ($old_menu = Menu::get($menu_tree['key'])) {
$pid = $old_menu['id'];
AdminRule::where('key', $menu_tree['key'])->update($menu_tree);
} else {
$pid = static::add($menu_tree);
}
foreach ($children as $menu) {
$menu['pid'] = $pid;
static::import($menu);
}
}
/**
* 删除菜单
* @param $key
* @return void
*/
public static function delete($key)
{
$item = AdminRule::where('key', $key)->find();
if (!$item) {
return;
}
// 子规则一起删除
$delete_ids = $children_ids = [$item['id']];
while($children_ids) {
$children_ids = AdminRule::whereIn('pid', $children_ids)->column('id');
$delete_ids = array_merge($delete_ids, $children_ids);
}
AdminRule::whereIn('id', $delete_ids)->delete();
}
/**
* 获取菜单中某个(些)字段的值
* @param $menu
* @param null $column
* @param null $index
* @return array|mixed
*/
public static function column($menu, $column = null, $index = null)
{
$values = [];
if (is_numeric(key($menu)) && !isset($menu['key'])) {
foreach ($menu as $item) {
$values = array_merge($values, static::column($item, $column, $index));
}
return $values;
}
$children = $menu['children'] ?? [];
unset($menu['children']);
if ($column === null) {
if ($index) {
$values[$menu[$index]] = $menu;
} else {
$values[] = $menu;
}
} else {
if (is_array($column)) {
$item = [];
foreach ($column as $f) {
$item[$f] = $menu[$f] ?? null;
}
if ($index) {
$values[$menu[$index]] = $item;
} else {
$values[] = $item;
}
} else {
$value = $menu[$column] ?? null;
if ($index) {
$values[$menu[$index]] = $value;
} else {
$values[] = $value;
}
}
}
foreach ($children as $child) {
$values = array_merge($values, static::column($child, $column, $index));
}
return $values;
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
namespace plugin\admin\api;
use ReflectionException;
use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
use support\exception\BusinessException;
/**
* 对外提供的鉴权中间件
*/
class Middleware implements MiddlewareInterface
{
/**
* 鉴权
* @param Request $request
* @param callable $handler
* @return Response
* @throws ReflectionException
* @throws BusinessException
*/
public function process(Request $request, callable $handler): Response
{
$controller = $request->controller;
$action = $request->action;
$code = 0;
$msg = '';
if (!Auth::canAccess($controller, $action, $code, $msg)) {
if ($request->expectsJson()) {
$response = json(['code' => $code, 'msg' => $msg, 'type' => 'error']);
} else {
if ($code === 401) {
$response = response(<<<EOF
<script>
if (self !== top) {
parent.location.reload();
}
</script>
EOF
);
} else {
$request->app = '';
$request->plugin = 'admin';
$response = view('common/403')->withStatus(403);
}
}
} else {
$response = $request->method() == 'OPTIONS' ? response('') : $handler($request);
}
return $response;
}
}