<?php
/*
 * PHP version 5
 *
 * @copyright Copyright 2010, Cake. (http://trpgtools-onweb.sourceforge.jp/)
 * @category Component
 * @package  TRPG Data Bank
 * @version  beta
 * @author   Cake <cake_67@users.sourceforge.jp>
 * @license  http://www.opensource.org/licenses/mit-license.php The MIT License
 * @link     http://trpgtools-onweb.sourceforge.jp/
 */
/**
 * CSRF対策用Tokenチェッカー
 * Security.level = medium または low のみ
 */

class TokenComponent extends Object
{

/**
 * Components used by TokenHelper
 *
 * @var array
 * @access public
 */
	var $components = array('Session');

	var $_modelClass;
	var $_data = array();
	var $_action;
	var $_actionMap = array();
	var $type;
	var $useToken = false;
	var $disableActions = array();

	function initialize(&$controller)
	{
		$this->_modelClass = $controller->modelClass;
		$this->_action = $controller->action;
		if (isset($controller->params['data'])) {
			$this->_data = $controller->params['data'];
		}

		if (isset($controller->AuthPlus)) {
			$this->_actionMap = $controller->AuthPlus->actionMap;
		} else {
			return ;
		}

		if (isset($this->_actionMap[$this->_action])) {
			$this->type = $this->_actionMap[$this->_action];
		}

		if (!isset($controller->disableTokenActions)) {
			$this->useToken = false;
		} else {
			$this->useToken = $this->isUseToken($controller->disableTokenActions);
		}

		$this->Session->startup($controller);
	}

	/* true: Token OK */
	function checkToken($tag_name = '__Token', $hash_type = 'md5')
	{
		if ($this->useToken === false) {
			return ;
		}
		$hashed_session_id = $this->get_hashed_session_id();

		if ($this->_data) {
			if (!isset($this->_data[$this->_modelClass][$tag_name])) {
				$this->_blackHole();
			}
			if ($this->_data[$this->_modelClass][$tag_name] != $hashed_session_id) {
				$this->_blackHole();
			}
		} else {
			return ;
		}
	}

	/* true:Token使用 */
	function isUseToken($disableTokenActions)
	{
		if ($disableTokenActions == '*') {
			return false;
		}
		if (!$this->type || $this->type == 'read') {
			return false;
		}
		if (in_array($this->_action, (array)$disableTokenActions)) {
			return false;
		}

		return true;
	}

	function _blackHole($msg='')
	{
		if (!$msg) {
			$msg = _('ILLEGAL POST!');
		}
		
		die($msg);
	}

	/* 現在のセッションIDを暗号化して取得 */
	function get_hashed_session_id($hash_type = 'md5')
	{
		$session_id = $this->Session->id(null);

		if (!$session_id) {
			$this->_blackHole('No Session.');
		}

		return Security::hash($session_id. Configure::read('Security.salt'), $hash_type);
	}

}

