Completed
Push — master ( 321616...2caab7 )
by Torben
03:43
created

FrontendUserService::getPasswordHash()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 16
c 0
b 0
f 0
rs 9.9
cc 3
nc 3
nop 1
1
<?php
2
declare(strict_types=1);
3
namespace Derhansen\FeChangePwd\Service;
4
5
/*
6
 * This file is part of the Extension "fe_change_pwd" for TYPO3 CMS.
7
 *
8
 * For the full copyright and license information, please read the
9
 * LICENSE.txt file that was distributed with this source code.
10
 */
11
12
use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory;
13
use TYPO3\CMS\Core\Database\ConnectionPool;
14
use TYPO3\CMS\Core\Utility\GeneralUtility;
15
use TYPO3\CMS\Saltedpasswords\Salt\SaltFactory;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Saltedpasswords\Salt\SaltFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility;
0 ignored issues
show
Bug introduced by
The type TYPO3\CMS\Saltedpassword...\SaltedPasswordsUtility was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
18
/**
19
 * Class FrontendUserService
20
 */
21
class FrontendUserService
22
{
23
    /**
24
     * The session key
25
     */
26
    const SESSION_KEY = 'mustChangePasswordReason';
27
28
    /**
29
     * @var SettingsService
30
     */
31
    protected $settingsService = null;
32
33
    /**
34
     * @param SettingsService $settingsService
35
     */
36
    public function injectSettingsService(\Derhansen\FeChangePwd\Service\SettingsService $settingsService)
37
    {
38
        $this->settingsService = $settingsService;
39
    }
40
41
    /**
42
     * Returns if the frontend user must change the password
43
     *
44
     * @param array $feUserRecord
45
     * @return bool
46
     */
47
    public function mustChangePassword(array $feUserRecord)
48
    {
49
        $reason = '';
50
        $result = false;
51
        $mustChangePassword = $feUserRecord['must_change_password'] ?? 0;
52
        $passwordExpiryTimestamp = $feUserRecord['password_expiry_date'] ?? 0;
53
        if ((bool)$mustChangePassword) {
54
            $reason = 'forcedChange';
55
            $result = true;
56
        } elseif (((int)$passwordExpiryTimestamp > 0 && (int)$passwordExpiryTimestamp < time())) {
57
            $reason = 'passwordExpired';
58
            $result = true;
59
        }
60
61
        if ($result) {
62
            // Store reason for password change in user session
63
            $this->getFrontendUser()->setKey('ses', self::SESSION_KEY, $reason);
64
            $this->getFrontendUser()->storeSessionData();
65
        }
66
        return $result;
67
    }
68
69
    /**
70
     * Returns the reason for the password change stored in the session
71
     *
72
     * @return mixed
73
     */
74
    public function getMustChangePasswordReason()
75
    {
76
        return $this->getFrontendUser()->getKey('ses', self::SESSION_KEY);
77
    }
78
79
    /**
80
     * Updates the password of the current user if a current user session exist
81
     *
82
     * @param string $newPassword
83
     * @return void
84
     */
85
    public function updatePassword(string $newPassword)
86
    {
87
        if (!$this->isUserLoggedIn()) {
88
            return;
89
        }
90
91
        $password = $this->getPasswordHash($newPassword);
92
93
        $userTable = $this->getFrontendUser()->user_table;
94
        $userUid = $this->getFrontendUser()->user['uid'];
95
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($userTable);
96
        $queryBuilder->getRestrictions()->removeAll();
97
        $queryBuilder->update($userTable)
98
            ->set('password', $password)
99
            ->set('must_change_password', 0)
100
            ->set('password_expiry_date', $this->settingsService->getPasswordExpiryTimestamp())
101
            ->set('tstamp', (int)$GLOBALS['EXEC_TIME'])
102
            ->where(
103
                $queryBuilder->expr()->eq(
104
                    'uid',
105
                    $queryBuilder->createNamedParameter($userUid, \PDO::PARAM_INT)
106
                )
107
            )
108
            ->execute();
109
110
        // Unset reason for password change in user session
111
        $this->getFrontendUser()->setKey('ses', self::SESSION_KEY, null);
112
    }
113
114
    /**
115
     * Returns a password hash
116
     *
117
     * @param string $password
118
     * @return string
119
     * @throws MissingPasswordHashServiceException
120
     * @throws \TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException
121
     */
122
    protected function getPasswordHash(string $password)
123
    {
124
        if (class_exists(PasswordHashFactory::class)) {
125
            $hashInstance = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('FE');
126
            $password = $hashInstance->getHashedPassword($password);
127
        } elseif (SaltedPasswordsUtility::isUsageEnabled('FE')) {
128
            $saltingInstance = SaltFactory::getSaltingInstance();
129
            $password = $saltingInstance->getHashedPassword($password);
130
        } else {
131
            throw new MissingPasswordHashServiceException(
132
                'No secure password hashing service could be initialized. Please check your TYPO3 system configuration',
133
                1557550040515
134
            );
135
        }
136
137
        return $password;
138
    }
139
140
    /**
141
     * Returns is there is a current user login
142
     *
143
     * @return bool
144
     */
145
    public function isUserLoggedIn()
146
    {
147
        return  $GLOBALS['TSFE']->loginUser;
148
    }
149
150
    /**
151
     * Returns the frontendUserAuthentication
152
     *
153
     * @return \TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
154
     */
155
    protected function getFrontendUser()
156
    {
157
        return $GLOBALS['TSFE']->fe_user;
158
    }
159
}
160