Skip to content

Commit bbb96dd

Browse files
author
Robin Cawser
committed
Add (ircmaxell) secure random string gen
1 parent bc249e2 commit bbb96dd

3 files changed

Lines changed: 191 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
namespace spec\Vivait\StringGeneratorBundle\Generator;
4+
5+
use PhpSpec\ObjectBehavior;
6+
use Prophecy\Argument;
7+
use RandomLib\Factory;
8+
use RandomLib\Generator;
9+
use RandomLib\Mixer;
10+
use SecurityLib\Strength;
11+
12+
class SecureStringGeneratorSpec extends ObjectBehavior
13+
{
14+
15+
/**
16+
* @var Factory
17+
*/
18+
private $factory;
19+
20+
function it_is_initializable()
21+
{
22+
$this->shouldHaveType('Vivait\StringGeneratorBundle\Generator\SecureStringGenerator');
23+
}
24+
25+
function let(Factory $factory, Generator $low, Generator $medium)
26+
{
27+
$factory->getMediumStrengthGenerator()->willReturn($medium);
28+
$factory->getLowStrengthGenerator()->willReturn($low);
29+
$this->beConstructedWith($factory);
30+
31+
$defaults = [
32+
'length' => 32,
33+
'chars' => '',
34+
'strength' => 'medium',
35+
];
36+
37+
$this->setOptions($defaults);
38+
}
39+
40+
function it_chooses_medium_strength_gen_by_default(Generator $medium)
41+
{
42+
$this->getGenerator()->shouldReturn($medium);
43+
}
44+
45+
function it_chooses_a_specified_strength_gen(Generator $medium, Generator $low)
46+
{
47+
$this->getGenerator('medium')->shouldReturn($medium);
48+
$this->getGenerator('low')->shouldReturn($low);
49+
}
50+
51+
function it_errors_on_invalid_strength_gen(Generator $medium, Generator $low)
52+
{
53+
$this->getGenerator('medium')->shouldReturn($medium);
54+
$this->getGenerator('low')->shouldReturn($low);
55+
56+
$this->shouldThrow('\InvalidArgumentException')->duringGetGenerator('high');
57+
$this->shouldThrow('\InvalidArgumentException')->duringGetGenerator('invalid');
58+
}
59+
60+
function it_generates_a_random_string(Generator $medium)
61+
{
62+
$medium->generateString(32, '')->shouldBeCalled();
63+
$this->generate();
64+
}
65+
66+
function it_generates_a_random_string_of_set_length(Generator $medium, Generator $low)
67+
{
68+
$options = [
69+
'length' => 8,
70+
'chars' => '',
71+
'strength' => 'low',
72+
];
73+
$this->setOptions($options);
74+
75+
$medium->generateString(8, '')->shouldNotBeCalled();
76+
$low->generateString(8, '')->shouldBeCalled();
77+
78+
$this->generate();
79+
}
80+
81+
function getMatchers()
82+
{
83+
return [
84+
'haveStrlen' => function($string, $length){
85+
return strlen($string) == $length;
86+
}
87+
];
88+
}
89+
}

src/Vivait/StringGeneratorBundle/Generator/SecureBytesGenerator.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@ public function generate()
3838
{
3939
return $this->secureRandom->nextBytes($this->length);
4040
}
41+
42+
/**
43+
* @param array $options
44+
*/
45+
public function setOptions(array $options)
46+
{
47+
// TODO: Implement setOptions() method.
48+
}
4149
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Vivait\StringGeneratorBundle\Generator;
4+
5+
use RandomLib\Factory;
6+
use RandomLib\Generator;
7+
use Symfony\Component\OptionsResolver\OptionsResolver;
8+
use Vivait\StringGeneratorBundle\Model\ConfigurableGeneratorInterface;
9+
use Vivait\StringGeneratorBundle\Model\GeneratorInterface;
10+
11+
class SecureStringGenerator implements ConfigurableGeneratorInterface
12+
{
13+
14+
/**
15+
* @var
16+
*/
17+
private $length = 32;
18+
19+
/**
20+
* @var Generator
21+
*/
22+
private $generator;
23+
24+
private $chars = '';
25+
26+
private $strength = 'medium';
27+
28+
/**
29+
* @var Factory
30+
*/
31+
private $factory;
32+
33+
/**
34+
* @param Factory $factory
35+
*/
36+
public function __construct(Factory $factory)
37+
{
38+
39+
$this->factory = $factory;
40+
}
41+
42+
/**
43+
* Creates a random string based on a length and alphabet
44+
*
45+
* @return string
46+
*/
47+
public function generate()
48+
{
49+
return $this->generator->generateString($this->length, $this->chars);
50+
}
51+
52+
public function getGenerator($strength = 'medium')
53+
{
54+
switch ($strength) {
55+
case 'low':
56+
return $this->factory->getLowStrengthGenerator();
57+
case 'medium':
58+
return $this->factory->getMediumStrengthGenerator();
59+
case 'high':
60+
throw new \InvalidArgumentException('"high" strength is currently unavailable');
61+
default:
62+
throw new \InvalidArgumentException('Could not find a generator for the specified strength');
63+
}
64+
}
65+
66+
public function setOptions(array $options = [])
67+
{
68+
$this->generator = $this->getGenerator($options['strength']);
69+
$this->length = $options['length'];
70+
$this->chars = $options['chars'];
71+
}
72+
73+
public function getDefaultOptions(OptionsResolver $resolver)
74+
{
75+
return $resolver->setDefaults(
76+
[
77+
'length' => $this->length,
78+
'chars' => $this->chars,
79+
'strength' => $this->strength,
80+
]
81+
);
82+
}
83+
84+
/**
85+
* @param integer $length
86+
* @return $this
87+
* @deprecated this will be deprecated in version 2.0 in favour of using callbacks on the generator. This is due to
88+
* some generators not actually needing a length - only random string type generators require it.
89+
*/
90+
public function setLength($length)
91+
{
92+
// TODO: Implement setLength() method.
93+
}
94+
}

0 commit comments

Comments
 (0)