2

I am trying to apply a security token using this code snipp from scott but I can't seem to work it out in symfony2, here is my code:

<?php

namespace Acme\UserManagementBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class TokenController extends Controller
{

    public function randSecureAction($min, $max) {
        $range = $max - $min;
        if ($range < 0) return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1

        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);

        return new Response ($min + $rnd);
    }

    public function getTokenAction($length=32) {
        $token = "";
        $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
        $codeAlphabet.= "0123456789";

        for($i=0;$i<$length;$i++) {
            $token .= $codeAlphabet[randSecureAction(0,strlen($codeAlphabet))];
        }
        return new Response ($token);
    }

}

I create this TokenController as a service like this so I can call it to my DefaultController, now the service can't call the other functions inside this controller, am I doing it wrong or there is a problem within my code because the function (getTokenAction) inside can't seem to use other function(randSecureAction) in the TokenController class.

Community
  • 1
  • 1
Cedric
  • 1,236
  • 2
  • 18
  • 35

2 Answers2

5

Inside getTokenAction you have the line:

$token .= $codeAlphabet[randSecureAction(0,strlen($codeAlphabet))];

Here is your problem, you have to use $this->randSecureAction(...). So try

$token .= $codeAlphabet[$this->randSecureAction(0,strlen($codeAlphabet))];
Syjin
  • 2,740
  • 1
  • 27
  • 31
  • wth? to forgot that simple pointer, I am really dizzy. One more question, is there another function besides the forward method in response component for calling another function in symfony because it returns a string with the header string in it, I just want to get the returned data from the function. tnx! – Cedric Jan 15 '14 at 08:23
  • I am not sure, if I understand you correctly. But you can call functions and return values as usual. You don't have to use Response for your internal functions. – Syjin Jan 15 '14 at 08:41
1

service is a php object. so you need to change it to

$this->randSecureAction(0,strlen($codeAlphabet))

also use Response objects to response, not instead of return.

and personally prefer to use Action word just at the end of action functions.

so final code should be like this

namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class TokenController extends Controller {

    public function randSecure($min, $max) {
        $range = $max - $min;
        if ($range < 0)
            return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);
        return $min + $rnd;
    }

    public function getToken($length = 32) {
        $token = "";
        $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
        $codeAlphabet.= "0123456789";
        for ($i = 0; $i < $length; $i++) {            
             $token .= $codeAlphabet[$this->randSecure(0, strlen($codeAlphabet))];
        }
        return $token;
    }

}

and definition as service:

    <parameters>
        <parameter key="acme.controller.token.class">Acme\DemoBundle\Controller\TokenController</parameter>
    </parameters>

    <services>
        <service id="acme.token.controller" class="%acme.controller.token.class%" />        
    </services>

and usage:

public function helloAction($name) {

    $token = $this->get('acme.token.controller')->getToken();

}
Erfan
  • 1,132
  • 15
  • 21
  • tnx for the guides! I am new in symfony so I am not used in naming conventions in it so I am really thankful for the guide! tnx again!. – Cedric Jan 15 '14 at 08:30