﻿<?php
/////////////////////////////////////////////////////////////////////////////
//
// SpeedPHP - 蹇€熺殑涓枃PHP妗嗘灦
//
// Copyright (c) 2008 - 2009 SpeedPHP.com All rights reserved.
//
// 璁稿彲鍗忚璇锋煡鐪?http://www.speedphp.com/
//
/////////////////////////////////////////////////////////////////////////////

/**
 * 灏唒winput娉ㄥ唽鍒皊marty妯℃澘涓娇鐢?
 * 璇锋敞镒弑pAcl鏂囦欢骞堕潪镊姩锷犺浇锛屾墍浠ュ湪smarty涓娇鐢╬winput鍓嶏紝闇€瑕佸湪鎺у埗鍣ㄤ腑鐢╥mport("spAcl.php");鏉ヨ浇鍏ユ枃浠?
 *
 * 鍦╯marty涓彲浠ョ敤锛?{pwinput id=mypw add="class=pwform name=mypwname"}>鏉ョ敓鎴愯杈揿叆妗?
 */
spAddViewFunction('pwinput', array("spAcl", "smarty_pwinput"));


/**
 * 鍩轰簬缁勭殑鐢ㄦ埛鏉冮檺鍒ゆ柇链哄埗
 * 瑕佷娇鐢ㄨ鏉冮檺鎺у埗绋嫔簭锛岄渶瑕佸湪搴旗敤绋嫔簭閰岖疆涓仛浠ヤ笅閰岖疆锛?
 * 链夐檺鎺у埗镄勬儏鍐碉紝鍦ㄩ厤缃腑浣跨敤	'launch' => array( 'router_prefilter' => array( array('spAcl','mincheck'), ), )
 * 寮哄埗鎺у埗镄勬儏鍐碉紝鍦ㄩ厤缃腑浣跨敤	'launch' => array( 'router_prefilter' => array( array('spAcl','maxcheck'), ), )
 */
class spAcl
{
	/**
	 * 榛樿鏉冮檺妫€镆ョ殑澶勭悊绋嫔簭璁剧疆锛屽彲浠ユ槸鍑芥暟鍚嶆垨鏄暟缁勶纸array(绫诲悕,鏂规硶)镄勫舰寮忥级
	 */
	public $checker = array('spAclModel','check');
	
	/**
	 * 榛樿鎻愮ず镞犳潈闄愭彁绀猴紝鍙互鏄嚱鏁板悕鎴栨槸鏁扮粍锛坅rray(绫诲悕,鏂规硶)镄勫舰寮忥级
	 */
	public $prompt = array('spAcl','def_prompt');
	/**
	 * 鏋勯€犲嚱鏁帮紝璁剧疆鏉冮檺妫€镆ョ▼搴忎笌鎻愮ず绋嫔簭
	 */
	public function __construct()
	{	
		$params = spExt("spAcl");
		if( !empty($params["prompt"]) )$this->prompt = $params["prompt"];
		if( !empty($params["checker"]) )$this->checker = $params["checker"];
	}

	/**
	 * 銮峰彇褰揿墠浼氲瘽镄勭敤鎴锋爣璇?
	 */
	public function get()
	{
		return $_SESSION["SpAclSession"];
	}

	/**
	 * 寮哄埗鎺у埗镄勬镆ョ▼搴忥紝阃傜敤浜庡悗鍙般€傛棤鏉冮檺鎺у埗镄勯〉闱㈠潎涓嶈兘杩涘叆
	 */
	public function maxcheck()
	{
		$acl_handle = $this->check();
		if( 1 !== $acl_handle ){
			$this->prompt();
			return FALSE;
		}
		return TRUE;
	}

	/**
	 * 链夐檺镄勬潈闄愭带鍒讹紝阃傜敤浜庡墠鍙般€备粎鍦ㄦ潈闄愯〃澹版槑绂佹镄勯〉闱㈣捣浣灭敤锛屽叾浠栨棤澹版槑椤甸溃鍧囧彲杩涘叆
	 */
	public function mincheck()
	{
		$acl_handle = $this->check();
		if( 0 === $acl_handle ){
			$this->prompt();
			return FALSE;
		}
		return TRUE;
	}
	
