Completed
Push — master ( 9354c8...f870e6 )
by Philip
02:16
created

UserSetup::possibleGenSalt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the CRUDlexUser package.
5
 *
6
 * (c) Philip Lehmann-Böhm <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace CRUDlex;
13
14
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
15
use CRUDlex\Data;
16
17
/**
18
 * This class setups CRUDlex with some events so the passwords get salted and
19
 * hashed properly.
20
 */
21
class UserSetup {
22
23
    /**
24
     * Generates a new salt if the given salt is null.
25
     *
26
     * @param &string $salt
0 ignored issues
show
Documentation introduced by
The doc-type &string could not be parsed: Unknown type name "&string" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
27
     * the salt to override if null
28
     *
29
     * @return boolean
30
     * true if a new salt was generated
31
     */
32
    private function possibleGenSalt(&$salt) {
33
        if (!$salt) {
34
            $salt = $this->getSalt(40);
35
            $entity->set($saltField, $salt);
0 ignored issues
show
Bug introduced by
The variable $entity does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $saltField does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
36
            return true;
37
        }
38
        return false;
39
    }
40
41
    /**
42
     * Generates a random salt of the given length.
43
     *
44
     * @param int $len
45
     * the desired length
46
     *
47
     * @return string
48
     * a random salt of the given length
49
     */
50
    public function getSalt($len) {
51
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()-=_+';
52
        $l = strlen($chars) - 1;
53
        $str = '';
54
        for ($i = 0; $i < $len; ++$i) {
55
            $str .= $chars[mt_rand(0, $l)];
56
        }
57
        return $str;
58
    }
59
60
    /**
61
     * Setups CRUDlex with some events so the passwords get salted and
62
     * hashed properly.
63
     *
64
     * @param Data $data
65
     * the Data instance managing the users
66
     *
67
     * @param string $passwordField
68
     * the Entity fieldname of the password hash
69
     *
70
     * @param string $saltField
71
     * the Entity fieldname of the password hash salt
72
     */
73
    public function addEvents(Data $data, $passwordField = 'password', $saltField = 'salt') {
74
75
        $that = $this;
76
77
        $saltGenFunction = function(Entity $entity) use ($saltField, $that) {
78
            $salt = $that->getSalt(40);
79
            $entity->set($saltField, $salt);
80
            return true;
81
        };
82
83
        $data->pushEvent('before', 'create', $saltGenFunction);
84
85
        $pwHashFunction = function(Entity $entity) use ($data, $passwordField, $saltField, $that) {
86
            $password = $entity->get($passwordField);
87
88
            if (!$password) {
89
                return true;
90
            }
91
92
            $encoder = new MessageDigestPasswordEncoder();
93
            $salt = $entity->get($saltField);
94
            $newSalt = $that->possibleGenSalt($salt);
95
96
            $passwordHash = $encoder->encodePassword($password, $salt);
97
98
            $doGenerateHash = true;
99
            $id = $entity->get('id');
100
            if ($id !== null) {
101
                $oldEntity = $data->get($entity->get('id'));
102
                $doGenerateHash = $oldEntity->get($passwordField) !== $password || $newSalt;
103
            }
104
105
            if ($doGenerateHash) {
106
                $entity->set($passwordField, $passwordHash);
107
            }
108
            return true;
109
        };
110
111
        $data->pushEvent('before', 'create', $pwHashFunction);
112
        $data->pushEvent('before', 'update', $pwHashFunction);
113
114
    }
115
116
}
117