]> git.mxchange.org Git - friendica.git/blob - src/Console/User.php
ccd3caa3797b6f39353f1f0c5beba9928df1fa6a
[friendica.git] / src / Console / User.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Console;
23
24 use Friendica\App;
25 use Friendica\Core\L10n;
26 use Friendica\Database\Database;
27 use Friendica\Model\Register;
28 use Friendica\Model\User as UserModel;
29 use RuntimeException;
30 use Seld\CliPrompt\CliPrompt;
31
32 /**
33  * tool to set a new password for a user
34  *
35  * With this tool, you can set a new password for a user
36  */
37 class User extends \Asika\SimpleConsole\Console
38 {
39         protected $helpOptions = ['h', 'help', '?'];
40
41         /**
42          * @var App\Mode
43          */
44         private $appMode;
45         /**
46          * @var L10n
47          */
48         private $l10n;
49         /**
50          * @var Database
51          */
52         private $dba;
53
54         protected function getHelp()
55         {
56                 $help = <<<HELP
57 console user - Modify user settings per console commands.
58 Usage
59         bin/console user password <nickname> [<password>] [-h|--help|-?] [-v]
60         bin/console user add [<name> [<nickname> [<email> [<language>]]]] [-h|--help|-?] [-v]
61         bin/console user delete [<nickname>] [-q] [-h|--help|-?] [-v]
62         bin/console user allow [<nickname>] [-h|--help|-?] [-v]
63         bin/console user deny [<nickname>] [-h|--help|-?] [-v]
64         bin/console user block [<nickname>] [-h|--help|-?] [-v]
65         bin/console user unblock [<nickname>] [-h|--help|-?] [-v]
66
67 Description
68         Modify user settings per console commands.
69
70 Options
71     -h|--help|-? Show help information
72     -v           Show more debug information.
73     -q           Quiet mode (don't ask for a command).
74 HELP;
75                 return $help;
76         }
77
78         public function __construct(App\Mode $appMode, L10n $l10n, Database $dba, array $argv = null)
79         {
80                 parent::__construct($argv);
81
82                 $this->appMode     = $appMode;
83                 $this->l10n        = $l10n;
84                 $this->dba         = $dba;
85         }
86
87         protected function doExecute()
88         {
89                 if ($this->getOption('v')) {
90                         $this->out('Class: ' . __CLASS__);
91                         $this->out('Arguments: ' . var_export($this->args, true));
92                         $this->out('Options: ' . var_export($this->options, true));
93                 }
94
95                 if (count($this->args) == 0) {
96                         $this->out($this->getHelp());
97                         return 0;
98                 }
99
100                 if ($this->appMode->isInstall()) {
101                         throw new RuntimeException('Database isn\'t ready or populated yet');
102                 }
103
104                 $command = $this->getArgument(0);
105
106                 switch ($command) {
107                         case 'password':
108                                 return $this->password();
109                         case 'add':
110                                 return $this->addUser();
111                         case 'allow':
112                                 return $this->pendingUser(true);
113                         case 'deny':
114                                 return $this->pendingUser(false);
115                         case 'block':
116                                 return $this->blockUser(true);
117                         case 'unblock':
118                                 return $this->blockUser(false);
119                         case 'delete':
120                                 return $this->deleteUser();
121                         default:
122                                 throw new \Asika\SimpleConsole\CommandArgsException('Wrong command.');
123                 }
124         }
125
126         /**
127          * Sets a new password
128          *
129          * @return int Return code of this command
130          *
131          * @throws \Exception
132          */
133         private function password()
134         {
135                 $nick = $this->getArgument(1);
136
137                 $user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
138                 if (!$this->dba->isResult($user)) {
139                         throw new RuntimeException($this->l10n->t('User not found'));
140                 }
141
142                 $password = $this->getArgument(2);
143
144                 if (is_null($password)) {
145                         $this->out($this->l10n->t('Enter new password: '), false);
146                         $password = CliPrompt::hiddenPrompt(true);
147                 }
148
149                 try {
150                         $result = UserModel::updatePassword($user['uid'], $password);
151
152                         if (!$this->dba->isResult($result)) {
153                                 throw new \Exception($this->l10n->t('Password update failed. Please try again.'));
154                         }
155
156                         $this->out($this->l10n->t('Password changed.'));
157                 } catch (\Exception $e) {
158                         throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
159                 }
160
161                 return 0;
162         }
163
164         /**
165          * Adds a new user based on given console arguments
166          *
167          * @return bool True, if the command was successful
168          * @throws \ErrorException
169          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
170          * @throws \ImagickException
171          */
172         private function addUser()
173         {
174                 $name  = $this->getArgument(1);
175                 $nick  = $this->getArgument(2);
176                 $email = $this->getArgument(3);
177                 $lang  = $this->getArgument(4);
178
179                 if (empty($name)) {
180                         $this->out($this->l10n->t('Enter user name: '));
181                         $name = CliPrompt::prompt();
182                         if (empty($name)) {
183                                 throw new RuntimeException('A name must be set.');
184                         }
185                 }
186
187                 if (empty($nick)) {
188                         $this->out($this->l10n->t('Enter user nickname: '));
189                         $nick = CliPrompt::prompt();
190                         if (empty($nick)) {
191                                 throw new RuntimeException('A nick name must be set.');
192                         }
193                 }
194
195                 if (empty($email)) {
196                         $this->out($this->l10n->t('Enter user email address: '));
197                         $email = CliPrompt::prompt();
198                         if (empty($email)) {
199                                 throw new RuntimeException('A email address must be set.');
200                         }
201                 }
202
203                 if (empty($lang)) {
204                         $this->out($this->l10n->t('Enter a language (optional): '));
205                         $lang = CliPrompt::prompt();
206                 }
207
208                 if (empty($lang)) {
209                         return UserModel::createMinimal($name, $email, $nick);
210                 } else {
211                         return UserModel::createMinimal($name, $email, $nick, $lang);
212                 }
213         }
214
215         /**
216          * Allows or denys a user based on it's nickname
217          *
218          * @param bool $allow True, if the pending user is allowed, false if denies
219          *
220          * @return bool True, if allow was successful
221          * @throws \Friendica\Network\HTTPException\InternalServerErrorException
222          */
223         private function pendingUser(bool $allow = true)
224         {
225                 $nick = $this->getArgument(1);
226
227                 if (!$nick) {
228                         $this->out($this->l10n->t('Enter user nickname: '));
229                         $nick = CliPrompt::prompt();
230                         if (empty($nick)) {
231                                 throw new RuntimeException('A nick name must be set.');
232                         }
233                 }
234
235                 $user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
236                 if (empty($user)) {
237                         throw new RuntimeException($this->l10n->t('User not found'));
238                 }
239
240                 $pending = Register::getPendingForUser($user['uid'] ?? 0);
241                 if (empty($pending)) {
242                         throw new RuntimeException($this->l10n->t('User is not pending.'));
243                 }
244
245                 return ($allow) ? UserModel::allow($pending['hash']) : UserModel::deny($pending['hash']);
246         }
247
248         /**
249          * Blocks/unblocks a user
250          *
251          * @param bool $block True, if the given user should get blocked
252          *
253          * @return bool True, if the command was successful
254          * @throws \Exception
255          */
256         private function blockUser(bool $block = true)
257         {
258                 $nick = $this->getArgument(1);
259
260                 if (!$nick) {
261                         $this->out($this->l10n->t('Enter user nickname: '));
262                         $nick = CliPrompt::prompt();
263                         if (empty($nick)) {
264                                 throw new RuntimeException('A nick name must be set.');
265                         }
266                 }
267
268                 $user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
269                 if (empty($user)) {
270                         throw new RuntimeException($this->l10n->t('User not found'));
271                 }
272
273                 return $block ? UserModel::block($user['uid'] ?? 0) : UserModel::block($user['uid'] ?? 0, false);
274         }
275
276         /**
277          * Deletes a user
278          *
279          * @return bool True, if the delete was successful
280          * @throws \Exception
281          */
282         private function deleteUser()
283         {
284                 $nick = $this->getArgument(1);
285
286                 if (!$nick) {
287                         $this->out($this->l10n->t('Enter user nickname: '));
288                         $nick = CliPrompt::prompt();
289                         if (empty($nick)) {
290                                 throw new RuntimeException('A nick name must be set.');
291                         }
292                 }
293
294                 $user = $this->dba->selectFirst('user', ['uid'], ['nickname' => $nick]);
295                 if (empty($user)) {
296                         throw new RuntimeException($this->l10n->t('User not found'));
297                 }
298
299                 if (!$this->getOption('q')) {
300                         $this->out($this->l10n->t('Type "yes" to delete %s', $nick));
301                         if (CliPrompt::prompt() !== 'yes') {
302                                 throw new RuntimeException('Delete abort.');
303                         }
304                 }
305
306                 return UserModel::remove($user['uid'] ?? -1);
307         }
308 }