	/**
	 * 浣跨敤绋嫔簭璋冨害鍣ㄨ繘琛屾镆ョ瓑澶勭悊
	 */
	private function check()
	{
		GLOBAL $__controller, $__action;
		$checker = $this->checker; $name = $this->get();

		if( is_array($checker) ){
			return spClass($checker[0])->{$checker[1]}($name, $__controller, $__action);
		}else{
			return call_user_func_array($checker, array($name, $__controller, $__action));
		}
	}
	/**
	 * 镞犳潈闄愭彁绀鸿烦杞?
	 */
	public function prompt()
	{
		$prompt = $this->prompt;
		if( is_array($prompt) ){
			return spClass($prompt[0])->{$prompt[1]}();
		}else{
			return call_user_func_array($prompt,array());
		}
	}
	
	/**
	 * 榛樿镄勬棤鏉冮檺鎻愮ず璺宠浆
	 */
	public function def_prompt()
	{
		$url = spUrl(); // 璺宠浆鍒伴椤碉紝鍦ㄥ己鍒舵潈闄愮殑鎯呭喌涓嬶紝璇峰皢璇ラ〉闱㈣缃垚鍙互杩涘叆銆?
		echo "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><script>function sptips(){alert(\"Access Failed!\");location.href=\"{$url}\";}</script></head><body onload=\"sptips()\"></body></html>";
		exit;
	}

	/**
	 * 璁剧疆褰揿墠鐢ㄦ埛锛屽唴閮ㄤ娇鐢⊿ESSION璁板綍
	 * 
	 * @param acl_name    鐢ㄦ埛镙囱瘑锛氩彲浠ユ槸缁勫悕鎴栫敤鎴峰悕
	 */
	public function set($acl_name)
	{
		$_SESSION["SpAclSession"] = $acl_name;
	}
	
