PageRenderTime 57ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/component/charcoal/form/FormTokenComponent.class.php

https://bitbucket.org/stk2k/charcoalphp2.1
PHP | 204 lines | 110 code | 39 blank | 55 comment | 20 complexity | c89bfe79b9d40bae7094079176d114c6 MD5 | raw file
  1. <?php
  2. /**
  3. * Form Token Component
  4. *
  5. * PHP version 5
  6. *
  7. * @package component.charcoal.form
  8. * @author CharcoalPHP Development Team
  9. * @copyright 2008 stk2k, sazysoft
  10. */
  11. require_once( 'FormTokenComponentException.class.php' );
  12. require_once( 'FormTokenValidationException.class.php' );
  13. class Charcoal_FormTokenComponent extends Charcoal_CharcoalComponent implements Charcoal_ICharcoalComponent
  14. {
  15. private $token_key;
  16. private $debug_mode;
  17. /** @var Charcoal_ITokenGenerator */
  18. private $token_generator;
  19. /*
  20. * Construct object
  21. */
  22. public function __construct()
  23. {
  24. parent::__construct();
  25. }
  26. /**
  27. * Initialize instance
  28. *
  29. * @param array $config configuration data
  30. */
  31. public function configure( $config )
  32. {
  33. parent::configure( $config );
  34. log_debug( "debug", "config: " . print_r($config,true) );
  35. $config = new Charcoal_HashMap($config);
  36. $this->token_key = $config->getString( 'token_key', 'charcoaltoken_key' );
  37. $this->debug_mode = $config->getBoolean( 'debug_mode', FALSE );
  38. $this->token_generator = $config->getString( 'token_generator', 'simple' );
  39. log_debug( "debug", "token key: {$this->token_key}" );
  40. log_debug( "debug", "debug mode: {$this->debug_mode}" );
  41. log_debug( "debug", "token generator: {$this->token_generator}" );
  42. $this->token_generator = $this->getSandbox()->createObject( $this->token_generator, 'token_generator' );
  43. }
  44. /*
  45. * Set token generator
  46. *
  47. * @param Charcoal_ITokenGenerator $token_generator token generator
  48. */
  49. public function setTokenGenerator( $token_generator )
  50. {
  51. Charcoal_ParamTrait::validateIsA( 1, 'Charcoal_ITokenGenerator', $token_generator );
  52. $this->token_generator = $token_generator;
  53. }
  54. /*
  55. * Get token generator
  56. *
  57. * @return Charcoal_ITokenGenerator token generator
  58. */
  59. public function getTokenGenerator()
  60. {
  61. return $this->token_generator;
  62. }
  63. /*
  64. * generate token
  65. *
  66. * @param Charcoal_Session $session
  67. *
  68. * @return string new form token
  69. */
  70. public function generate( $session )
  71. {
  72. try{
  73. $token_key = $this->token_key;
  74. /** @var Charcoal_Session $session */
  75. // get token container from session.
  76. $token_list = $session->getArray( $token_key );
  77. if ( $token_list === NULL || !is_array($token_list) ){
  78. $token_list = array();
  79. }
  80. // Generate token
  81. $new_token = $this->token_generator->generateToken();
  82. log_debug( "debug", "token generated: $new_token" );
  83. // add new token to token list.
  84. $token_list[] = $new_token;
  85. log_debug( "debug", "token_list: ", print_r($token_list, true) );
  86. // save token list in session.
  87. $session->set( $token_key, $token_list );
  88. log_debug( "debug", "session: " . print_r($session,true) );
  89. return $new_token;
  90. }
  91. catch( Exception $e )
  92. {
  93. _catch( $e );
  94. _throw( new Charcoal_FormTokenComponentException( s(__CLASS__.'#'.__METHOD__.' failed.'), $e ) );
  95. }
  96. return null;
  97. }
  98. /*
  99. * validate token in request and session
  100. *
  101. * @param Charcoal_Session $session Session object
  102. * @param string|Charcoal_String $form_token Form token
  103. * @param boolean|Charcoal_Boolean $throws If true, this method throws an exception on failure. Otherwise returns true/false
  104. */
  105. public function validate( $session, $form_token, $throws = TRUE )
  106. {
  107. $throws = ub($throws);
  108. /** @var Charcoal_Session $session */
  109. log_debug( "debug", "session: " . print_r($session,true) );
  110. log_debug( "debug", "form_token: " . print_r($form_token,true) );
  111. if ( $this->getSandbox()->isDebug() && $this->debug_mode ){
  112. ad($session,array('title'=>"session"));
  113. }
  114. $token_key = $this->token_key;
  115. log_debug( "debug", "token_key: " . print_r($token_key,true) );
  116. if ( $this->getSandbox()->isDebug() && $this->debug_mode ){
  117. ad($token_key,array('title'=>"token_key","type"=>"div"));
  118. }
  119. // get token container from session.
  120. $token_list = $session->getArray( $token_key );
  121. if ( $this->getSandbox()->isDebug() && $this->debug_mode ){
  122. ad($token_list,array('title'=>"token list"));
  123. }
  124. log_debug( "debug", "token_list: " . print_r($token_list,true) );
  125. if ( $token_list === NULL || !is_array($token_list) ){
  126. $token_list = array();
  127. }
  128. // find token from token list.
  129. $token_index = NULL;
  130. foreach( $token_list as $idx => $token ){
  131. log_info( "debug", "token: $token" );
  132. if ( $this->getSandbox()->isDebug() && $this->debug_mode ){
  133. ad($token,array('title'=>"token","type"=>"div"));
  134. }
  135. if ( $token == $form_token ){
  136. $token_index = $idx;
  137. break;
  138. }
  139. }
  140. if ( $token_index === NULL ){
  141. // illegal access
  142. log_warning( "system, debug", "token not found: $form_token" );
  143. if ( $this->getSandbox()->isDebug() && $this->debug_mode ){
  144. ad($form_token,array('title'=>"token not found","type"=>"div"));
  145. }
  146. if ( $throws ){
  147. _throw( new Charcoal_FormTokenValidationException( 'token not found in session:'.$form_token ), FALSE );
  148. }
  149. return FALSE;
  150. }
  151. else{
  152. // authorized access
  153. log_debug( "debug", "token accepted: $form_token" );
  154. if ( $this->getSandbox()->isDebug() && $this->debug_mode ){
  155. ad($form_token,array('title'=>"token accepted","type"=>"div"));
  156. }
  157. // erase token from token list to prevent duplicate form submission.
  158. unset( $token_list[$token_index] );
  159. }
  160. // update token list in session.
  161. $session->set( $token_key, $token_list );
  162. // the event was successfully processed.
  163. return TRUE;
  164. }
  165. }