提交api控制器

This commit is contained in:
焦钰锟 2025-03-26 18:08:58 +08:00
parent d0a89dd141
commit 40abf15a0a
12 changed files with 417 additions and 18 deletions

View File

@ -27,6 +27,7 @@ class Admin extends Backend
protected $selectpageFields = 'id,username,nickname,avatar';
protected $searchFields = 'id,username,nickname';
protected $childrenGroupIds = [];
protected $childrenApiGroupIds = [];
protected $childrenAdminIds = [];
public function _initialize()
@ -36,6 +37,9 @@ class Admin extends Backend
$this->childrenAdminIds = $this->auth->getChildrenAdminIds($this->auth->isSuperAdmin());
$this->childrenGroupIds = $this->auth->getChildrenGroupIds($this->auth->isSuperAdmin());
// var_dump($this->childrenGroupIds);
$groupList = collection(AuthGroup::where('id', 'in', $this->childrenGroupIds)->select())->toArray();
@ -61,6 +65,39 @@ class Admin extends Backend
}
$this->view->assign('groupdata', $groupdata);
$this->childrenApiGroupIds = $this->auth->getChildrenApiGroupIds($this->auth->isSuperAdmin());
// var_dump($this->childrenApiGroupIds);
$groupList = collection(\app\admin\model\api\AuthGroup::where('id', 'in', $this->childrenApiGroupIds)->select())->toArray();
Tree::instance()->init($groupList);
$groupdata = [];
if ($this->auth->isSuperAdmin()) {
$result = Tree::instance()->getTreeList(Tree::instance()->getTreeArray(0));
foreach ($result as $k => $v) {
$groupdata[$v['id']] = $v['name'];
}
} else {
$result = [];
$groups = $this->auth->getGroups();
foreach ($groups as $m => $n) {
$childlist = Tree::instance()->getTreeList(Tree::instance()->getTreeArray($n['id']));
$temp = [];
foreach ($childlist as $k => $v) {
$temp[$v['id']] = $v['name'];
}
$result[__($n['name'])] = $temp;
}
$groupdata = $result;
}
$this->view->assign('apigroupdata', $groupdata);
$this->assignconfig("admin", ['id' => $this->auth->id]);
$this->getCity();
@ -141,6 +178,7 @@ class Admin extends Backend
exception($this->model->getError());
}
$group = $this->request->post("group/a");
$apigroup = $this->request->post("apigroup/a");
//过滤不允许的组别,避免越权
$group = array_intersect($this->childrenGroupIds, $group);
@ -148,11 +186,27 @@ class Admin extends Backend
exception(__('The parent group exceeds permission limit'));
}
$apigroup = array_intersect($this->childrenApiGroupIds, $group);
if (!$apigroup) {
exception(__('The parent group exceeds permission limit'));
}
$dataset = [];
foreach ($group as $value) {
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
}
model('AuthGroupAccess')->saveAll($dataset);
$dataset = [];
foreach ($apigroup as $value) {
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
}
(new \app\admin\model\api\AuthGroupAccess())->saveAll($dataset);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
@ -207,8 +261,10 @@ class Admin extends Backend
// 先移除所有权限
model('AuthGroupAccess')->where('uid', $row->id)->delete();
\app\admin\model\api\AuthGroupAccess::where('uid', $row->id)->delete();
$group = $this->request->post("group/a");
$apigroup = $this->request->post("apigroup/a");
// 过滤不允许的组别,避免越权
$group = array_intersect($this->childrenGroupIds, $group);
@ -216,11 +272,25 @@ class Admin extends Backend
exception(__('The parent group exceeds permission limit'));
}
$apigroup = array_intersect($this->childrenApiGroupIds, $group);
if (!$apigroup) {
exception(__('The parent group exceeds permission limit'));
}
$dataset = [];
foreach ($group as $value) {
$dataset[] = ['uid' => $row->id, 'group_id' => $value];
}
model('AuthGroupAccess')->saveAll($dataset);
$dataset = [];
foreach ($apigroup as $value) {
$dataset[] = ['uid' => $this->model->id, 'group_id' => $value];
}
(new \app\admin\model\api\AuthGroupAccess())->saveAll($dataset);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
@ -237,6 +307,16 @@ class Admin extends Backend
}
$this->view->assign("row", $row);
$this->view->assign("groupids", $groupids);
$grouplist = $this->auth->getApiGroups($row['id']);
$groupids = [];
foreach ($grouplist as $k => $v) {
$groupids[] = $v['id'];
}
// $this->view->assign("row", $row);
$this->view->assign("apigroupids", $groupids);
return $this->view->fetch();
}

