]> git.mxchange.org Git - friendica.git/blob - src/Console/ServerBlock.php
spelling: unable
[friendica.git] / src / Console / ServerBlock.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
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 Asika\SimpleConsole\CommandArgsException;
25 use Asika\SimpleConsole\Console;
26 use Console_Table;
27 use Friendica\Core\Worker;
28 use Friendica\Moderation\DomainPatternBlocklist;
29
30 /**
31  * Manage blocked servers
32  *
33  * With this tool, you can list the current blocked servers
34  * or you can add / remove a blocked server from the list
35  */
36 class ServerBlock extends Console
37 {
38         protected $helpOptions = ['h', 'help', '?'];
39
40         /** @var DomainPatternBlocklist */
41         private $blocklist;
42
43         protected function getHelp(): string
44         {
45                 return <<<HELP
46 console serverblock - Manage blocked server domain patterns
47 Usage
48     bin/console serverblock [-h|--help|-?] [-v]
49     bin/console serverblock add <pattern> <reason> [-h|--help|-?] [-v]
50     bin/console serverblock remove <pattern> [-h|--help|-?] [-v]
51     bin/console serverblock export <filename>
52     bin/console serverblock import <filename>
53
54 Description
55     With this tool, you can list the current blocked server domain patterns
56     or you can add / remove a blocked server domain pattern from the list.
57     Using the export and import options you can share your server blocklist
58     with other node admins by CSV files.
59
60     Patterns are case-insensitive shell wildcard comprising the following special characters:
61     - * : Any number of characters
62     - ? : Any single character
63     - [<char1><char2>...] : char1 or char2 or...
64
65 Options
66     -h|--help|-? Show help information
67     -v           Show more debug information.
68 HELP;
69         }
70
71         public function __construct(DomainPatternBlocklist $blocklist, $argv = null)
72         {
73                 parent::__construct($argv);
74
75                 $this->blocklist = $blocklist;
76         }
77
78         protected function doExecute(): int
79         {
80                 if (count($this->args) == 0) {
81                         $this->printBlockedServers();
82                         return 0;
83                 }
84
85                 switch ($this->getArgument(0)) {
86                         case 'add':
87                                 return $this->addBlockedServer();
88                         case 'remove':
89                                 return $this->removeBlockedServer();
90                         case 'export':
91                                 return $this->exportBlockedServers();
92                         case 'import':
93                                 return $this->importBlockedServers();
94                         default:
95                                 throw new CommandArgsException('Unknown command.');
96                 }
97         }
98
99         /**
100          * Exports the list of blocked domain patterns including the reason for the
101          * block to a CSV file.
102          *
103          * @return int
104          * @throws \Exception
105          */
106         private function exportBlockedServers(): int
107         {
108                 $filename = $this->getArgument(1);
109
110                 if (empty($filename)) {
111                         $this->out('A file name is required, e.g. ./bin/console serverblock export backup.csv');
112                         return 1;
113                 }
114
115                 $this->blocklist->exportToFile($filename);
116
117                 // Success
118                 return 0;
119         }
120
121         /**
122          * Imports a list of domain patterns and a reason for the block from a CSV
123          * file, e.g. created with the export function.
124          *
125          * @return int
126          * @throws \Exception
127          */
128         private function importBlockedServers(): int
129         {
130                 $filename = $this->getArgument(1);
131
132                 $newBlockList = $this->blocklist::extractFromCSVFile($filename);
133
134                 if ($this->blocklist->append($newBlockList)) {
135                         $this->out(sprintf("Entries from %s that were not blocked before are now blocked", $filename));
136                         Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
137                         return 0;
138                 } else {
139                         $this->out("Couldn't save the block list");
140                         return 1;
141                 }
142         }
143
144         /**
145          * Prints the whole list of blocked domain patterns including the reason
146          */
147         private function printBlockedServers(): void
148         {
149                 $table = new Console_Table();
150                 $table->setHeaders(['Pattern', 'Reason']);
151                 foreach ($this->blocklist->get() as $pattern) {
152                         $table->addRow($pattern);
153                 }
154
155                 $this->out($table->getTable());
156         }
157
158         /**
159          * Adds a domain pattern to the block list
160          *
161          * @return int The return code (0 = success, 1 = failed)
162          */
163         private function addBlockedServer(): int
164         {
165                 if (count($this->args) != 3) {
166                         throw new CommandArgsException('Add needs a domain pattern and a reason.');
167                 }
168
169                 $pattern = $this->getArgument(1);
170                 $reason  = $this->getArgument(2);
171
172                 $result = $this->blocklist->addPattern($pattern, $reason);
173                 if ($result) {
174                         if ($result == 2) {
175                                 $this->out(sprintf("The domain pattern '%s' is now updated. (Reason: '%s')", $pattern, $reason));
176                         } else {
177                                 $this->out(sprintf("The domain pattern '%s' is now blocked. (Reason: '%s')", $pattern, $reason));
178                         }
179                         Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
180                         return 0;
181                 } else {
182                         $this->out(sprintf("Couldn't save '%s' as blocked domain pattern", $pattern));
183                         return 1;
184                 }
185         }
186
187         /**
188          * Removes a domain pattern from the block list
189          *
190          * @return int The return code (0 = success, 1 = failed)
191          */
192         private function removeBlockedServer(): int
193         {
194                 if (count($this->args) !== 2) {
195                         throw new CommandArgsException('Remove needs a second parameter.');
196                 }
197
198                 $pattern = $this->getArgument(1);
199
200                 $result = $this->blocklist->removePattern($pattern);
201                 if ($result) {
202                         if ($result == 2) {
203                                 $this->out(sprintf("The domain pattern '%s' isn't blocked anymore", $pattern));
204                                 Worker::add(Worker::PRIORITY_LOW, 'UpdateBlockedServers');
205                                 return 0;
206                         } else {
207                                 $this->out(sprintf("The domain pattern '%s' wasn't blocked.", $pattern));
208                                 return 1;
209                         }
210                 } else {
211                         $this->out(sprintf("Couldn't remove '%s' from blocked domain patterns", $pattern));
212                         return 1;
213                 }
214         }
215 }