]> jfr.im git - uguu.git/blob - static/php/includes/Core.namespace.php
142e5bf6dbdc46c7781ff339b286d3e7b4c1d204
[uguu.git] / static / php / includes / Core.namespace.php
1 <?php
2
3 /*
4 * Uguu
5 *
6 * @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22
23 namespace Core {
24
25 require_once 'Upload.class.php';
26
27 use Exception;
28 use PDO;
29 use Upload as Upload;
30
31 class Settings
32 {
33
34 public static mixed $DB;
35
36 public static string $DB_MODE;
37 public static string $DB_PATH;
38 public static string $DB_USER;
39 public static string $DB_PASS;
40
41 public static bool $LOG_IP;
42 public static bool $ANTI_DUPE;
43 public static bool $BLACKLIST_DB;
44 public static bool $FILTER_MODE;
45
46 public static string $FILES_ROOT;
47 public static int $FILES_RETRIES;
48
49 public static bool $SSL;
50 public static string $URL;
51
52 public static int $NAME_LENGTH;
53 public static string $ID_CHARSET;
54 public static array $BLOCKED_EXTENSIONS;
55 public static array $BLOCKED_MIME;
56
57
58 /**
59 * @throws Exception
60 */
61 public static function loadConfig()
62 {
63 if (!file_exists('/var/www/uguu/dist.json')) {
64 throw new Exception('Cant read settings file.', 500);
65 }
66 try {
67 $settings_array = json_decode(
68 file_get_contents('/var/www/uguu/dist.json'),
69 true
70 );
71 self::$DB_MODE = $settings_array['DB_MODE'];
72 self::$DB_PATH = $settings_array['DB_PATH'];
73 self::$DB_USER = $settings_array['DB_USER'];
74 self::$DB_PASS = $settings_array['DB_PASS'];
75 self::$LOG_IP = $settings_array['LOG_IP'];
76 self::$ANTI_DUPE = $settings_array['ANTI_DUPE'];
77 self::$BLACKLIST_DB = $settings_array['BLACKLIST_DB'];
78 self::$FILTER_MODE = $settings_array['FILTER_MODE'];
79 self::$FILES_ROOT = $settings_array['FILES_ROOT'];
80 self::$FILES_RETRIES = $settings_array['FILES_RETRIES'];
81 self::$SSL = $settings_array['SSL'];
82 self::$URL = $settings_array['URL'];
83 self::$NAME_LENGTH = $settings_array['NAME_LENGTH'];
84 self::$ID_CHARSET = $settings_array['ID_CHARSET'];
85 self::$BLOCKED_EXTENSIONS = $settings_array['BLOCKED_EXTENSIONS'];
86 self::$BLOCKED_MIME = $settings_array['BLOCKED_MIME'];
87 } catch (Exception) {
88 throw new Exception('Cant populate settings.', 500);
89 }
90 (new Database())->assemblePDO();
91 }
92 }
93
94 class cuteGrills
95 {
96 public static array $GRILLS;
97
98 public static function showGrills()
99 {
100 self::loadGrills();
101 if (!headers_sent()) {
102 header(
103 'Location: /img/grills/' .
104 self::$GRILLS[array_rand(self::$GRILLS)],
105 true,
106 303
107 );
108 }
109 }
110
111 public static function loadGrills()
112 {
113 self::$GRILLS = array_slice(scandir('img/grills/'), 2);
114 }
115 }
116
117 class Response
118 {
119 private mixed $type;
120
121 public function __construct($response_type = null)
122 {
123 switch ($response_type) {
124 case 'csv':
125 header('Content-Type: text/csv; charset=UTF-8');
126 $this->type = $response_type;
127 break;
128 case 'html':
129 header('Content-Type: text/html; charset=UTF-8');
130 $this->type = $response_type;
131 break;
132 case 'json':
133 header('Content-Type: application/json; charset=UTF-8');
134 $this->type = $response_type;
135 break;
136 case 'gyazo':
137 header('Content-Type: text/plain; charset=UTF-8');
138 $this->type = 'text';
139 break;
140 case 'text':
141 header('Content-Type: text/plain; charset=UTF-8');
142 $this->type = $response_type;
143 break;
144 default:
145 header('Content-Type: application/json; charset=UTF-8');
146 $this->type = 'json';
147 $this->error(400, 'Invalid response type. Valid options are: csv, html, json, text.');
148 break;
149 }
150 }
151
152 public function error($code, $desc)
153 {
154 $response = null;
155
156 switch ($this->type) {
157 case 'csv':
158 $response = $this->csvError($desc);
159 break;
160 case 'html':
161 $response = $this->htmlError($code, $desc);
162 break;
163 case 'json':
164 $response = $this->jsonError($code, $desc);
165 break;
166 case 'text':
167 $response = $this->textError($code, $desc);
168 break;
169 }
170 http_response_code($code);
171 echo $response;
172 }
173
174 private static function csvError($description): string
175 {
176 return '"error"' . "\r\n" . "\"$description\"" . "\r\n";
177 }
178
179 private static function htmlError($code, $description): string
180 {
181 return '<p>ERROR: (' . $code . ') ' . $description . '</p>';
182 }
183
184 private static function jsonError($code, $description): bool|string
185 {
186 return json_encode([
187 'success' => false,
188 'errorcode' => $code,
189 'description' => $description,
190 ], JSON_PRETTY_PRINT);
191 }
192
193
194 private static function textError($code, $description): string
195 {
196 return 'ERROR: (' . $code . ') ' . $description;
197 }
198
199 public function send($files)
200 {
201 $response = null;
202
203 switch ($this->type) {
204 case 'csv':
205 $response = $this->csvSuccess($files);
206 break;
207 case 'html':
208 $response = $this->htmlSuccess($files);
209 break;
210 case 'json':
211 $response = $this->jsonSuccess($files);
212 break;
213 case 'text':
214 $response = $this->textSuccess($files);
215 break;
216 }
217
218 http_response_code(200); // "200 OK". Success.
219 echo $response;
220 }
221
222 private static function csvSuccess($files): string
223 {
224 $result = '"name","url","hash","size"' . "\r\n";
225 foreach ($files as $file) {
226 $result .= '"' . $file['name'] . '"' . ',' .
227 '"' . $file['url'] . '"' . ',' .
228 '"' . $file['hash'] . '"' . ',' .
229 '"' . $file['size'] . '"' . "\r\n";
230 }
231
232 return $result;
233 }
234
235 private static function htmlSuccess($files): string
236 {
237 $result = '';
238
239 foreach ($files as $file) {
240 $result .= '<a href="' . $file['url'] . '">' . $file['url'] . '</a><br>';
241 }
242
243 return $result;
244 }
245
246 private static function jsonSuccess($files): bool|string
247 {
248 return json_encode([
249 'success' => true,
250 'files' => $files,
251 ], JSON_PRETTY_PRINT);
252 }
253
254 private static function textSuccess($files): string
255 {
256 $result = '';
257
258 foreach ($files as $file) {
259 $result .= $file['url'] . "\n";
260 }
261
262 return $result;
263 }
264 }
265
266 class Database
267 {
268 /**
269 * @throws Exception
270 */
271 public static function assemblePDO()
272 {
273 try {
274 Settings::$DB = new PDO(
275 Settings::$DB_MODE . ':' . Settings::$DB_PATH, Settings::$DB_USER,
276 Settings::$DB_PASS
277 );
278 } catch (Exception) {
279 throw new Exception('Cant connect to DB.', 500);
280 }
281 }
282
283 /**
284 * @throws Exception
285 */
286 public function dbCheckNameExists()
287 {
288 try {
289 $q = Settings::$DB->prepare('SELECT COUNT(filename) FROM files WHERE filename = (:name)');
290 $q->bindValue(':name', Upload::$NEW_NAME_FULL);
291 $q->execute();
292 return $q->fetchColumn();
293 } catch (Exception) {
294 throw new Exception('Cant check if name exists in DB.', 500);
295 }
296 }
297
298 /**
299 * @throws Exception
300 */
301 public function checkFileBlacklist()
302 {
303 try {
304 $q = Settings::$DB->prepare('SELECT hash, COUNT(*) AS count FROM blacklist WHERE hash = (:hash)');
305 $q->bindValue(':hash', Upload::$SHA1, PDO::PARAM_STR);
306 $q->execute();
307 $result = $q->fetch();
308 if ($result['count'] > 0) {
309 throw new Exception('File blacklisted!', 415);
310 }
311 } catch (Exception) {
312 throw new Exception('Cant check blacklist DB.', 500);
313 }
314 }
315
316 /**
317 * @throws Exception
318 */
319 public function antiDupe()
320 {
321 try {
322 $q = Settings::$DB->prepare(
323 'SELECT filename, COUNT(*) AS count FROM files WHERE hash = (:hash) AND size = (:size)'
324 );
325 $q->bindValue(':hash', Upload::$SHA1, PDO::PARAM_STR);
326 $q->bindValue(':size', Upload::$FILE_SIZE, PDO::PARAM_INT);
327 $q->execute();
328 $result = $q->fetch();
329 if ($result['count'] > 0) {
330 Upload::$NEW_NAME_FULL = $result['filename'];
331 }
332 } catch (Exception) {
333 throw new Exception('Cant check for dupes in DB.', 500);
334 }
335 }
336
337 /**
338 * @throws Exception
339 */
340 public function newIntoDB()
341 {
342 try {
343 $q = Settings::$DB->prepare(
344 'INSERT INTO files (hash, originalname, filename, size, date, ip)' .
345 'VALUES (:hash, :orig, :name, :size, :date, :ip)'
346 );
347 $q->bindValue(':hash', Upload::$SHA1, PDO::PARAM_STR);
348 $q->bindValue(':orig', strip_tags(Upload::$FILE_NAME), PDO::PARAM_STR);
349 $q->bindValue(':name', Upload::$NEW_NAME_FULL, PDO::PARAM_STR);
350 $q->bindValue(':size', Upload::$FILE_SIZE, PDO::PARAM_INT);
351 $q->bindValue(':date', time(), PDO::PARAM_STR);
352 $q->bindValue(':ip', Upload::$IP, PDO::PARAM_STR);
353 $q->execute();
354 } catch (Exception) {
355 throw new Exception('Cant insert into DB.', 500);
356 }
357 }
358 }
359 }
360
361
362