mirror of
https://github.com/nokonoko/Uguu.git
synced 2024-01-06 13:35:15 +00:00
test
This commit is contained in:
parent
83f6699d7f
commit
cec6349edd
@ -1,51 +1,50 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* Uguu
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pomf\Uguu\Classes;
|
|
||||||
|
|
||||||
class CuteGrills
|
|
||||||
{
|
|
||||||
public array $GRILLS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the list of grills, then redirects to a random grill
|
* Uguu
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
public function showGrills(): void
|
|
||||||
|
namespace Uguu\Classes;
|
||||||
|
|
||||||
|
class CuteGrills
|
||||||
{
|
{
|
||||||
$this->loadGrills();
|
public array $GRILLS;
|
||||||
if (!headers_sent()) {
|
|
||||||
header(
|
/**
|
||||||
'Location: /img/grills/' .
|
* Loads the list of grills, then redirects to a random grill
|
||||||
$this->GRILLS[array_rand($this->GRILLS)],
|
*/
|
||||||
true,
|
public function showGrills():void
|
||||||
303
|
{
|
||||||
);
|
$this->loadGrills();
|
||||||
|
if (!headers_sent()) {
|
||||||
|
header(
|
||||||
|
'Location: /img/grills/' .
|
||||||
|
$this->GRILLS[array_rand($this->GRILLS)],
|
||||||
|
true,
|
||||||
|
303,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the images from the `img/grills/` directory into the `GRILLS` array
|
||||||
|
*/
|
||||||
|
public function loadGrills():void
|
||||||
|
{
|
||||||
|
$this->GRILLS = array_slice(scandir('img/grills/'), 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the images from the `img/grills/` directory into the `GRILLS` array
|
|
||||||
*/
|
|
||||||
public function loadGrills(): void
|
|
||||||
{
|
|
||||||
$this->GRILLS = array_slice(scandir('img/grills/'), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,227 +1,219 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* Uguu
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pomf\Uguu\Classes;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use PDO;
|
|
||||||
|
|
||||||
class Database
|
|
||||||
{
|
|
||||||
private PDO $DB;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of the DB variable.
|
* Uguu
|
||||||
*
|
*
|
||||||
* @param $DB PDO The database connection.
|
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
public function setDB(PDO $DB): void
|
|
||||||
{
|
|
||||||
$this->DB = $DB;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
namespace Uguu\Classes;
|
||||||
* Checks if a file name exists in the database
|
|
||||||
*
|
use Exception;
|
||||||
* @param $name string The name of the file.
|
use PDO;
|
||||||
*
|
|
||||||
* @return int The number of rows that match the query.
|
class Database
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function dbCheckNameExists(string $name): int
|
|
||||||
{
|
{
|
||||||
try {
|
private PDO $DB;
|
||||||
$q = $this->DB->prepare('SELECT COUNT(filename) FROM files WHERE filename = (:name)');
|
|
||||||
$q->bindValue(':name', $name);
|
/**
|
||||||
$q->execute();
|
* Sets the value of the DB variable.
|
||||||
return $q->fetchColumn();
|
*
|
||||||
} catch (Exception) {
|
* @param $DB PDO The database connection.
|
||||||
throw new Exception('Cant check if name exists in DB.', 500);
|
*/
|
||||||
|
public function setDB(PDO $DB):void
|
||||||
|
{
|
||||||
|
$this->DB = $DB;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the file is blacklisted
|
* Checks if a file name exists in the database
|
||||||
*
|
*
|
||||||
* @param $FILE_INFO array An array containing the following:
|
* @param $name string The name of the file.
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @return int The number of rows that match the query.
|
||||||
*/
|
* @throws \Exception
|
||||||
public function checkFileBlacklist(array $FILE_INFO): void
|
*/
|
||||||
{
|
public function dbCheckNameExists(string $name):int
|
||||||
try {
|
{
|
||||||
$q = $this->DB->prepare('SELECT hash, COUNT(*) AS count FROM blacklist WHERE hash = (:hash)');
|
try {
|
||||||
$q->bindValue(':hash', $FILE_INFO['SHA1']);
|
$q = $this->DB->prepare('SELECT COUNT(filename) FROM files WHERE filename = (:name)');
|
||||||
$q->execute();
|
$q->bindValue(':name', $name);
|
||||||
$result = $q->fetch();
|
$q->execute();
|
||||||
if ($result['count'] > 0) {
|
return $q->fetchColumn();
|
||||||
throw new Exception('File blacklisted!', 415);
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new Exception('Cant check if name exists in DB.', 500);
|
||||||
}
|
}
|
||||||
} catch (Exception) {
|
|
||||||
throw new Exception('Cant check blacklist DB.', 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the file already exists in the database
|
|
||||||
*
|
|
||||||
* @param $hash string The hash of the file you want to check for.
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function antiDupe(string $hash): bool | array | string
|
|
||||||
{
|
|
||||||
if (!$this->CONFIG['ANTI_DUPE']) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
/**
|
||||||
$q = $this->DB->prepare(
|
* Checks if the file is blacklisted
|
||||||
'SELECT filename, COUNT(*) AS count FROM files WHERE hash = (:hash)'
|
*
|
||||||
);
|
* @param $FILE_INFO array An array containing the following:
|
||||||
$q->bindValue(':hash', $hash);
|
*
|
||||||
$q->execute();
|
* @throws \Exception
|
||||||
$result = $q->fetch();
|
*/
|
||||||
if ($result['count'] > 0) {
|
public function checkFileBlacklist(array $FILE_INFO):void
|
||||||
return $result['filename'];
|
{
|
||||||
} else {
|
try {
|
||||||
|
$q = $this->DB->prepare('SELECT hash, COUNT(*) AS count FROM blacklist WHERE hash = (:hash)');
|
||||||
|
$q->bindValue(':hash', $FILE_INFO['SHA1']);
|
||||||
|
$q->execute();
|
||||||
|
$result = $q->fetch();
|
||||||
|
if ($result['count'] > 0) {
|
||||||
|
throw new Exception('File blacklisted!', 415);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new Exception('Cant check blacklist DB.', 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the file already exists in the database
|
||||||
|
*
|
||||||
|
* @param $hash string The hash of the file you want to check for.
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function antiDupe(string $hash):bool|array|string
|
||||||
|
{
|
||||||
|
if (!$this->CONFIG['ANTI_DUPE']) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Exception) {
|
try {
|
||||||
throw new Exception('Cant check for dupes in DB.', 500);
|
$q = $this->DB->prepare(
|
||||||
|
'SELECT filename, COUNT(*) AS count FROM files WHERE hash = (:hash)',
|
||||||
|
);
|
||||||
|
$q->bindValue(':hash', $hash);
|
||||||
|
$q->execute();
|
||||||
|
$result = $q->fetch();
|
||||||
|
if ($result['count'] > 0) {
|
||||||
|
return $result['filename'];
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
throw new Exception('Cant check for dupes in DB.', 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a new file into the database
|
* Inserts a new file into the database
|
||||||
*
|
*
|
||||||
* @param $FILE_INFO array
|
* @param $FILE_INFO array
|
||||||
* @param $fingerPrintInfo array
|
* @param $fingerPrintInfo array
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function newIntoDB(array $FILE_INFO, array $fingerPrintInfo): void
|
public function newIntoDB(array $FILE_INFO, array $fingerPrintInfo):void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$q = $this->DB->prepare(
|
$q = $this->DB->prepare(
|
||||||
'INSERT INTO files (hash, originalname, filename, size, date, ip)' .
|
'INSERT INTO files (hash, originalname, filename, size, date, ip)' .
|
||||||
'VALUES (:hash, :orig, :name, :size, :date, :ip)'
|
'VALUES (:hash, :orig, :name, :size, :date, :ip)',
|
||||||
);
|
);
|
||||||
$q->bindValue(':hash', $FILE_INFO['SHA1']);
|
$q->bindValue(':hash', $FILE_INFO['SHA1']);
|
||||||
$q->bindValue(':orig', $FILE_INFO['NAME']);
|
$q->bindValue(':orig', $FILE_INFO['NAME']);
|
||||||
$q->bindValue(':name', $FILE_INFO['NEW_NAME']);
|
$q->bindValue(':name', $FILE_INFO['NEW_NAME']);
|
||||||
$q->bindValue(':size', $FILE_INFO['SIZE'], PDO::PARAM_INT);
|
$q->bindValue(':size', $FILE_INFO['SIZE'], PDO::PARAM_INT);
|
||||||
$q->bindValue(':date', $fingerPrintInfo['timestamp']);
|
$q->bindValue(':date', $fingerPrintInfo['timestamp']);
|
||||||
$q->bindValue(':ip', $fingerPrintInfo['ip']);
|
$q->bindValue(':ip', $fingerPrintInfo['ip']);
|
||||||
$q->execute();
|
$q->execute();
|
||||||
} catch (Exception) {
|
}
|
||||||
throw new Exception('Cant insert into DB.', 500);
|
catch (Exception) {
|
||||||
|
throw new Exception('Cant insert into DB.', 500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* Creates a new row in the database with the information provided
|
||||||
* Creates a new row in the database with the information provided
|
*
|
||||||
*
|
* @param $fingerPrintInfo array
|
||||||
* @param $fingerPrintInfo array
|
*/
|
||||||
*/
|
public function createRateLimit(array $fingerPrintInfo):void
|
||||||
public function createRateLimit(array $fingerPrintInfo): void
|
{
|
||||||
{
|
|
||||||
$q = $this->DB->prepare(
|
|
||||||
'INSERT INTO timestamp (iphash, files, time)' .
|
|
||||||
'VALUES (:iphash, :files, :time)'
|
|
||||||
);
|
|
||||||
|
|
||||||
$q->bindValue(':iphash', $fingerPrintInfo['ip_hash']);
|
|
||||||
$q->bindValue(':files', $fingerPrintInfo['files_amount']);
|
|
||||||
$q->bindValue(':time', $fingerPrintInfo['timestamp']);
|
|
||||||
$q->execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the rate limit table with the new file count and timestamp
|
|
||||||
*
|
|
||||||
* @param $fCount int The number of files uploaded by the user.
|
|
||||||
* @param $iStamp boolean A boolean value that determines whether or not to update the timestamp.
|
|
||||||
* @param $fingerPrintInfo array An array containing the following keys:
|
|
||||||
*/
|
|
||||||
public function updateRateLimit(int $fCount, bool $iStamp, array $fingerPrintInfo): void
|
|
||||||
{
|
|
||||||
if ($iStamp) {
|
|
||||||
$q = $this->DB->prepare(
|
$q = $this->DB->prepare(
|
||||||
'UPDATE ratelimit SET files = (:files), time = (:time) WHERE iphash = (:iphash)'
|
'INSERT INTO timestamp (iphash, files, time)' .
|
||||||
|
'VALUES (:iphash, :files, :time)',
|
||||||
);
|
);
|
||||||
|
$q->bindValue(':iphash', $fingerPrintInfo['ip_hash']);
|
||||||
|
$q->bindValue(':files', $fingerPrintInfo['files_amount']);
|
||||||
$q->bindValue(':time', $fingerPrintInfo['timestamp']);
|
$q->bindValue(':time', $fingerPrintInfo['timestamp']);
|
||||||
} else {
|
$q->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the rate limit table with the new file count and timestamp
|
||||||
|
*
|
||||||
|
* @param $fCount int The number of files uploaded by the user.
|
||||||
|
* @param $iStamp boolean A boolean value that determines whether or not to update the timestamp.
|
||||||
|
* @param $fingerPrintInfo array An array containing the following keys:
|
||||||
|
*/
|
||||||
|
public function updateRateLimit(int $fCount, bool $iStamp, array $fingerPrintInfo):void
|
||||||
|
{
|
||||||
|
if ($iStamp) {
|
||||||
|
$q = $this->DB->prepare(
|
||||||
|
'UPDATE ratelimit SET files = (:files), time = (:time) WHERE iphash = (:iphash)',
|
||||||
|
);
|
||||||
|
$q->bindValue(':time', $fingerPrintInfo['timestamp']);
|
||||||
|
} else {
|
||||||
|
$q = $this->DB->prepare(
|
||||||
|
'UPDATE ratelimit SET files = (:files) WHERE iphash = (:iphash)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$q->bindValue(':files', $fCount);
|
||||||
|
$q->bindValue(':iphash', $fingerPrintInfo['ip_hash']);
|
||||||
|
$q->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the user has uploaded more than 100 files in the last minute, if so it returns true, if not it updates the database with the new file
|
||||||
|
* count and timestamp
|
||||||
|
*
|
||||||
|
* @param $fingerPrintInfo array An array containing the following:
|
||||||
|
*
|
||||||
|
* @return bool A boolean value.
|
||||||
|
*/
|
||||||
|
public function checkRateLimit(array $fingerPrintInfo):bool
|
||||||
|
{
|
||||||
$q = $this->DB->prepare(
|
$q = $this->DB->prepare(
|
||||||
'UPDATE ratelimit SET files = (:files) WHERE iphash = (:iphash)'
|
'SELECT files, time, iphash, COUNT(*) AS count FROM ratelimit WHERE iphash = (:iphash)',
|
||||||
);
|
);
|
||||||
}
|
$q->bindValue(':iphash', $fingerPrintInfo['ip_hash']);
|
||||||
|
$q->execute();
|
||||||
$q->bindValue(':files', $fCount);
|
$result = $q->fetch();
|
||||||
$q->bindValue(':iphash', $fingerPrintInfo['ip_hash']);
|
$nTime = $fingerPrintInfo['timestamp'] - (60);
|
||||||
$q->execute();
|
switch (true) {
|
||||||
}
|
//If more then 100 files trigger rate-limit
|
||||||
|
case $result['files'] > 100:
|
||||||
|
return true;
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the user has uploaded more than 100 files in the last minute, if so it returns true, if not it updates the database with the new file count and
|
|
||||||
* timestamp
|
|
||||||
*
|
|
||||||
* @param $fingerPrintInfo array An array containing the following:
|
|
||||||
*
|
|
||||||
* @return bool A boolean value.
|
|
||||||
*/
|
|
||||||
public function checkRateLimit(array $fingerPrintInfo): bool
|
|
||||||
{
|
|
||||||
$q = $this->DB->prepare(
|
|
||||||
'SELECT files, time, iphash, COUNT(*) AS count FROM ratelimit WHERE iphash = (:iphash)'
|
|
||||||
);
|
|
||||||
$q->bindValue(':iphash', $fingerPrintInfo['ip_hash']);
|
|
||||||
$q->execute();
|
|
||||||
$result = $q->fetch();
|
|
||||||
|
|
||||||
$nTime = $fingerPrintInfo['timestamp'] - (60);
|
|
||||||
|
|
||||||
switch (true) {
|
|
||||||
//If more then 100 files trigger rate-limit
|
|
||||||
case $result['files'] > 100:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//if timestamp is older than one minute, set new files count and timestamp
|
//if timestamp is older than one minute, set new files count and timestamp
|
||||||
case $result['time'] < $nTime:
|
case $result['time'] < $nTime:
|
||||||
$this->updateRateLimit($fingerPrintInfo['files_amount'], true, $fingerPrintInfo);
|
$this->updateRateLimit($fingerPrintInfo['files_amount'], true, $fingerPrintInfo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//if timestamp isn't older than one-minute update the files count
|
//if timestamp isn't older than one-minute update the files count
|
||||||
case $result['time'] > $nTime:
|
case $result['time'] > $nTime:
|
||||||
$this->updateRateLimit($fingerPrintInfo['files_amount'] + $result['files'], false, $fingerPrintInfo);
|
$this->updateRateLimit($fingerPrintInfo['files_amount'] + $result['files'], false, $fingerPrintInfo);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//If there is no other match a record does not exist, create one
|
//If there is no other match a record does not exist, create one
|
||||||
default:
|
default:
|
||||||
$this->createRateLimit($fingerPrintInfo);
|
$this->createRateLimit($fingerPrintInfo);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,222 +1,214 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* Uguu
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pomf\Uguu\Classes;
|
|
||||||
|
|
||||||
class Response
|
|
||||||
{
|
|
||||||
public mixed $type;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a string as an argument and sets the header to the appropriate content type
|
* Uguu
|
||||||
*
|
*
|
||||||
* @param $response_type string The type of response you want to return. Valid options are: csv, html, json, text.
|
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
public function __construct(string $response_type = "json")
|
|
||||||
|
namespace Uguu\Classes;
|
||||||
|
|
||||||
|
class Response
|
||||||
{
|
{
|
||||||
switch ($response_type) {
|
public mixed $type;
|
||||||
case 'csv':
|
|
||||||
header('Content-Type: text/csv; charset=UTF-8');
|
|
||||||
$this->type = $response_type;
|
|
||||||
break;
|
|
||||||
case 'html':
|
|
||||||
header('Content-Type: text/html; charset=UTF-8');
|
|
||||||
$this->type = $response_type;
|
|
||||||
break;
|
|
||||||
case 'json':
|
|
||||||
header('Content-Type: application/json; charset=UTF-8');
|
|
||||||
$this->type = $response_type;
|
|
||||||
break;
|
|
||||||
case 'gyazo':
|
|
||||||
header('Content-Type: text/plain; charset=UTF-8');
|
|
||||||
$this->type = 'text';
|
|
||||||
break;
|
|
||||||
case 'text':
|
|
||||||
header('Content-Type: text/plain; charset=UTF-8');
|
|
||||||
$this->type = $response_type;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
header('Content-Type: application/json; charset=UTF-8');
|
|
||||||
$this->type = 'json';
|
|
||||||
$this->error(400, 'Invalid response type. Valid options are: csv, html, json, text.');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string based on the type of response requested
|
* Takes a string as an argument and sets the header to the appropriate content type
|
||||||
*
|
*
|
||||||
* @param $code mixed The HTTP status code to return.
|
* @param $response_type string The type of response you want to return. Valid options are: csv, html, json, text.
|
||||||
* @param $desc string The description of the error.
|
*/
|
||||||
*/
|
public function __construct(string $response_type = "json")
|
||||||
public function error(mixed $code, string $desc): void
|
{
|
||||||
{
|
switch ($response_type) {
|
||||||
$response = match ($this->type) {
|
case 'csv':
|
||||||
'csv' => $this->csvError($desc),
|
header('Content-Type: text/csv; charset=UTF-8');
|
||||||
'html' => $this->htmlError($code, $desc),
|
$this->type = $response_type;
|
||||||
'json' => $this->jsonError($code, $desc),
|
break;
|
||||||
'text' => $this->textError($code, $desc),
|
case 'html':
|
||||||
};
|
header('Content-Type: text/html; charset=UTF-8');
|
||||||
http_response_code($code);
|
$this->type = $response_type;
|
||||||
echo $response;
|
break;
|
||||||
}
|
case 'json':
|
||||||
|
header('Content-Type: application/json; charset=UTF-8');
|
||||||
/* Returning a string that contains the error message. */
|
$this->type = $response_type;
|
||||||
private static function csvError(string $description): string
|
break;
|
||||||
{
|
case 'gyazo':
|
||||||
return '"error"' . "\r\n" . "\"$description\"" . "\r\n";
|
header('Content-Type: text/plain; charset=UTF-8');
|
||||||
}
|
$this->type = 'text';
|
||||||
|
break;
|
||||||
/**
|
case 'text':
|
||||||
* Returns a string containing an HTML paragraph element with the error code and description
|
header('Content-Type: text/plain; charset=UTF-8');
|
||||||
*
|
$this->type = $response_type;
|
||||||
* @param $code int|string The error code.
|
break;
|
||||||
* @param $description string The description of the error.
|
default:
|
||||||
*
|
header('Content-Type: application/json; charset=UTF-8');
|
||||||
* @return string A string.
|
$this->type = 'json';
|
||||||
*/
|
$this->error(400, 'Invalid response type. Valid options are: csv, html, json, text.');
|
||||||
private static function htmlError(int|string $code, string $description): string
|
break;
|
||||||
{
|
}
|
||||||
return '<p>ERROR: (' . $code . ') ' . $description . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a JSON string with the error code and description
|
|
||||||
*
|
|
||||||
* @param $code int|string The error code.
|
|
||||||
* @param $description string The description of the error.
|
|
||||||
*
|
|
||||||
* @return bool|string A JSON string
|
|
||||||
*/
|
|
||||||
private static function jsonError(int|string $code, string $description): bool|string
|
|
||||||
{
|
|
||||||
return json_encode([
|
|
||||||
'success' => false,
|
|
||||||
'errorcode' => $code,
|
|
||||||
'description' => $description,
|
|
||||||
], JSON_PRETTY_PRINT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string that contains the error code and description
|
|
||||||
*
|
|
||||||
* @param $code int|string The error code.
|
|
||||||
* @param $description string The description of the error.
|
|
||||||
*
|
|
||||||
* @return string A string with the error code and description.
|
|
||||||
*/
|
|
||||||
private static function textError(int|string $code, string $description): string
|
|
||||||
{
|
|
||||||
return 'ERROR: (' . $code . ') ' . $description;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* "If the type is csv, then call the csvSuccess function, if the type is html, then call the htmlSuccess function, etc."
|
|
||||||
*
|
|
||||||
* The `match` keyword is a new feature in PHP 8. It's a lot like a switch statement, but it's more powerful
|
|
||||||
*
|
|
||||||
* @param $files array An array of file objects.
|
|
||||||
*/
|
|
||||||
public function send(array $files): void
|
|
||||||
{
|
|
||||||
$response = match ($this->type) {
|
|
||||||
'csv' => $this->csvSuccess($files),
|
|
||||||
'html' => $this->htmlSuccess($files),
|
|
||||||
'json' => $this->jsonSuccess($files),
|
|
||||||
'text' => $this->textSuccess($files),
|
|
||||||
};
|
|
||||||
|
|
||||||
http_response_code(200); // "200 OK". Success.
|
|
||||||
echo $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes an array of files and returns a CSV string
|
|
||||||
*
|
|
||||||
* @param $files array An array of files that have been uploaded.
|
|
||||||
*
|
|
||||||
* @return string A string of the files in the array.
|
|
||||||
*/
|
|
||||||
private static function csvSuccess(array $files): string
|
|
||||||
{
|
|
||||||
$result = '"name","url","hash","size"' . "\r\n";
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$result .= '"' . $file['name'] . '"' . ',' .
|
|
||||||
'"' . $file['url'] . '"' . ',' .
|
|
||||||
'"' . $file['hash'] . '"' . ',' .
|
|
||||||
'"' . $file['size'] . '"' . "\r\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
/**
|
||||||
}
|
* Returns a string based on the type of response requested
|
||||||
|
*
|
||||||
/**
|
* @param $code mixed The HTTP status code to return.
|
||||||
* Takes an array of files and returns a string of HTML links
|
* @param $desc string The description of the error.
|
||||||
*
|
*/
|
||||||
* @param $files array An array of files to be uploaded.
|
public function error(mixed $code, string $desc):void
|
||||||
*
|
{
|
||||||
* @return string the result of the foreach loop.
|
$response = match ($this->type) {
|
||||||
*/
|
'csv' => $this->csvError($desc),
|
||||||
private static function htmlSuccess(array $files): string
|
'html' => $this->htmlError($code, $desc),
|
||||||
{
|
'json' => $this->jsonError($code, $desc),
|
||||||
$result = '';
|
'text' => $this->textError($code, $desc),
|
||||||
|
};
|
||||||
foreach ($files as $file) {
|
http_response_code($code);
|
||||||
$result .= '<a href="' . $file['url'] . '">' . $file['url'] . '</a><br>';
|
echo $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
/* Returning a string that contains the error message. */
|
||||||
}
|
private static function csvError(string $description):string
|
||||||
|
{
|
||||||
/**
|
return '"error"' . "\r\n" . "\"$description\"" . "\r\n";
|
||||||
* Returns a JSON string that contains a success message and the files that were uploaded
|
|
||||||
*
|
|
||||||
* @param $files array The files to be uploaded.
|
|
||||||
*
|
|
||||||
* @return bool|string A JSON string
|
|
||||||
*/
|
|
||||||
private static function jsonSuccess(array $files): bool|string
|
|
||||||
{
|
|
||||||
return json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'files' => $files,
|
|
||||||
], JSON_PRETTY_PRINT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes an array of files and returns a string of URLs
|
|
||||||
*
|
|
||||||
* @param $files array The files to be uploaded.
|
|
||||||
*
|
|
||||||
* @return string the url of the file.
|
|
||||||
*/
|
|
||||||
private static function textSuccess(array $files): string
|
|
||||||
{
|
|
||||||
$result = '';
|
|
||||||
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$result .= $file['url'] . "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
/**
|
||||||
|
* Returns a string containing an HTML paragraph element with the error code and description
|
||||||
|
*
|
||||||
|
* @param $code int|string The error code.
|
||||||
|
* @param $description string The description of the error.
|
||||||
|
*
|
||||||
|
* @return string A string.
|
||||||
|
*/
|
||||||
|
private static function htmlError(int|string $code, string $description):string
|
||||||
|
{
|
||||||
|
return '<p>ERROR: (' . $code . ') ' . $description . '</p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a JSON string with the error code and description
|
||||||
|
*
|
||||||
|
* @param $code int|string The error code.
|
||||||
|
* @param $description string The description of the error.
|
||||||
|
*
|
||||||
|
* @return bool|string A JSON string
|
||||||
|
*/
|
||||||
|
private static function jsonError(int|string $code, string $description):bool|string
|
||||||
|
{
|
||||||
|
return json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'errorcode' => $code,
|
||||||
|
'description' => $description,
|
||||||
|
], JSON_PRETTY_PRINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string that contains the error code and description
|
||||||
|
*
|
||||||
|
* @param $code int|string The error code.
|
||||||
|
* @param $description string The description of the error.
|
||||||
|
*
|
||||||
|
* @return string A string with the error code and description.
|
||||||
|
*/
|
||||||
|
private static function textError(int|string $code, string $description):string
|
||||||
|
{
|
||||||
|
return 'ERROR: (' . $code . ') ' . $description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "If the type is csv, then call the csvSuccess function, if the type is html, then call the htmlSuccess function, etc."
|
||||||
|
*
|
||||||
|
* The `match` keyword is a new feature in PHP 8. It's a lot like a switch statement, but it's more powerful
|
||||||
|
*
|
||||||
|
* @param $files array An array of file objects.
|
||||||
|
*/
|
||||||
|
public function send(array $files):void
|
||||||
|
{
|
||||||
|
$response = match ($this->type) {
|
||||||
|
'csv' => $this->csvSuccess($files),
|
||||||
|
'html' => $this->htmlSuccess($files),
|
||||||
|
'json' => $this->jsonSuccess($files),
|
||||||
|
'text' => $this->textSuccess($files),
|
||||||
|
};
|
||||||
|
http_response_code(200); // "200 OK". Success.
|
||||||
|
echo $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of files and returns a CSV string
|
||||||
|
*
|
||||||
|
* @param $files array An array of files that have been uploaded.
|
||||||
|
*
|
||||||
|
* @return string A string of the files in the array.
|
||||||
|
*/
|
||||||
|
private static function csvSuccess(array $files):string
|
||||||
|
{
|
||||||
|
$result = '"name","url","hash","size"' . "\r\n";
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$result .= '"' . $file['name'] . '"' . ',' .
|
||||||
|
'"' . $file['url'] . '"' . ',' .
|
||||||
|
'"' . $file['hash'] . '"' . ',' .
|
||||||
|
'"' . $file['size'] . '"' . "\r\n";
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of files and returns a string of HTML links
|
||||||
|
*
|
||||||
|
* @param $files array An array of files to be uploaded.
|
||||||
|
*
|
||||||
|
* @return string the result of the foreach loop.
|
||||||
|
*/
|
||||||
|
private static function htmlSuccess(array $files):string
|
||||||
|
{
|
||||||
|
$result = '';
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$result .= '<a href="' . $file['url'] . '">' . $file['url'] . '</a><br>';
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a JSON string that contains a success message and the files that were uploaded
|
||||||
|
*
|
||||||
|
* @param $files array The files to be uploaded.
|
||||||
|
*
|
||||||
|
* @return bool|string A JSON string
|
||||||
|
*/
|
||||||
|
private static function jsonSuccess(array $files):bool|string
|
||||||
|
{
|
||||||
|
return json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'files' => $files,
|
||||||
|
], JSON_PRETTY_PRINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of files and returns a string of URLs
|
||||||
|
*
|
||||||
|
* @param $files array The files to be uploaded.
|
||||||
|
*
|
||||||
|
* @return string the url of the file.
|
||||||
|
*/
|
||||||
|
private static function textSuccess(array $files):string
|
||||||
|
{
|
||||||
|
$result = '';
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$result .= $file['url'] . "\n";
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,271 +1,262 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
|
||||||
* Uguu
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pomf\Uguu\Classes;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class Upload extends Response
|
|
||||||
{
|
|
||||||
public array $FILE_INFO;
|
|
||||||
public array $fingerPrintInfo;
|
|
||||||
private mixed $Connector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes an array of files, and returns an array of arrays containing the file's temporary name, name, size, SHA1 hash, extension, and MIME type
|
* Uguu
|
||||||
*
|
*
|
||||||
* @param $files array The files array from the $_FILES superglobal.
|
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
||||||
*
|
*
|
||||||
* @return array An array of arrays.
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* @throws \Exception
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
public function reFiles(array $files): array
|
|
||||||
|
namespace Uguu\Classes;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class Upload extends Response
|
||||||
{
|
{
|
||||||
$this->Connector = new Connector();
|
public array $FILE_INFO;
|
||||||
$this->Connector->setDB($this->Connector->DB);
|
public array $fingerPrintInfo;
|
||||||
$result = [];
|
private mixed $Connector;
|
||||||
$files = $this->diverseArray($files);
|
|
||||||
foreach ($files as $file) {
|
/**
|
||||||
$hash = sha1_file($file['tmp_name']);
|
* Takes an array of files, and returns an array of arrays containing the file's temporary name, name, size, SHA1 hash, extension, and MIME type
|
||||||
$this->FILE_INFO = [
|
*
|
||||||
'TEMP_NAME' => $file['tmp_name'],
|
* @param $files array The files array from the $_FILES superglobal.
|
||||||
'NAME' => strip_tags($file['name']),
|
*
|
||||||
'SIZE' => $file['size'],
|
* @return array An array of arrays.
|
||||||
'SHA1' => $hash,
|
* @throws \Exception
|
||||||
'EXTENSION' => $this->fileExtension($file),
|
*/
|
||||||
'MIME' => $this->fileMIME($file),
|
public function reFiles(array $files):array
|
||||||
'NEW_NAME' => $this->generateName($this->fileExtension($file), $hash)
|
{
|
||||||
];
|
$this->Connector = new Connector();
|
||||||
$result[] = [
|
$this->Connector->setDB($this->Connector->DB);
|
||||||
$this->FILE_INFO['TEMP_NAME'],
|
$result = [];
|
||||||
$this->FILE_INFO['NAME'],
|
$files = $this->diverseArray($files);
|
||||||
$this->FILE_INFO['SIZE'],
|
foreach ($files as $file) {
|
||||||
$this->FILE_INFO['SHA1'],
|
$hash = sha1_file($file['tmp_name']);
|
||||||
$this->FILE_INFO['EXTENSION'],
|
$this->FILE_INFO = [
|
||||||
$this->FILE_INFO['MIME']
|
'TEMP_NAME' => $file['tmp_name'],
|
||||||
|
'NAME' => strip_tags($file['name']),
|
||||||
|
'SIZE' => $file['size'],
|
||||||
|
'SHA1' => $hash,
|
||||||
|
'EXTENSION' => $this->fileExtension($file),
|
||||||
|
'MIME' => $this->fileMIME($file),
|
||||||
|
'NEW_NAME' => $this->generateName($this->fileExtension($file), $hash),
|
||||||
|
];
|
||||||
|
$result[] = [
|
||||||
|
$this->FILE_INFO['TEMP_NAME'],
|
||||||
|
$this->FILE_INFO['NAME'],
|
||||||
|
$this->FILE_INFO['SIZE'],
|
||||||
|
$this->FILE_INFO['SHA1'],
|
||||||
|
$this->FILE_INFO['EXTENSION'],
|
||||||
|
$this->FILE_INFO['MIME'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of arrays and returns an array of arrays with the keys and values swapped
|
||||||
|
*
|
||||||
|
* @param $files array an array of arrays
|
||||||
|
*
|
||||||
|
* @return array ```
|
||||||
|
* array:2 [▼
|
||||||
|
* 0 => array:2 [▼
|
||||||
|
* 'TEMP_NAME' => 'example'
|
||||||
|
* 'NAME' => 'example'
|
||||||
|
* 'SIZE' => 'example'
|
||||||
|
* 'SHA1' => 'example'
|
||||||
|
* 'EXTENSION' => 'example'
|
||||||
|
* 'MIME' => 'example'
|
||||||
|
*
|
||||||
|
* ]
|
||||||
|
* 1 => array:2 [▼
|
||||||
|
* 'TEMP_NAME' => 'example'
|
||||||
|
* 'NAME' => 'example'
|
||||||
|
* 'SIZE' => 'example'
|
||||||
|
* 'SHA1' => 'example'
|
||||||
|
* 'EXTENSION' => 'example'
|
||||||
|
* 'MIME' => 'example'
|
||||||
|
* ]
|
||||||
|
* ]
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public function diverseArray(array $files):array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($files as $key1 => $value1) {
|
||||||
|
foreach ($value1 as $key2 => $value2) {
|
||||||
|
$result[$key2][$key1] = $value2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a file, checks if it's blacklisted, moves it to the file storage, and then logs it to the database
|
||||||
|
*
|
||||||
|
* @return array An array containing the hash, name, url, and size of the file.
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function uploadFile():array
|
||||||
|
{
|
||||||
|
if ($this->Connector->CONFIG['RATE_LIMIT']) {
|
||||||
|
$this->Connector->checkRateLimit($this->fingerPrintInfo);
|
||||||
|
}
|
||||||
|
if ($this->Connector->CONFIG['BLACKLIST_DB']) {
|
||||||
|
$this->Connector->checkFileBlacklist($this->FILE_INFO);
|
||||||
|
}
|
||||||
|
if ($this->Connector->CONFIG['FILTER_MODE'] && empty($this->FILE_INFO['EXTENSION'])) {
|
||||||
|
$this->checkMimeBlacklist();
|
||||||
|
}
|
||||||
|
if ($this->Connector->CONFIG['FILTER_MODE'] && !empty($this->FILE_INFO['EXTENSION'])) {
|
||||||
|
$this->checkMimeBlacklist();
|
||||||
|
$this->checkExtensionBlacklist();
|
||||||
|
}
|
||||||
|
if (!is_dir($this->Connector->CONFIG['FILES_ROOT'])) {
|
||||||
|
throw new Exception('File storage path not accessible.', 500);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!move_uploaded_file(
|
||||||
|
$this->FILE_INFO['TEMP_NAME'],
|
||||||
|
$this->Connector->CONFIG['FILES_ROOT'] .
|
||||||
|
$this->FILE_INFO['NEW_NAME'],
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Exception('Failed to move file to destination', 500);
|
||||||
|
}
|
||||||
|
if (!chmod($this->Connector->CONFIG['FILES_ROOT'] . $this->FILE_INFO['NEW_NAME'], 0644)) {
|
||||||
|
throw new Exception('Failed to change file permissions', 500);
|
||||||
|
}
|
||||||
|
if (!$this->Connector->CONFIG['LOG_IP']) {
|
||||||
|
$this->fingerPrintInfo['ip'] = null;
|
||||||
|
}
|
||||||
|
$this->Connector->newIntoDB($this->FILE_INFO, $this->fingerPrintInfo);
|
||||||
|
return [
|
||||||
|
'hash' => $this->FILE_INFO['SHA1'],
|
||||||
|
'name' => $this->FILE_INFO['NAME'],
|
||||||
|
'url' => $this->Connector->CONFIG['FILES_URL'] . '/' . $this->FILE_INFO['NEW_NAME'],
|
||||||
|
'size' => $this->FILE_INFO['SIZE'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return $result;
|
|
||||||
}
|
/**
|
||||||
/**
|
* Takes the amount of files that are being uploaded, and creates a fingerprint of the user's IP address, user agent, and the amount of files being
|
||||||
* Takes an array of arrays and returns an array of arrays with the keys and values swapped
|
* uploaded
|
||||||
*
|
*
|
||||||
* @param $files array an array of arrays
|
* @param $files_amount int The amount of files that are being uploaded.
|
||||||
*
|
*
|
||||||
* @return array ```
|
* @throws \Exception
|
||||||
* array:2 [▼
|
*/
|
||||||
* 0 => array:2 [▼
|
public function fingerPrint(int $files_amount):void
|
||||||
* 'TEMP_NAME' => 'example'
|
{
|
||||||
* 'NAME' => 'example'
|
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
|
||||||
* 'SIZE' => 'example'
|
$USER_AGENT = filter_var($_SERVER['HTTP_USER_AGENT'], FILTER_SANITIZE_ENCODED);
|
||||||
* 'SHA1' => 'example'
|
$this->fingerPrintInfo = [
|
||||||
* 'EXTENSION' => 'example'
|
'timestamp' => time(),
|
||||||
* 'MIME' => 'example'
|
'useragent' => $USER_AGENT,
|
||||||
*
|
'ip' => $_SERVER['REMOTE_ADDR'],
|
||||||
* ]
|
'ip_hash' => hash('sha1', $_SERVER['REMOTE_ADDR'] . $USER_AGENT),
|
||||||
* 1 => array:2 [▼
|
'files_amount' => $files_amount,
|
||||||
* 'TEMP_NAME' => 'example'
|
];
|
||||||
* 'NAME' => 'example'
|
} else {
|
||||||
* 'SIZE' => 'example'
|
throw new Exception('Invalid user agent.', 500);
|
||||||
* 'SHA1' => 'example'
|
|
||||||
* 'EXTENSION' => 'example'
|
|
||||||
* 'MIME' => 'example'
|
|
||||||
* ]
|
|
||||||
* ]
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
public function diverseArray(array $files): array
|
|
||||||
{
|
|
||||||
$result = [];
|
|
||||||
foreach ($files as $key1 => $value1) {
|
|
||||||
foreach ($value1 as $key2 => $value2) {
|
|
||||||
$result[$key2][$key1] = $value2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a file, checks if it's blacklisted, moves it to the file storage, and then logs it to the database
|
* Returns the MIME type of a file
|
||||||
*
|
*
|
||||||
* @return array An array containing the hash, name, url, and size of the file.
|
* @param $file array The file to be checked.
|
||||||
* @throws \Exception
|
*
|
||||||
*/
|
* @return string The MIME type of the file.
|
||||||
public function uploadFile(): array
|
*/
|
||||||
{
|
public function fileMIME(array $file):string
|
||||||
|
{
|
||||||
if ($this->Connector->CONFIG['RATE_LIMIT']) {
|
$FILE_INFO = finfo_open(FILEINFO_MIME_TYPE);
|
||||||
$this->Connector->checkRateLimit($this->fingerPrintInfo);
|
return finfo_file($FILE_INFO, $file['tmp_name']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->Connector->CONFIG['BLACKLIST_DB']) {
|
/**
|
||||||
$this->Connector->checkFileBlacklist($this->FILE_INFO);
|
* Takes a file and returns the file extension
|
||||||
|
*
|
||||||
|
* @param $file array The file you want to get the extension from.
|
||||||
|
*
|
||||||
|
* @return ?string The file extension of the file.
|
||||||
|
*/
|
||||||
|
public function fileExtension(array $file):?string
|
||||||
|
{
|
||||||
|
$extension = explode('.', $file['name']);
|
||||||
|
if (substr_count($file['name'], '.') > 0) {
|
||||||
|
return end($extension);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->Connector->CONFIG['FILTER_MODE'] && empty($this->FILE_INFO['EXTENSION'])) {
|
/**
|
||||||
$this->checkMimeBlacklist();
|
* > Check if the file's MIME type is in the blacklist
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function checkMimeBlacklist():void
|
||||||
|
{
|
||||||
|
if (in_array($this->FILE_INFO['MIME'], $this->Connector->CONFIG['BLOCKED_MIME'])) {
|
||||||
|
throw new Exception('Filetype not allowed.', 415);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->Connector->CONFIG['FILTER_MODE'] && !empty($this->FILE_INFO['EXTENSION'])) {
|
/**
|
||||||
$this->checkMimeBlacklist();
|
* > Check if the file extension is in the blacklist
|
||||||
$this->checkExtensionBlacklist();
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function checkExtensionBlacklist():void
|
||||||
|
{
|
||||||
|
if (in_array($this->FILE_INFO['EXTENSION'], $this->Connector->CONFIG['BLOCKED_EXTENSIONS'])) {
|
||||||
|
throw new Exception('Filetype not allowed.', 415);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_dir($this->Connector->CONFIG['FILES_ROOT'])) {
|
/**
|
||||||
throw new Exception('File storage path not accessible.', 500);
|
* Generates a random string of characters, checks if it exists in the database, and if it does, it generates another one
|
||||||
}
|
*
|
||||||
|
* @param $extension string The file extension.
|
||||||
if (
|
* @param $hash string The hash of the file.
|
||||||
!move_uploaded_file($this->FILE_INFO['TEMP_NAME'], $this->Connector->CONFIG['FILES_ROOT'] .
|
*
|
||||||
$this->FILE_INFO['NEW_NAME'])
|
* @return string A string
|
||||||
) {
|
* @throws \Exception
|
||||||
throw new Exception('Failed to move file to destination', 500);
|
*/
|
||||||
}
|
public function generateName(string $extension, string $hash):string
|
||||||
|
{
|
||||||
if (!chmod($this->Connector->CONFIG['FILES_ROOT'] . $this->FILE_INFO['NEW_NAME'], 0644)) {
|
if ($this->Connector->antiDupe($hash)) {
|
||||||
throw new Exception('Failed to change file permissions', 500);
|
do {
|
||||||
}
|
if ($this->Connector->CONFIG['FILES_RETRIES'] === 0) {
|
||||||
|
throw new Exception('Gave up trying to find an unused name!', 500);
|
||||||
if (!$this->Connector->CONFIG['LOG_IP']) {
|
}
|
||||||
$this->fingerPrintInfo['ip'] = null;
|
$NEW_NAME = '';
|
||||||
}
|
for ($i = 0; $i < $this->Connector->CONFIG['NAME_LENGTH']; ++$i) {
|
||||||
|
$NEW_NAME .= $this->Connector->CONFIG['ID_CHARSET']
|
||||||
$this->Connector->newIntoDB($this->FILE_INFO, $this->fingerPrintInfo);
|
[mt_rand(0, strlen($this->Connector->CONFIG['ID_CHARSET']))];
|
||||||
|
}
|
||||||
return [
|
if (!empty($extension)) {
|
||||||
'hash' => $this->FILE_INFO['SHA1'],
|
$NEW_NAME .= '.' . $extension;
|
||||||
'name' => $this->FILE_INFO['NAME'],
|
}
|
||||||
'url' => $this->Connector->CONFIG['FILES_URL'] . '/' . $this->FILE_INFO['NEW_NAME'],
|
} while ($this->Connector->dbCheckNameExists($NEW_NAME) > 0);
|
||||||
'size' => $this->FILE_INFO['SIZE']
|
return $NEW_NAME;
|
||||||
];
|
} else {
|
||||||
}
|
return $this->Connector->antiDupe($hash);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Takes the amount of files that are being uploaded, and creates a fingerprint of the user's IP address, user agent, and the amount of files being uploaded
|
|
||||||
*
|
|
||||||
* @param $files_amount int The amount of files that are being uploaded.
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function fingerPrint(int $files_amount): void
|
|
||||||
{
|
|
||||||
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
|
|
||||||
$USER_AGENT = filter_var($_SERVER['HTTP_USER_AGENT'], FILTER_SANITIZE_ENCODED);
|
|
||||||
$this->fingerPrintInfo = [
|
|
||||||
'timestamp' => time(),
|
|
||||||
'useragent' => $USER_AGENT,
|
|
||||||
'ip' => $_SERVER['REMOTE_ADDR'],
|
|
||||||
'ip_hash' => hash('sha1', $_SERVER['REMOTE_ADDR'] . $USER_AGENT),
|
|
||||||
'files_amount' => $files_amount
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
throw new Exception('Invalid user agent.', 500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the MIME type of a file
|
|
||||||
*
|
|
||||||
* @param $file array The file to be checked.
|
|
||||||
*
|
|
||||||
* @return string The MIME type of the file.
|
|
||||||
*/
|
|
||||||
public function fileMIME(array $file): string
|
|
||||||
{
|
|
||||||
$FILE_INFO = finfo_open(FILEINFO_MIME_TYPE);
|
|
||||||
return finfo_file($FILE_INFO, $file['tmp_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes a file and returns the file extension
|
|
||||||
*
|
|
||||||
* @param $file array The file you want to get the extension from.
|
|
||||||
*
|
|
||||||
* @return ?string The file extension of the file.
|
|
||||||
*/
|
|
||||||
public function fileExtension(array $file): ?string
|
|
||||||
{
|
|
||||||
$extension = explode('.', $file['name']);
|
|
||||||
if (substr_count($file['name'], '.') > 0) {
|
|
||||||
return end($extension);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* > Check if the file's MIME type is in the blacklist
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function checkMimeBlacklist(): void
|
|
||||||
{
|
|
||||||
if (in_array($this->FILE_INFO['MIME'], $this->Connector->CONFIG['BLOCKED_MIME'])) {
|
|
||||||
throw new Exception('Filetype not allowed.', 415);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* > Check if the file extension is in the blacklist
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function checkExtensionBlacklist(): void
|
|
||||||
{
|
|
||||||
if (in_array($this->FILE_INFO['EXTENSION'], $this->Connector->CONFIG['BLOCKED_EXTENSIONS'])) {
|
|
||||||
throw new Exception('Filetype not allowed.', 415);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a random string of characters, checks if it exists in the database, and if it does, it generates another one
|
|
||||||
*
|
|
||||||
* @param $extension string The file extension.
|
|
||||||
* @param $hash string The hash of the file.
|
|
||||||
*
|
|
||||||
* @return string A string
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function generateName(string $extension, string $hash): string
|
|
||||||
{
|
|
||||||
if ($this->Connector->antiDupe($hash)) {
|
|
||||||
do {
|
|
||||||
if ($this->Connector->CONFIG['FILES_RETRIES'] === 0) {
|
|
||||||
throw new Exception('Gave up trying to find an unused name!', 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
$NEW_NAME = '';
|
|
||||||
for ($i = 0; $i < $this->Connector->CONFIG['NAME_LENGTH']; ++$i) {
|
|
||||||
$NEW_NAME .= $this->Connector->CONFIG['ID_CHARSET']
|
|
||||||
[mt_rand(0, strlen($this->Connector->CONFIG['ID_CHARSET']))];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($extension)) {
|
|
||||||
$NEW_NAME .= '.' . $extension;
|
|
||||||
}
|
|
||||||
} while ($this->Connector->dbCheckNameExists($NEW_NAME) > 0);
|
|
||||||
return $NEW_NAME;
|
|
||||||
} else {
|
|
||||||
return $this->Connector->antiDupe($hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,30 +1,29 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Uguu
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
namespace Uguu;
|
||||||
* Uguu
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2022 Go Johansson (nokonoko) <neku@pomf.se>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pomf\Uguu;
|
class GrillLoader extends Classes\CuteGrills
|
||||||
|
|
||||||
class GrillLoader extends Classes\CuteGrills
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
{
|
||||||
$this->showGrills();
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->showGrills();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -18,10 +18,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Pomf\Uguu;
|
namespace Uguu;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Pomf\Uguu\Classes\Response;
|
use Uguu\Classes\Response;
|
||||||
|
|
||||||
class UploadGateway extends Classes\Upload
|
class UploadGateway extends Classes\Upload
|
||||||
{
|
{
|
||||||
@ -38,7 +38,6 @@
|
|||||||
$type = 'json' ?? $output;
|
$type = 'json' ?? $output;
|
||||||
$response = (new Response($type));
|
$response = (new Response($type));
|
||||||
if (!empty($_FILES['files'])) {
|
if (!empty($_FILES['files'])) {
|
||||||
|
|
||||||
$files = $this->reFiles($files);
|
$files = $this->reFiles($files);
|
||||||
try {
|
try {
|
||||||
$this->fingerPrint(count($files));
|
$this->fingerPrint(count($files));
|
||||||
@ -53,7 +52,6 @@
|
|||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
$response->error($e->getCode(), $e->getMessage());
|
$response->error($e->getCode(), $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$response->error(400, 'No input file(s)');
|
$response->error(400, 'No input file(s)');
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,6 @@
|
|||||||
*/
|
*/
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
use Pomf\Uguu\GrillLoader;
|
use Pomf\GrillLoader;
|
||||||
|
|
||||||
new GrillLoader();
|
new GrillLoader();
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
checkConfig();
|
checkConfig();
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
use Pomf\Uguu\UploadGateway;
|
use Uguu\UploadGateway;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
(new UploadGateway())->handleFile($_GET['output'], $_FILES['files']);
|
(new UploadGateway())->handleFile($_GET['output'], $_FILES['files']);
|
||||||
|
Loading…
Reference in New Issue
Block a user