View File

@ -3,7 +3,7 @@
namespace app\admin\controller\auth\api;
use addons\csmtable\library\xcore\xcore\utils\XcAdminSessionUtils;
use app\admin\model\AuthGroup;
use app\admin\model\api\AuthGroup;
use app\common\controller\Backend;
/**
@ -16,7 +16,7 @@ class Adminlog extends Backend
{
/**
* @var \app\admin\model\AdminLog
* @var \app\admin\model\api\AdminLog
*/
protected $model = null;
protected $childrenGroupIds = [];
@ -25,7 +25,7 @@ class Adminlog extends Backend
public function _initialize()
{
parent::_initialize();
$this->model = model('AdminLog');
$this->model = new \app\admin\model\api\AdminLog;
$this->childrenAdminIds = $this->auth->getChildrenAdminIds(true);
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);

View File

@ -2,7 +2,9 @@
namespace app\admin\controller\auth\api;
use app\admin\model\AuthGroup;
use app\admin\model\api\AuthGroup;
use app\admin\model\api\AuthGroupAccess;
use app\admin\model\api\AuthRule;
use app\common\controller\Backend;
use fast\Tree;
use think\Db;
@ -18,7 +20,7 @@ class Group extends Backend
{
/**
* @var \app\admin\model\AuthGroup
* @var \app\admin\model\api\AuthGroup
*/
protected $model = null;
//当前登录管理员所有子组别
@ -32,7 +34,7 @@ class Group extends Backend
public function _initialize()
{
parent::_initialize();
$this->model = model('AuthGroup');
$this->model = new AuthGroup;
$this->childrenGroupIds = $this->auth->getChildrenGroupIds(true);
@ -94,7 +96,7 @@ class Group extends Backend
if (!in_array($params['pid'], $this->childrenGroupIds)) {
$this->error(__('The parent group exceeds permission limit'));
}
$parentmodel = model("AuthGroup")->get($params['pid']);
$parentmodel = (new AuthGroup)->get($params['pid']);
if (!$parentmodel) {
$this->error(__('The parent group can not found'));
}
@ -142,7 +144,7 @@ class Group extends Backend
}
$params['rules'] = explode(',', $params['rules']);
$parentmodel = model("AuthGroup")->get($params['pid']);
$parentmodel = (new AuthGroup)->get($params['pid']);
if (!$parentmodel) {
$this->error(__('The parent group can not found'));
}
@ -160,13 +162,13 @@ class Group extends Backend
Db::startTrans();
try {
$row->save($params);
$children_auth_groups = model("AuthGroup")->all(['id' => ['in', implode(',', (Tree::instance()->getChildrenIds($row->id)))]]);
$children_auth_groups = (new AuthGroup)->all(['id' => ['in', implode(',', (Tree::instance()->getChildrenIds($row->id)))]]);
$childparams = [];
foreach ($children_auth_groups as $key => $children_auth_group) {
$childparams[$key]['id'] = $children_auth_group->id;
$childparams[$key]['rules'] = implode(',', array_intersect(explode(',', $children_auth_group->rules), $rules));
}
model("AuthGroup")->saveAll($childparams);
(new AuthGroup)->saveAll($childparams);
Db::commit();
$this->success();
} catch (Exception $e) {
@ -201,7 +203,7 @@ class Group extends Backend
// 循环判断每一个组别是否可删除
$grouplist = $this->model->where('id', 'in', $ids)->select();
$groupaccessmodel = model('AuthGroupAccess');
$groupaccessmodel = new AuthGroupAccess();
foreach ($grouplist as $k => $v) {
// 当前组别下有管理员
$groupone = $groupaccessmodel->get(['group_id' => $v['id']]);
@ -246,7 +248,7 @@ class Group extends Backend
{
$this->loadlang('auth/group');
$model = model('AuthGroup');
$model = (new AuthGroup);
$id = $this->request->post("id");
$pid = $this->request->post("pid");
$parentGroupModel = $model->get($pid);
@ -256,7 +258,7 @@ class Group extends Backend
}
if (($pid || $parentGroupModel) && (!$id || $currentGroupModel)) {
$id = $id ? $id : null;
$ruleList = collection(model('AuthRule')->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
$ruleList = collection((new AuthRule())->order('weigh', 'desc')->order('id', 'asc')->select())->toArray();
//读取父类角色所有节点列表
$parentRuleList = [];
if (in_array('*', explode(',', $parentGroupModel->rules))) {
@ -275,7 +277,7 @@ class Group extends Backend
//当前所有正常规则列表
$ruleTree->init($parentRuleList);
//角色组列表
$groupTree->init(collection(model('AuthGroup')->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
$groupTree->init(collection((new AuthGroup)->where('id', 'in', $this->childrenGroupIds)->select())->toArray());
//读取当前角色下规则ID集合
$adminRuleIds = $this->auth->getRuleIds();

View File

@ -2,7 +2,7 @@
namespace app\admin\controller\auth\api;
use app\admin\model\AuthRule;
use app\admin\model\api\AuthRule;
use app\common\controller\Backend;
use fast\Tree;
use think\Cache;
@ -17,7 +17,7 @@ class Rule extends Backend
{
/**
* @var \app\admin\model\AuthRule
* @var \app\admin\model\api\AuthRule
*/
protected $model = null;
protected $rulelist = [];
@ -29,9 +29,9 @@ class Rule extends Backend
if (!$this->auth->isSuperAdmin()) {
$this->error(__('Access is allowed only to the super management group'));
}
$this->model = model('AuthRule');
$this->model = new AuthRule;
// 必须将结果集转换为数组
$ruleList = \think\Db::name("auth_rule")->field('type,condition,remark,createtime,updatetime', true)->order('weigh DESC,id ASC')->select();
$ruleList = \think\Db::name("api_auth_rule")->field('type,condition,remark,createtime,updatetime', true)->order('weigh DESC,id ASC')->select();
foreach ($ruleList as $k => &$v) {
$v['title'] = __($v['title']);
}

View File

@ -279,6 +279,13 @@ class Auth extends \fast\Auth
return parent::getGroups($uid);
}
public function getApiGroups($uid = null)
{
$uid = is_null($uid) ? $this->id : $uid;
// var_dump($uid);
return parent::getApiGroups($uid);
}
public function getRuleList($uid = null)
{
$uid = is_null($uid) ? $this->id : $uid;
@ -580,4 +587,54 @@ class Auth extends \fast\Auth
{
return $this->_error ? __($this->_error) : '';
}
/**
* 取出当前管理员所拥有api权限的分组
* @param boolean $withself 是否包含当前所在的分组
* @return array
*/
public function getChildrenApiGroupIds($withself = false)
{
//取出当前管理员所有的分组
$groups = $this->getApiGroups();
// var_dump($groups);
$groupIds = [];
foreach ($groups as $k => $v) {
$groupIds[] = $v['id'];
}
$originGroupIds = $groupIds;
foreach ($groups as $k => $v) {
if (in_array($v['pid'], $originGroupIds)) {
$groupIds = array_diff($groupIds, [$v['id']]);
unset($groups[$k]);
}
}
// 取出所有分组
$groupList = \app\admin\model\api\AuthGroup::where($this->isSuperAdmin() ? '1=1' : ['status' => 'normal'])->select();
$objList = [];
foreach ($groups as $k => $v) {
if ($v['rules'] === '*') {
$objList = $groupList;
break;
}
// 取出包含自己的所有子节点
$childrenList = Tree::instance()->init($groupList, 'pid')->getChildren($v['id'], true);
$obj = Tree::instance()->init($childrenList, 'pid')->getTreeArray($v['pid']);
$objList = array_merge($objList, Tree::instance()->getTreeList($obj));
}
$childrenGroupIds = [];
foreach ($objList as $k => $v) {
$childrenGroupIds[] = $v['id'];
}
if (!$withself) {
$childrenGroupIds = array_diff($childrenGroupIds, $groupIds);
}
return $childrenGroupIds;
}
}

View File

@ -0,0 +1,119 @@
<?php
namespace app\admin\model\api;
use app\admin\library\Auth;
use think\Model;
use think\Loader;
class AdminLog extends Model
{
protected $name = 'admin_api_log';
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = '';
//自定义日志标题
protected static $title = '';
//自定义日志内容
protected static $content = '';
//忽略的链接正则列表
protected static $ignoreRegex = [
'/^(.*)\/(selectpage|index)$/i',
];
public static function setTitle($title)
{
self::$title = $title;
}
public static function setContent($content)
{
self::$content = $content;
}
public static function setIgnoreRegex($regex = [])
{
$regex = is_array($regex) ? $regex : [$regex];
self::$ignoreRegex = array_merge(self::$ignoreRegex, $regex);
}
/**
* 记录日志
* @param string $title 日志标题
* @param string $content 日志内容
*/
public static function record($title = '', $content = '')
{
$auth = Auth::instance();
$admin_id = $auth->isLogin() ? $auth->id : 0;
$username = $auth->isLogin() ? $auth->username : __('Unknown');
// 设置过滤函数
request()->filter('trim,strip_tags,htmlspecialchars');
$controllername = Loader::parseName(request()->controller());
$actionname = strtolower(request()->action());
$path = str_replace('.', '/', $controllername) . '/' . $actionname;
if (self::$ignoreRegex) {
foreach (self::$ignoreRegex as $index => $item) {
if (preg_match($item, $path)) {
return;
}
}
}
$content = $content ?: self::$content;
if (!$content) {
$content = request()->param('') ?: file_get_contents("php://input");
$content = self::getPureContent($content);
}
$title = $title ?: self::$title;
if (!$title) {
$title = [];
$breadcrumb = Auth::instance()->getBreadcrumb($path);
foreach ($breadcrumb as $k => $v) {
$title[] = $v['title'];
}
$title = implode(' / ', $title);
}
self::create([
'title' => $title,
'content' => !is_scalar($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content,
'url' => substr(xss_clean(strip_tags(request()->url())), 0, 1500),
'admin_id' => $admin_id,
'username' => $username,
'useragent' => substr(request()->server('HTTP_USER_AGENT'), 0, 255),
'ip' => xss_clean(strip_tags(request()->ip()))
]);
}
/**
* 获取已屏蔽关键信息的数据
* @param $content
* @return array
*/
protected static function getPureContent($content)
{
if (!is_array($content)) {
return $content;
}
foreach ($content as $index => &$item) {
if (preg_match("/(password|salt|token)/i", $index)) {
$item = "***";
} else {
if (is_array($item)) {
$item = self::getPureContent($item);
}
}
}
return $content;
}
public function admin()
{
return $this->belongsTo('Admin', 'admin_id')->setEagerlyType(0);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace app\admin\model\api;
use think\Model;
class AuthGroup extends Model
{
protected $name = 'api_auth_group';
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
public function getNameAttr($value, $data)
{
return __($value);
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace app\admin\model\api;
use think\Model;
class AuthGroupAccess extends Model
{
//
protected $name = 'api_auth_group_access';
}

View File

@ -0,0 +1,63 @@
<?php
namespace app\admin\model\api;
use think\Cache;
use think\Model;
class AuthRule extends Model
{
protected $name = 'api_auth_rule';
// 开启自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
// 数据自动完成字段
protected $insert = ['py', 'pinyin'];
protected $update = ['py', 'pinyin'];
// 拼音对象
protected static $pinyin = null;
protected static function init()
{
self::$pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
self::beforeWrite(function ($row) {
if (isset($_POST['row']) && is_array($_POST['row']) && isset($_POST['row']['condition'])) {
$originRow = $_POST['row'];
$row['condition'] = $originRow['condition'] ?? '';
}
});
self::afterWrite(function ($row) {
Cache::rm('__menu__');
});
}
public function getTitleAttr($value, $data)
{
return __($value);
}
public function getMenutypeList()
{
return ['addtabs' => __('Addtabs'), 'dialog' => __('Dialog'), 'ajax' => __('Ajax'), 'blank' => __('Blank')];
}
public function setPyAttr($value, $data)
{
if (isset($data['title']) && $data['title']) {
return self::$pinyin->abbr(__($data['title']));
}
return '';
}
public function setPinyinAttr($value, $data)
{
if (isset($data['title']) && $data['title']) {
return self::$pinyin->permalink(__($data['title']), '');
}
return '';
}
}

View File

@ -6,6 +6,15 @@
{:build_select('group[]', $groupdata, null, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('API权限组')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_select('apigroup[]', $apigroupdata, null, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
</div>
</div>
<div class="form-group">
<label for="username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
<div class="col-xs-12 col-sm-8">

View File

@ -6,6 +6,16 @@
{:build_select('group[]', $groupdata, $groupids, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('API权限组')}:</label>
<div class="col-xs-12 col-sm-8">
{:build_select('apigroup[]', $apigroupdata, $apigroupids, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
</div>
</div>
<div class="form-group">
<label for="username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
<div class="col-xs-12 col-sm-8">

View File

@ -263,4 +263,30 @@ class Auth
return $user_info[$uid];
}
/**
* 根据用户id获取Api用户组,返回值为数组
* @param int $uid 用户id
* @return array 用户所属的用户组 array(
* array('uid'=>'用户id','group_id'=>'用户组id','name'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
* ...)
*/
public function getApiGroups($uid)
{
static $groups = [];
if (isset($groups[$uid])) {
return $groups[$uid];
}
// 执行查询
$user_groups = Db::name('api_auth_group_access')
->alias('aga')
->join('__' . strtoupper("api_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='normal'")
->select();
$groups[$uid] = $user_groups ?: [];
return $groups[$uid];
}
}