<?php
/**
* +----------------------------------------------------------------------
* | TickyPHP [ This is a freeware ]
* +----------------------------------------------------------------------
* | Copyright (c) 2015 All rights reserved.
* +----------------------------------------------------------------------
* | Author: luomingui <e-mail:minguiluo@163.com> <QQ:271391233>
* | SVN: $Id: Auth.php 29529 2018-2-12 luomingui $
* +----------------------------------------------------------------------
* | Description:权限认证类
* $auth=new Auth();
* $auth->check('规则名称','用户id')
* +----------------------------------------------------------------------
*/
namespace ticky;
use ticky\config;
class autht {
protected $config = array(
'AUTH_ON' => true, 'AUTH_TYPE' => 1, 'AUTH_GROUP' => 'auth_role', 'AUTH_GROUP_ACCESS' => 'auth_role_member', 'AUTH_RULE' => 'auth_rule', 'AUTH_USER' => 'member' );
protected $prefix;
public function __construct() {
$config = config::get('db');
$driver = $config['driver'];
$config = $config[$driver];
$this->prefix = $config['prefix'];
$this->config['AUTH_GROUP'] = $this->prefix . $this->config['AUTH_GROUP'];
$this->config['AUTH_RULE'] = $this->prefix . $this->config['AUTH_RULE'];
$this->config['AUTH_USER'] = $this->prefix . $this->config['AUTH_USER'];
$this->config['AUTH_GROUP_ACCESS'] = $this->prefix . $this->config['AUTH_GROUP_ACCESS'];
}
public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or') {
$authList = $this->getAuthList($uid, $type); if (is_string($name)) {
$name = strtolower($name);
if (strpos($name, ',') !== false) {
$name = explode(',', $name);
} else {
$name = array($name);
}
}
$list = array(); 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;
}
protected function getAuthList($uid, $type) {
static $_authList = array(); $t = implode(',', (array) $type);
if (isset($_authList[$uid . $t])) {
return $_authList[$uid . $t];
}
if ($this->config['AUTH_TYPE'] == 2 && isset($_SESSION['_AUTH_LIST_' . $uid . $t])) {
return $_SESSION['_AUTH_LIST_' . $uid . $t];
}
$groups = $this->getGroups($uid);
$ids = array(); foreach ($groups as $g) {
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
}
$ids = array_unique($ids);
if (empty($ids)) {
$_authList[$uid . $t] = array();
return array();
}
$map = array(
'ruleid' => array('in', $ids),
'type' => $type,
'status' => 1,
);
$rules = db($this->config['AUTH_RULE'])->where($map)->field('regex,name')->select();
$authList = array(); foreach ($rules as $rule) {
if (!empty($rule['condition'])) { $user = $this->getUserInfo($uid);
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['regex']);
(eval('$condition=(' . $command . ');'));
if ($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);
}
public function getGroups($uid) {
static $groups = array();
if (isset($groups[$uid])) {
return $groups[$uid];
}
$user_groups = db($this->config['AUTH_GROUP_ACCESS'] . ' a')
->field('a.uid,a.roleid,g.title,g.rules')
->join($this->config['AUTH_GROUP'] . " g on a.roleid=g.roleid")
->where("a.uid='$uid' and g.status='1'")
->select();
$groups[$uid] = $user_groups ?: array();
return $groups[$uid];
}
protected function getUserInfo($uid) {
static $userinfo = array();
if (!isset($userinfo[$uid])) {
$userinfo[$uid] = db($this->config['AUTH_USER'])->where(['uid' => $uid])->field('regex,name')->find();
}
return $userinfo[$uid];
}
public function init_perm() {
$modules = array('admin'); $i = 0;
foreach ($modules as $module) {
$all_controller = $this->getController($module);
foreach ($all_controller as $controller) {
$all_action = $this->getAction($module, $controller);
if (isset($all_action)) {
foreach ($all_action as $action) {
$controller = str_replace('controller', '', $controller);
$data[$i]['module'] = $module;
$data[$i]['controller'] = $controller;
$data[$i]['action'] = $action;
if (!empty($module) && !empty($controller) && !empty($action)) {
$rule_name = $module . '-' . $controller . '-' . $action;
$rule = db($this->config['AUTH_RULE'])->where("name='" . strtolower($rule_name) . "'")->find();
if (!$rule) {
$idata = array();
$idata['module'] = strtolower($module . '-' . $controller);
$idata['type'] = "1";
$idata['name'] = strtolower($rule_name);
$idata['title'] = L(strtolower($rule_name));
$idata['regex'] = "";
$idata['status'] = "1";
db($this->config['AUTH_RULE'])->add($idata);
}
}
$i++;
}
}
}
}
return true;
}
private function getController($module) {
if (empty($module)) {
return null;
}
$module_path = APP_PATH . '/' . $module . '/controller/'; if (!is_dir($module_path)) {
return null;
}
$module_path .= '/*.php';
$ary_files = glob($module_path);
foreach ($ary_files as $file) {
if (is_dir($file)) {
continue;
} else {
$inherents_functions = array('auth', 'call', 'login', 'logout', 'index');
$filename = basename($file, '.php');
if (!in_array($filename, $inherents_functions)) {
$files[] = $filename;
}
}
}
return $files;
}
protected function getAction($module, $controller) {
if (empty($controller)) {
return null;
}
$file = APP_PATH . '/' . $module . '/controller/' . $controller . '.php';
if (file_exists($file)) {
$content = file_get_contents($file);
preg_match_all("/.*?public.*?function(.*?)\(.*?\)/i", $content, $matches);
$functions = $matches[1];
$inherents_functions = array('_initialize', '__construct', 'getActionName', 'isAjax', 'display', 'show', 'fetch', 'buildHtml', 'assign', '__set', 'get', '__get', '__isset', '__call', 'error', 'success', 'ajaxReturn', 'redirect', '__destruct', '_empty');
foreach ($functions as $func) {
$func = trim($func);
if (!in_array($func, $inherents_functions)) {
$customer_functions[] = $func;
}
}
return $customer_functions;
}
return null;
}
}