2013-05-10 8 views
6

Rozważmy następujący kod:CakePHP Testowanie kontrolera z elementem bezpieczeństwa

kod kontrolera

<?php 
App::uses('AppController', 'Controller'); 

class UsersController extends AppController { 

    public $components = array(
     'Security', 
     'Session' 
    ); 

    public function example() { 
     if ($this->request->is('post')) { 
      $this->set('some_var', true); 
     } 
    } 
} 

Zobacz Kod

<?php 

echo $this->Form->create(); 
echo $this->Form->input('name'); 
echo $this->Form->end('Submit'); 

Ponieważ mam komponent zabezpieczeń w miejscu, sabotaż z formularzem w jakikolwiek sposób (takim jak dodanie do niego pola) spowoduje, że żądanie będzie czarne-h oled. Chciałbym przetestować:

kod testowy

<?php 

class UsersControllerTest extends ControllerTestCase { 

    public function testExamplePostValidData() { 
     $this->Controller = $this->generate('Users', array(
      'components' => array(
       'Security' 
      ) 
     )); 

     $data = array(
      'User' => array(
       'name' => 'John Doe' 
      ) 
     ); 

     $this->testAction('/users/example', array('data' => $data, 'method' => 'post')); 
     $this->assertTrue($this->vars['some_var']); 
    } 

    public function testExamplePostInvalidData() { 
     $this->Controller = $this->generate('Users', array(
      'components' => array(
       'Security' 
      ) 
     )); 

     $data = array(
      'User' => array(
       'name' => 'John Doe', 
       'some_field' => 'The existence of this should cause the request to be black-holed.' 
      ) 
     ); 

     $this->testAction('/users/example', array('data' => $data, 'method' => 'post')); 
     $this->assertTrue($this->vars['some_var']); 
    } 
} 

Drugi test testExamplePostInvalidData powinna zawieść z powodu some_field będącego w tablicy $data, ale to przechodzi! Co ja robię źle?

Odpowiedz

1

Po dodaniu "some_field" w danych -> testAction, składnik bezpieczeństwa założy, że pole jest częścią twojej aplikacji (ponieważ pochodzi z twojego kodu, a nie z tablicy POST), więc nie będzie widoczne jako "próba włamania".

Sprawdzanie pod kątem dziur jest nieco bardziej zawiłe. Ale testy rdzeniowe ciast testują już funkcjonalność blackhole, więc jeśli te testy przejdą, nie musisz sprawdzać ich w swojej aplikacji.

Jeśli upierasz choć sprawdzeniu testów rdzeń ciasto na wytycznych:

Konkretnie:

/** 
* test that validatePost fails if any of its required fields are missing. 
* 
* @return void 
*/ 
public function testValidatePostFormHacking() { 
    $this->Controller->Security->startup($this->Controller); 
    $key = $this->Controller->params['_Token']['key']; 
    $unlocked = ''; 

    $this->Controller->request->data = array(
     'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'), 
     '_Token' => compact('key', 'unlocked') 
    ); 
    $result = $this->Controller->Security->validatePost($this->Controller); 
    $this->assertFalse($result, 'validatePost passed when fields were missing. %s'); 
} 

wiele innych przykładów w pliku:
https://github.com/cakephp/cakephp/blob/master/lib/Cake/Test/Case/Controller/Component/SecurityComponentTest.php

+0

Ta odpowiedź mnie myśleć możliwość sprawdzenia, co zwraca widok w GET i zobacz, czy zawiera pola, które nie powinny być edytowalne. Następnie, wiedząc, że komponent Security jest włączony, wiem, że jestem bezpieczny. Ale myślę, że mój test ma sens, ponieważ testy nie dbają o to, jaka jest twoja implementacja; testy tylko dbają o wynik. Zatem wynik umieszczania pól, które nie powinny być edytowalne, powinien skutkować błędem, niezależnie od tego, czy wygenerowany z komponentu Security, czy też nie (test nie dba o to). Ale myślę, że ta odpowiedź wystarcza. Dziękuję Ci! – Nick