Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
23.26% covered (danger)
23.26%
10 / 43
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccountUserPasswordLogic
23.26% covered (danger)
23.26%
10 / 43
50.00% covered (danger)
50.00%
2 / 4
36.93
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 startup
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 validateImpl
9.52% covered (danger)
9.52%
2 / 21
0.00% covered (danger)
0.00%
0 / 1
15.85
 executeImpl
12.50% covered (danger)
12.50%
2 / 16
0.00% covered (danger)
0.00%
0 / 1
4.68
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\App\Models\Domain\Page\Account;
6
7use PeServer\Core\I18n;
8use PeServer\Core\Cryptography;
9use PeServer\Core\Text;
10use PeServer\App\Models\AuditLog;
11use PeServer\Core\Mvc\LogicCallMode;
12use PeServer\Core\Mvc\LogicParameter;
13use PeServer\App\Models\SessionKey;
14use PeServer\Core\Database\IDatabaseContext;
15use PeServer\App\Models\Domain\AccountValidator;
16use PeServer\App\Models\Domain\Page\PageLogicBase;
17use PeServer\App\Models\Dao\Entities\UserAuthenticationsEntityDao;
18
19class AccountUserPasswordLogic extends PageLogicBase
20{
21    public function __construct(LogicParameter $parameter)
22    {
23        parent::__construct($parameter);
24    }
25
26    #region PageLogicBase
27
28    protected function startup(LogicCallMode $callMode): void
29    {
30        $this->registerParameterKeys([
31            'account_password_current',
32            'account_password_new',
33            'account_password_confirm',
34        ], false);
35    }
36
37    protected function validateImpl(LogicCallMode $callMode): void
38    {
39        if ($callMode === LogicCallMode::Initialize) {
40            return;
41        }
42
43        $this->validation('account_password_current', function (string $key, string $value) {
44            $this->validator->isNotWhiteSpace($key, $value);
45
46            $userInfo = $this->requireSession(SessionKey::ACCOUNT);
47
48            $database = $this->openDatabase();
49            $userAuthenticationsEntityDao = new UserAuthenticationsEntityDao($database);
50            $passwords = $userAuthenticationsEntityDao->selectPassword($userInfo->userId);
51
52            if (!Cryptography::verifyPassword($value, $passwords->fields['current_password'])) {
53                $this->addError($key, I18n::message('error/password_incorrect'));
54            }
55        });
56
57        $this->validation('account_password_new', function (string $key, string $value) {
58            $accountValidator = new AccountValidator($this, $this->validator);
59            $accountValidator->isPassword($key, $value);
60        }, ['trim' => false]);
61
62        $this->validation('account_password_confirm', function (string $key, string $value) {
63            $this->validator->isNotWhiteSpace($key, $value);
64            $newPassword = $this->getRequest('account_password_new', Text::EMPTY, false);
65            if ($value !== $newPassword) {
66                $this->addError($key, I18n::message('error/password_confirm'));
67            }
68        });
69    }
70
71    protected function executeImpl(LogicCallMode $callMode): void
72    {
73        if ($callMode === LogicCallMode::Initialize) {
74            return;
75        }
76
77        $userInfo = $this->requireSession(SessionKey::ACCOUNT);
78
79        $newPassword = $this->getRequest('account_password_new', Text::EMPTY, false);
80
81        $params = [
82            'user_id' => $userInfo->userId,
83            'password' => Cryptography::hashPassword($newPassword),
84        ];
85
86        $database = $this->openDatabase();
87
88        $database->transaction(function (IDatabaseContext $context) use ($params) {
89            $userAuthenticationsEntityDao = new UserAuthenticationsEntityDao($context);
90            $userAuthenticationsEntityDao->updateCurrentPassword($params['user_id'], $params['password']);
91
92            $this->writeAuditLogCurrentUser(AuditLog::USER_PASSWORD_CHANGE, null, $context);
93
94            return true;
95        });
96
97
98        $this->addTemporaryMessage(I18n::message('message/flash/updated_password'));
99    }
100
101    #endregion
102}