	/**
	 * 銮峰彇瀹夊叏锷犲瘑镄勫瘑镰佽緭鍏ユ锛屽紑鍙戣€呭皢闇€瑕佸湪HTML涓璮orm镙囩涓婂姞鍏?code>onsubmit="aclcode();"</code>鏉ヨЕ鍙戝姞瀵?
	 *
	 * @param id    鍦╥nput妗嗙殑id链笺€?
	 * @param add    鍦╥nput妗嗗唴镄勫叾浠栧唴瀹癸紝闄d澶栵紝name锛宑lass绛夊潎鍙€?
	 */
	public function pwinput($id, $add = null)
	{
		$raphash = substr(md5(mt_rand(10000,99999)),2,12);
		$html = "<script type='text/javascript'>".spAcl::getmd5()."</script>";
		$html .= "<script type='text/javascript'>function aclcode(){aclpwinput=document.getElementById('{$id}');document.getElementById('{$raphash}').value = hex_md5(aclpwinput.value);aclpwinput.value = '0000000000000000';}</script>";
		$html .= "<input type='password' id='{$id}' {$add}>";
		$html .= "<input type='hidden' id='{$raphash}' name='{$raphash}'>";
		$_SESSION["SpAclInputHash"] = $raphash;
		return $html;		
	}
	/**
	 * 杈呭侄pwinput镄勫嚱鏁帮紝璁﹑winput鍙湪妯℃澘涓娇鐢ㄣ€?
	 * @param params 浼犲叆镄勫弬鏁?
	 */
	public function smarty_pwinput($params){
		return spAcl::pwinput($params["id"],$params["add"]);
	}
	/**
	 * 銮峰彇锷犲瘑鍚庣殑瀵嗙爜锛岃瀵嗙爜涓篗D5锷犲瘑鍚庣殑瀛楃涓?
	 *
	 * 璇锋敞镒忚繑锲炲€硷细
	 *
	 * -1 鏄棤hash链硷紝鍙互鍒ゆ柇涓鸿繙绋嬫彁浜ょ瓑鏂瑰纺镄勬敾鍑绘垨鏄闂秴镞躲€傞渶瑕侀吨鏂拌闂橱褰曢〉闱€?
	 * false 鏄病链夎緭鍏ュ瘑镰侊紝鎴栨槸杩灭▼鎻愪氦瀵艰嚧镞犳硶銮峰彇鍒版纭殑hash镰并€傚悓镙疯姹傞吨鏂拌闂橱褰曢〉闱互鍐嶆杈揿叆瀵嗙爜鎻愪氦銆?
	 * MD5缂栫爜鍚庣殑瀵嗙爜
	 */
	public function pwvalue()
	{
		if(empty($_SESSION["SpAclInputHash"]))return -1;
		$md5pw = spClass("spArgs")->get($_SESSION["SpAclInputHash"],false);
		unset($_SESSION["SpAclInputHash"]);
		return $md5pw;
	}
	/**
	 * MD5镄凧S鎻愪緵
	 */
	private function getmd5(){
		return <<<EOF
var hexcase=0;function hex_md5(a){return rstr2hex(rstr_md5(str2rstr_utf8(a)))}function hex_hmac_md5(a,b){return rstr2hex(rstr_hmac_md5(str2rstr_utf8(a),str2rstr_utf8(b)))}function md5_vm_test(){return hex_md5("abc").toLowerCase()=="900150983cd24fb0d6963f7d28e17f72"}function rstr_md5(a){return binl2rstr(binl_md5(rstr2binl(a),a.length*8))}function rstr_hmac_md5(c,f){var e=rstr2binl(c);if(e.length>16){e=binl_md5(e,c.length*8)}var a=Array(16),d=Array(16);for(var b=0;b<16;b++){a[b]=e[b]^909522486;d[b]=e[b]^1549556828}var g=binl_md5(a.concat(rstr2binl(f)),512+f.length*8);return binl2rstr(binl_md5(d.concat(g),512+128))}function rstr2hex(c){try{hexcase}catch(g){hexcase=0}var f=hexcase?"0123456789ABCDEF":"0123456789abcdef";var b="";var a;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);b+=f.charAt((a>>>4)&15)+f.charAt(a&15)}return b}function str2rstr_utf8(c){var b="";var d=-1;var a,e;while(++d<c.length){a=c.charCodeAt(d);e=d+1<c.length?c.charCodeAt(d+1):0;if(55296<=a&&a<=56319&&56320<=e&&e<=57343){a=65536+((a&1023)<<10)+(e&1023);d++}if(a<=127){b+=String.fromCharCode(a)}else{if(a<=2047){b+=String.fromCharCode(192|((a>>>6)&31),128|(a&63))}else{if(a<=65535){b+=String.fromCharCode(224|((a>>>12)&15),128|((a>>>6)&63),128|(a&63))}else{if(a<=2097151){b+=String.fromCharCode(240|((a>>>18)&7),128|((a>>>12)&63),128|((a>>>6)&63),128|(a&63))}}}}}return b}function rstr2binl(b){var a=Array(b.length>>2);for(var c=0;c<a.length;c++){a[c]=0}for(var c=0;c<b.length*8;c+=8){a[c>>5]|=(b.charCodeAt(c/8)&255)<<(c%32)}return a}function binl2rstr(b){var a="";for(var c=0;c<b.length*32;c+=8){a+=String.fromCharCode((b[c>>5]>>>(c%32))&255)}return a}function binl_md5(p,k){p[k>>5]|=128<<((k)%32);p[(((k+64)>>>9)<<4)+14]=k;var o=1732584193;var n=-271733879;var m=-1732584194;var l=271733878;for(var g=0;g<p.length;g+=16){var j=o;var h=n;var f=m;var e=l;o=md5_ff(o,n,m,l,p[g+0],7,-680876936);l=md5_ff(l,o,n,m,p[g+1],12,-389564586);m=md5_ff(m,l,o,n,p[g+2],17,606105819);n=md5_ff(n,m,l,o,p[g+3],22,-1044525330);o=md5_ff(o,n,m,l,p[g+4],7,-176418897);l=md5_ff(l,o,n,m,p[g+5],12,1200080426);m=md5_ff(m,l,o,n,p[g+6],17,-1473231341);n=md5_ff(n,m,l,o,p[g+7],22,-45705983);o=md5_ff(o,n,m,l,p[g+8],7,1770035416);l=md5_ff(l,o,n,m,p[g+9],12,-1958414417);m=md5_ff(m,l,o,n,p[g+10],17,-42063);n=md5_ff(n,m,l,o,p[g+11],22,-1990404162);o=md5_ff(o,n,m,l,p[g+12],7,1804603682);l=md5_ff(l,o,n,m,p[g+13],12,-40341101);m=md5_ff(m,l,o,n,p[g+14],17,-1502002290);n=md5_ff(n,m,l,o,p[g+15],22,1236535329);o=md5_gg(o,n,m,l,p[g+1],5,-165796510);l=md5_gg(l,o,n,m,p[g+6],9,-1069501632);m=md5_gg(m,l,o,n,p[g+11],14,643717713);n=md5_gg(n,m,l,o,p[g+0],20,-373897302);o=md5_gg(o,n,m,l,p[g+5],5,-701558691);l=md5_gg(l,o,n,m,p[g+10],9,38016083);m=md5_gg(m,l,o,n,p[g+15],14,-660478335);n=md5_gg(n,m,l,o,p[g+4],20,-405537848);o=md5_gg(o,n,m,l,p[g+9],5,568446438);l=md5_gg(l,o,n,m,p[g+14],9,-1019803690);m=md5_gg(m,l,o,n,p[g+3],14,-187363961);n=md5_gg(n,m,l,o,p[g+8],20,1163531501);o=md5_gg(o,n,m,l,p[g+13],5,-1444681467);l=md5_gg(l,o,n,m,p[g+2],9,-51403784);m=md5_gg(m,l,o,n,p[g+7],14,1735328473);n=md5_gg(n,m,l,o,p[g+12],20,-1926607734);o=md5_hh(o,n,m,l,p[g+5],4,-378558);l=md5_hh(l,o,n,m,p[g+8],11,-2022574463);m=md5_hh(m,l,o,n,p[g+11],16,1839030562);n=md5_hh(n,m,l,o,p[g+14],23,-35309556);o=md5_hh(o,n,m,l,p[g+1],4,-1530992060);l=md5_hh(l,o,n,m,p[g+4],11,1272893353);m=md5_hh(m,l,o,n,p[g+7],16,-155497632);n=md5_hh(n,m,l,o,p[g+10],23,-1094730640);o=md5_hh(o,n,m,l,p[g+13],4,681279174);l=md5_hh(l,o,n,m,p[g+0],11,-358537222);m=md5_hh(m,l,o,n,p[g+3],16,-722521979);n=md5_hh(n,m,l,o,p[g+6],23,76029189);o=md5_hh(o,n,m,l,p[g+9],4,-640364487);l=md5_hh(l,o,n,m,p[g+12],11,-421815835);m=md5_hh(m,l,o,n,p[g+15],16,530742520);n=md5_hh(n,m,l,o,p[g+2],23,-995338651);o=md5_ii(o,n,m,l,p[g+0],6,-198630844);l=md5_ii(l,o,n,m,p[g+7],10,1126891415);m=md5_ii(m,l,o,n,p[g+14],15,-1416354905);n=md5_ii(n,m,l,o,p[g+5],21,-57434055);o=md5_ii(o,n,m,l,p[g+12],6,1700485571);l=md5_ii(l,o,n,m,p[g+3],10,-1894986606);m=md5_ii(m,l,o,n,p[g+10],15,-1051523);n=md5_ii(n,m,l,o,p[g+1],21,-2054922799);o=md5_ii(o,n,m,l,p[g+8],6,1873313359);l=md5_ii(l,o,n,m,p[g+15],10,-30611744);m=md5_ii(m,l,o,n,p[g+6],15,-1560198380);n=md5_ii(n,m,l,o,p[g+13],21,1309151649);o=md5_ii(o,n,m,l,p[g+4],6,-145523070);l=md5_ii(l,o,n,m,p[g+11],10,-1120210379);m=md5_ii(m,l,o,n,p[g+2],15,718787259);n=md5_ii(n,m,l,o,p[g+9],21,-343485551);o=safe_add(o,j);n=safe_add(n,h);m=safe_add(m,f);l=safe_add(l,e)}return Array(o,n,m,l)}function md5_cmn(h,e,d,c,g,f){return safe_add(bit_rol(safe_add(safe_add(e,h),safe_add(c,f)),g),d)}function md5_ff(g,f,k,j,e,i,h){return md5_cmn((f&k)|((~f)&j),g,f,e,i,h)}function md5_gg(g,f,k,j,e,i,h){return md5_cmn((f&j)|(k&(~j)),g,f,e,i,h)}function md5_hh(g,f,k,j,e,i,h){return md5_cmn(f^k^j,g,f,e,i,h)}function md5_ii(g,f,k,j,e,i,h){return md5_cmn(k^(f|(~j)),g,f,e,i,h)}function safe_add(a,d){var c=(a&65535)+(d&65535);var b=(a>>16)+(d>>16)+(c>>16);return(b<<16)|(c&65535)}function bit_rol(a,b){return(a<<b)|(a>>>(32-b))};
EOF;
	}
}

 define("SPANONYMOUS","SPANONYMOUS"); // 镞犳潈闄愯缃殑瑙掕壊鍚岖О
 /**
 * ACL鎿崭綔绫伙紝阃氲绷鏁版嵁琛ㄧ‘瀹氱敤鎴锋潈闄?
 * 琛ㄧ粨鏋勶细
 * CREATE TABLE acl
 * (
 * 	aclid int NOT NULL AUTO_INCREMENT,
 * 	name VARCHAR(200) NOT NULL,
 * 	controller VARCHAR(50) NOT NULL,
 * 	action VARCHAR(50) NOT NULL,
 * 	acl_name VARCHAR(50) NOT NULL,
 * 	PRIMARY KEY (aclid)
 * ) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
 */
