<?php

namespace app\admin\controller;
use think\Config;
use think\Session;
use think\Db;
class Auth {
protected $config = array(
'auth_on'=>true,
'auth_type'=>2,
'auth_group'=>'auth_group',
'auth_group_access'=>'auth_group_access',
'auth_rule'=>'auth_rule',
'auth_user'=>'auth_member'
);
public function __construct() {
if (Config::get('auth_config')) {
$this->config = array_merge($this->config,Config::get('auth_config'));
}
}
public function check($name,$uid,$type = 1,$mode = 'url',$relation = 'or') {
if (!$this->config['auth_on']) {
return true;
}
$authList = $this->getAuthList($uid,$type);
if (is_string($name)) {
$name = strtolower($name);
$name = strpos($name,',') !== false ?explode(',',$name) : [$name];
}
$list = [];
if ($mode == 'url') {
$REQUEST = unserialize(strtolower(serialize($_REQUEST)));
}
foreach ($authList as $auth) {
$query = preg_replace('/^.+\?/U','',$auth);
if ($mode == 'url'&&$query != $auth) {
parse_str($query,$param);
$intersect = array_intersect_assoc($REQUEST,$param);
$auth = preg_replace('/\?.*$/U','',$auth);
if (in_array($auth,$name) &&$intersect == $param) {
$list[] = $auth;
}
}else if (in_array($auth,$name)) {
$list[] = $auth;
}
}
if ($relation == 'or'and !empty($list)) {
return true;
}
$diff = array_diff($name,$list);
if ($relation == 'and'and empty($diff)) {
return true;
}
return false;
}
public function getGroups($uid) {
static $groups = [];
if (isset($groups[$uid])) {
return $groups[$uid];
}
$user_groups = Db::view($this->config['auth_group_access'],'uid,group_id')->view($this->config['auth_group'],'title,rules',"{$this->config['auth_group_access']}.group_id={$this->config['auth_group']}.id")
->where(['uid'=>$uid,'status'=>1])->select();
$groups[$uid] = $user_groups ?$user_groups : [];
return $groups[$uid];
}
protected function getAuthList($uid,$type) {
static $_authList = [];
$t = implode(',',(array) $type);
if (isset($_authList[$uid .$t])) {
return $_authList[$uid .$t];
}
if ($this->config['auth_type'] == 2 &&Session::has('_auth_list_'.$uid .$t)) {
return Session::get('_auth_list_'.$uid .$t);
}
$groups = $this->getGroups($uid);
$ids = [];
foreach ($groups as $g) {
$ids = array_merge($ids,explode(',',trim($g['rules'],',')));
}
$ids = array_unique($ids);
if (empty($ids)) {
$_authList[$uid .$t] = [];
return [];
}
$map = [
'id'=>['in',$ids],
'type'=>$type,
'status'=>1,
];
$rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,name')->select();
$authList = [];
foreach ($rules as $rule) {
if (!empty($rule['condition'])) {
$this->getUserInfo($uid);
$command = preg_replace('/\{(\w*?)\}/','$user[\'\\1\']',$rule['condition']);
@(eval('$condition=('.$command .');'));
$condition &&$authList[] = strtolower($rule['name']);
}else {
$authList[] = strtolower($rule['name']);
}
}
$_authList[$uid .$t] = $authList;
if ($this->config['auth_type'] == 2) {
$_SESSION['_auth_list_'.$uid .$t] = $authList;
}
return array_unique($authList);
}
protected function getUserInfo($uid) {
static $userinfo = [];
if (!isset($userinfo[$uid])) {
$userinfo[$uid] = Db::name($this->config['auth_user'])->where(['uid'=>$uid])->find();
}
return $userinfo[$uid];
}
}?>