Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.92% covered (success)
97.92%
47 / 48
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccountUserApiLogic
97.92% covered (success)
97.92%
47 / 48
75.00% covered (warning)
75.00%
3 / 4
11
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%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 validateImpl
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 executeImpl
97.44% covered (success)
97.44%
38 / 39
0.00% covered (danger)
0.00%
0 / 1
7
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\App\Models\Domain\Page\Account;
6
7use Error;
8use PeServer\App\Models\AppDatabaseCache;
9use PeServer\App\Models\AuditLog;
10use PeServer\App\Models\Dao\Entities\ApiKeysEntityDao;
11use PeServer\App\Models\Domain\ApiUtility;
12use PeServer\App\Models\Domain\Page\PageLogicBase;
13use PeServer\App\Models\Data\SessionAccount;
14use PeServer\App\Models\SessionKey;
15use PeServer\Core\Mvc\LogicCallMode;
16use PeServer\Core\Mvc\LogicParameter;
17
18class AccountUserApiLogic extends PageLogicBase
19{
20    private const API_KEY_RETRY_COUNT = 10;
21    private bool $isRegister = false;
22
23    public function __construct(LogicParameter $parameter, private AppDatabaseCache $dbCache)
24    {
25        parent::__construct($parameter);
26    }
27
28    #region PageLogicBase
29
30    protected function startup(LogicCallMode $callMode): void
31    {
32        /** @var SessionAccount */
33        $userInfo = $this->requireSession(SessionKey::ACCOUNT);
34
35        $database = $this->openDatabase();
36        $apiKeysEntityDao = new ApiKeysEntityDao($database);
37        $exist = $apiKeysEntityDao->selectExistsApiKeyByUserId($userInfo->userId);
38        $this->isRegister = !$exist;
39        $this->setValue('from_account_api_is_register', $this->isRegister);
40    }
41
42    protected function validateImpl(LogicCallMode $callMode): void
43    {
44        if ($callMode === LogicCallMode::Initialize) {
45            return;
46        }
47    }
48
49    protected function executeImpl(LogicCallMode $callMode): void
50    {
51        /** @var SessionAccount */
52        $userInfo = $this->requireSession(SessionKey::ACCOUNT);
53
54        if ($callMode === LogicCallMode::Initialize) {
55            if (!$this->isRegister) {
56                $database = $this->openDatabase();
57                $apiKeysEntityDao = new ApiKeysEntityDao($database);
58                $apiKeyInfo = $apiKeysEntityDao->selectApiKeyByUserId($userInfo->userId);
59
60                $this->setValue('api_key', $apiKeyInfo->fields['api_key']);
61                $this->setValue('created_timestamp', $apiKeyInfo->fields['created_timestamp']);
62            }
63
64            $secret = $this->popTemporary('secret_key');
65            $this->setValue('secret_key', $secret);
66
67            return;
68        }
69
70        $database = $this->openDatabase();
71        if ($this->isRegister) {
72            $secret = ApiUtility::generateSecret();
73
74            $database->transaction(function ($context) use ($userInfo, $secret) {
75                $apiKeysEntityDao = new ApiKeysEntityDao($context);
76
77                $apiKey = '';
78                $existsApiKey = true;
79                for ($i = 0; $existsApiKey && $i < self::API_KEY_RETRY_COUNT; $i++) {
80                    $apiKey = ApiUtility::generateKey();
81                    $existsApiKey = $apiKeysEntityDao->selectExistsApiKeyByApiKey($apiKey);
82                }
83                if ($existsApiKey) {
84                    throw new Error((string)self::API_KEY_RETRY_COUNT);
85                }
86
87                $apiKeysEntityDao->insertApiKey($userInfo->userId, $apiKey, $secret);
88
89                $this->writeAuditLogCurrentUser(AuditLog::USER_API_KEY_REGISTER, ['api_key' => $apiKey, 'secret' => $secret], $context);
90
91                return true;
92            });
93
94            $this->addTemporaryMessage('APIキーを登録しました');
95            $this->addTemporaryMessage('シークレットキーは大事に保存してください');
96
97            $this->pushTemporary('secret_key', $secret);
98        } else {
99            $database->transaction(function ($context) use ($userInfo) {
100                $apiKeysEntityDao = new ApiKeysEntityDao($context);
101                $apiKeysEntityDao->deleteApiKeyByUserId($userInfo->userId);
102
103                $this->writeAuditLogCurrentUser(AuditLog::USER_API_KEY_UNREGISTER, null, $context);
104
105                return true;
106            });
107
108            $this->addTemporaryMessage('APIキーを削除しました');
109            $this->removeTemporary('secret_key');
110        }
111
112        $this->dbCache->exportUserInformation();
113    }
114
115    #endregion
116}