class spAclModel extends spModel
{

	public $pk = 'aclid';
	/**
	 * 琛ㄥ悕
	 */
	public $table = 'acl';

	/**
	 * 妫€镆ュ搴旗殑鏉冮檺
	 *
	 * 杩斿洖1鏄€氲绷妫€镆ワ紝0鏄笉鑳介€氲绷妫€镆ワ纸鎺у埗鍣ㄥ强锷ㄤ綔瀛桦湪浣嗙敤鎴锋爣璇嗘病链夎褰曪级
	 * 杩斿洖-1鏄棤璇ユ潈闄愭带鍒讹纸鍗宠鎺у埗鍣ㄥ强锷ㄤ綔涓嶅瓨鍦ㄤ簬鏉冮檺琛ㄤ腑锛?
	 * 
	 * @param acl_name    鐢ㄦ埛镙囱瘑锛氩彲浠ユ槸缁勫悕鎴栨槸鐢ㄦ埛鍚?
	 * @param controller    鎺у埗鍣ㄥ悕绉?
	 * @param action    锷ㄤ綔鍚岖О
	 */
	public function check($acl_name = SPANONYMOUS, $controller, $action)
	{
		$rows = array('controller' => $controller, 'action' => $action );
		if( $acl = $this->findAll($rows) ){
			foreach($acl as $v){
				if($v["acl_name"] == SPANONYMOUS || $v["acl_name"] == $acl_name)return 1;
			}
			return 0;
		}else{
			return -1;
		}
	}
}