<?php
  
/*
--------------------------------------
Класс для защиты методов GET и POST от
подделок запросов
--------------------------------------
*/
  
CLASS CSRF{
  
  //Генерация id токена из сессионной переменной
  PUBLIC STATIC FUNCTION TOKEN_ID() {
    
    IF (ISSET($_SESSION['token_id'])) { 
      
      RETURN $_SESSION['token_id'];
    
    }ELSE{
      
      $token_id = CSRF::RANDOM(10);
      $_SESSION['token_id'] = $token_id;
      
      RETURN $token_id;
    
    }
  
  }
  
  //Значение токена
  PUBLIC STATIC FUNCTION TOKEN() {
    
    IF (ISSET($_SESSION['token_value'])) {
      
      RETURN $_SESSION['token_value']; 
    
    }ELSE{
      
      $token = HASH('sha256', CSRF::RANDOM(500));
      $_SESSION['token_value'] = $token;
      
      RETURN $token;
    
    }
  
  }
  
  //Проверка на валидность id и значение токена
  PUBLIC STATIC FUNCTION CHECK_VALID($method) {
    
    IF ($method == 'post' || $method == 'get') {
      
      $post = $_POST;
      $get = $_GET;
      
      IF (ISSET(${$method}[CSRF::TOKEN_ID()]) && (${$method}[CSRF::TOKEN_ID()] == CSRF::TOKEN())) {
        
        RETURN TRUE;
      
      }ELSE{
        
        RETURN FALSE;	
      
      }
    
    }ELSE{
      
      RETURN FALSE;	
    
    }
  
  }
  
  //Проверка на валидность id и значение токена для get запросов
  PUBLIC STATIC FUNCTION GET_CHECK_VALID($get) {
    
    IF (CONFIG('CSRF') == 0 || CSRF::CHECK_VALID('get')) {
      
      $result = $get;
      
      RETURN $result;
    
    }ELSE{
      
      ERROR('Неверный ключ запроса', 'session');
      REDIRECT('/');
    
    }
    
  }
  
  //Проверка на валидность id и значение токена для post запросов
  PUBLIC STATIC FUNCTION POST_CHECK_VALID($post) {
    
    IF (CONFIG('CSRF') == 0 || CSRF::CHECK_VALID('post')) {
      
      $result = $post;
      
      RETURN $result;
    
    }ELSE{
      
      ERROR('Неверный ключ запроса', 'session');
      REDIRECT(REQUEST_URI);
    
    }
    
  }
  
  //Генерирация случайной строки  
  PUBLIC STATIC FUNCTION RANDOM($len) {
    
    IF (FUNCTION_EXISTS('openssl_random_pseudo_bytes')) {
      
      $byteLen = INTVAL(($len / 2) + 1);
      $return = SUBSTR(BIN2HEX(OPENSSL_RANDOM_PSEUDO_BYTES($byteLen)), 0, $len);
    
    }ELSEIF (@IS_READABLE('/dev/urandom')) {
      
      $f = FOPEN('/dev/urandom', 'r');
      $urandom = FREAD($f, $len);
      FCLOSE($f);
      
      $return = NULL;
    
    }
    
    IF (EMPTY($return)) {
      
      FOR ($i = 0; $i < $len; ++$i) {
        
        IF (!ISSET($urandom)) {
          
          IF ($i % 2 == 0) {
            
            MT_SRAND(TIME() % 2147 * 1000000 + (DOUBLE)MICROTIME() * 1000000);
          
          }
          
          $rand = 48 + MT_RAND() % 64;
        
        }ELSE{
          
          $rand = 48 + ORD($urandom[$i]) % 64;
        
        }
        
        IF ($rand > 57){
          
          $rand += 7;
          
        }
        
        IF ($rand > 90){
          
          $rand += 6;
          
        }
        
        IF ($rand == 123){
          
          $rand = 52;
          
        }
        
        IF ($rand == 124){
          
          $rand = 53;
          
        }
        
        $return .= CHR($rand);
      
      }
    
    }
    
    RETURN $return;
  
  }
  
}
  
?>