Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
47.62% |
30 / 63 |
|
16.67% |
1 / 6 |
CRAP | |
0.00% |
0 / 1 |
UserDomainDao | |
47.62% |
30 / 63 |
|
16.67% |
1 / 6 |
17.20 | |
0.00% |
0 / 1 |
selectLoginUser | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
2.00 | |||
selectEmailAndWaitTokenTimestamp | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
selectCacheItems | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
1 | |||
selectUserIdFromApiKey | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
6 | |||
selectUserItems | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
updateEmailFromWaitEmail | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace PeServer\App\Models\Dao\Domain; |
6 | |
7 | use DateTime; |
8 | use PeServer\App\Models\Cache\UserCache; |
9 | use PeServer\App\Models\Cache\UserCacheItem; |
10 | use PeServer\App\Models\Data\Dto\LoginUserDto; |
11 | use PeServer\App\Models\Data\Dto\UserListItemDto; |
12 | use PeServer\App\Models\Domain\UserLevel; |
13 | use PeServer\App\Models\Domain\UserState; |
14 | use PeServer\Core\Database\DaoBase; |
15 | use PeServer\Core\Database\DaoTrait; |
16 | use PeServer\Core\Database\DatabaseRowResult; |
17 | use PeServer\Core\Database\IDatabaseContext; |
18 | use PeServer\Core\TypeUtility; |
19 | use PeServer\Core\Utc; |
20 | |
21 | class UserDomainDao extends DaoBase |
22 | { |
23 | use DaoTrait; |
24 | |
25 | #region function |
26 | |
27 | /** |
28 | * @param string $loginId |
29 | * @phpstan-return LoginUserDto|null |
30 | */ |
31 | public function selectLoginUser(string $loginId): ?LoginUserDto |
32 | { |
33 | $result = $this->context->querySingleOrNull( |
34 | <<<SQL |
35 | |
36 | select |
37 | users.user_id, |
38 | users.login_id, |
39 | users.name, |
40 | users.level, |
41 | users.state, |
42 | user_authentications.current_password |
43 | from |
44 | users |
45 | inner join |
46 | user_authentications |
47 | on |
48 | ( |
49 | user_authentications.user_id = users.user_id |
50 | ) |
51 | where |
52 | users.login_id = :login_id |
53 | and |
54 | ( |
55 | users.state = 'enabled' |
56 | ) |
57 | |
58 | SQL, |
59 | [ |
60 | 'login_id' => $loginId, |
61 | ] |
62 | ); |
63 | |
64 | if ($result === null) { |
65 | return null; |
66 | } |
67 | |
68 | return $result->mapping(LoginUserDto::class); |
69 | } |
70 | |
71 | /** |
72 | * @template TFieldArray of array{email:string,wait_email:string,token_timestamp_utc:string} |
73 | * |
74 | * @param string $userId |
75 | * @phpstan-return DatabaseRowResult<TFieldArray> |
76 | */ |
77 | public function selectEmailAndWaitTokenTimestamp(string $userId, int $limitMinutes): DatabaseRowResult |
78 | { |
79 | /** @phpstan-var DatabaseRowResult<TFieldArray> */ |
80 | return $this->context->querySingle( |
81 | <<<SQL |
82 | |
83 | select |
84 | users.email, |
85 | IFNULL(user_change_wait_emails.email, '') as wait_email, |
86 | IFNULL(STRFTIME('%Y-%m-%dT%H:%M:%SZ', user_change_wait_emails.timestamp), '') as token_timestamp_utc |
87 | from |
88 | users |
89 | left join |
90 | user_change_wait_emails |
91 | on |
92 | ( |
93 | user_change_wait_emails.user_id = users.user_id |
94 | and |
95 | (STRFTIME('%s', CURRENT_TIMESTAMP) - STRFTIME('%s', user_change_wait_emails.timestamp)) < :limit_minutes * 60 |
96 | ) |
97 | where |
98 | users.user_id = :user_id |
99 | |
100 | SQL, |
101 | [ |
102 | 'user_id' => $userId, |
103 | 'limit_minutes' => $limitMinutes, |
104 | ] |
105 | ); |
106 | } |
107 | |
108 | /** |
109 | * Undocumented function |
110 | * |
111 | * @return UserCacheItem[] |
112 | */ |
113 | public function selectCacheItems(): array |
114 | { |
115 | $result = $this->context->query( |
116 | <<<SQL |
117 | |
118 | select |
119 | users.user_id, |
120 | users.name, |
121 | users.level, |
122 | users.state, |
123 | users.website, |
124 | users.description, |
125 | IFNULL(api_keys.api_key, '') as api_key, |
126 | IFNULL(api_keys.secret_key, '') as secret_key, |
127 | api_keys.created_timestamp as api_created_timestamp |
128 | from |
129 | users |
130 | left join |
131 | api_keys |
132 | on |
133 | ( |
134 | api_keys.user_id = users.user_id |
135 | ) |
136 | order by |
137 | users.user_id |
138 | |
139 | SQL |
140 | ); |
141 | |
142 | return array_map(function ($i) { |
143 | $rawApiTimestamp = $i['api_created_timestamp']; |
144 | /** @var DateTime|null */ |
145 | $apiTimestamp = null; |
146 | Utc::tryParseDateTime($rawApiTimestamp, $apiTimestamp); |
147 | |
148 | $cache = new UserCacheItem( |
149 | $i['user_id'], |
150 | $i['name'], |
151 | $i['level'], |
152 | $i['state'], |
153 | $i['website'], |
154 | $i['description'], |
155 | $i['api_key'], |
156 | $i['secret_key'], |
157 | $apiTimestamp |
158 | ); |
159 | |
160 | return $cache; |
161 | }, $result->rows); |
162 | } |
163 | |
164 | public function selectUserIdFromApiKey(string $apiKey, string $secretKey): ?string |
165 | { |
166 | // 特に何かとくっつける必要はないが将来的になんか項目が増えたら面倒なのでこのクラスに実装 |
167 | |
168 | /** @phpstan-var DatabaseRowResult<non-empty-array<string,string>>|null */ |
169 | $result = $this->context->querySingleOrNull( |
170 | <<<SQL |
171 | |
172 | select |
173 | api_keys.user_id |
174 | from |
175 | api_keys |
176 | where |
177 | api_keys.api_key = :api_key |
178 | and |
179 | api_keys.secret_key = :secret_key |
180 | |
181 | SQL, |
182 | [ |
183 | 'api_key' => $apiKey, |
184 | 'secret_key' => $secretKey, |
185 | ] |
186 | ); |
187 | |
188 | if ($result === null) { |
189 | return null; |
190 | } |
191 | |
192 | return $result->fields['user_id']; |
193 | } |
194 | |
195 | /** |
196 | * 管理用ユーザー一覧取得。 |
197 | * |
198 | * @phpstan-return UserListItemDto[] |
199 | */ |
200 | public function selectUserItems(): array |
201 | { |
202 | $result = $this->context->selectOrdered( |
203 | <<<SQL |
204 | |
205 | select |
206 | Users.user_id, |
207 | Users.login_id, |
208 | Users.name, |
209 | Users.state, |
210 | Users.level |
211 | from |
212 | Users |
213 | order by |
214 | case Users.state |
215 | when 'enabled' then 0 |
216 | when 'locked' then 1 |
217 | when 'disabled' then 2 |
218 | else 100 |
219 | end, |
220 | Users.name, |
221 | Users.login_id |
222 | |
223 | SQL, |
224 | ); |
225 | |
226 | return $result->mapping(UserListItemDto::class); |
227 | } |
228 | |
229 | |
230 | public function updateEmailFromWaitEmail(string $userId, string $token): bool |
231 | { |
232 | return $this->context->updateByKeyOrNothing( |
233 | <<<SQL |
234 | |
235 | update |
236 | users |
237 | set |
238 | email = ( |
239 | select |
240 | user_change_wait_emails.email |
241 | from |
242 | user_change_wait_emails |
243 | where |
244 | user_change_wait_emails.user_id = users.user_id |
245 | and |
246 | user_change_wait_emails.token = :token |
247 | ), |
248 | mark_email = ( |
249 | select |
250 | user_change_wait_emails.mark_email |
251 | from |
252 | user_change_wait_emails |
253 | where |
254 | user_change_wait_emails.user_id = users.user_id |
255 | and |
256 | user_change_wait_emails.token = :token |
257 | ) |
258 | where |
259 | users.user_id = :user_id |
260 | |
261 | SQL, |
262 | [ |
263 | 'user_id' => $userId, |
264 | 'token' => $token, |
265 | ] |
266 | ); |
267 | } |
268 | |
269 | #endregion |
270 | } |