Compare commits

...

27 Commits

Author SHA1 Message Date
Go Johansson da5fc5295b Update 'README.md' 2 months ago
Go Johansson 1704a52542 Update '.mailmap' 2 months ago
Go Johansson 1736639a04 Update 'README.md' 2 months ago
Go Johansson ccf3370ab5 Update 'docker/Dockerfile' 2 months ago
Go Johansson ab53dc2d5c Update 'Makefile' 2 months ago
Go Johansson 2d4a30d675 Update 'README.md' 2 months ago
Go Johansson b2eba08767 Merge branch 'master' of https://git.pomf.se/Pomf/uguu 2 months ago
Go Johansson fca510308b Merge branch 'master' of https://git.pomf.se/Pomf/uguu 2 months ago
Go Johansson 4717c93610 Update 'docker/Dockerfile' 2 months ago
Go Johansson b3c0237ad9 docker support added 2 months ago
Go Johansson 9650e66147 Update 'docker/Dockerfile' 2 months ago
Go Johansson c37c18d723 Update 'README.md' 2 months ago
Go Johansson 64edada887 Merge pull request 'Dockerfile for Uguu' (#71) from r4jeshwar/dockerize-uguu into master 2 months ago
Rajeshwar R a4bf8f8017
Update .env 3 months ago
r4jeshwar 0a6585a2bd Dockerize Uguu to work with the default SQLite DB 3 months ago
Go Johansson 32cba5812d strip some tags 5 months ago
Go Johansson 3465b5926e file ext fix 5 months ago
Go Johansson e08efcd9d7 fix for filename extension bug 5 months ago
Go Johansson 948faf8ff9 Merge branch 'master' of https://github.com/nokonoko/Uguu 5 months ago
Go Johansson 3b67377c5d Update Upload.class.php 5 months ago
Go Johansson a8fb2438a7
Delete phpdocs directory 5 months ago
Go Johansson fb13a2a304 fix extension fix 5 months ago
Go Johansson 6b16f63c83 1.5.0 changes 5 months ago
Go Johansson 5b30192d33 Create .sonarcloud.properties 5 months ago
Go Johansson 81c0258e47 remove trash 5 months ago
Go Johansson 2d0bf4f30c add phpdocs 5 months ago
Go Johansson eec51db0eb
Update README.md 5 months ago
  1. 6
      .gitignore
  2. 2
      .mailmap
  3. 1
      .sonarcloud.properties
  4. 15
      Makefile
  5. 15
      README.md
  6. 2
      dist.json
  7. 23
      docker/.env
  8. 70
      docker/Dockerfile
  9. 70
      docker/dist.json
  10. 5
      docker/docker-entrypoint.sh
  11. 0
      docker/ssl/fullchain.pem
  12. 0
      docker/ssl/privkey.pem
  13. 32
      docker/supervisord.conf
  14. 64
      docker/uguu.conf
  15. 8
      docker_build.sh
  16. 2
      docker_purge.sh
  17. 8
      package.json
  18. 16
      static/php/includes/Core.namespace.php
  19. 78
      static/php/includes/Upload.class.php
  20. 4
      static/php/upload.php

6
.gitignore vendored

@ -2,7 +2,9 @@
node_modules
dist/
build/
*.xml
package-lock.json
uguu.sq3
.idea/copyright/profiles_settings.xml
*.xml
.idea
.phpdoc
.vscode

2
.mailmap

@ -1 +1 @@
Eric Johansson <neku@pomf.se>
Go Johansson <neku@pomf.se>

1
.sonarcloud.properties

@ -0,0 +1 @@
sonar.exclusions=phpdocs

15
Makefile

@ -7,6 +7,9 @@ NPM="npm"
DESTDIR="./dist"
PKG_VERSION := $( $(GREP) -Po '(?<="version": ")[^"]*' )
TMPDIR := $(shell mktemp -d)
DOCKER_IMAGE = "$(shell basename $(CURDIR) | tr [:upper:] [:lower:])"
DOCKER_TAG="$(DOCKER_TAG)"
CONTAINER_NAME="$(CONTAINER_NAME)"
# default modules
MODULES="php"
@ -79,6 +82,18 @@ uninstall:
npm_dependencies:
$(NPM) install
build-image:
docker build -f docker/Dockerfile --build-arg VERSION=$(UGUU_RELEASE_VER) --no-cache -t $(DOCKER_IMAGE):$(DOCKER_TAG) .
run-container:
docker run --name $(CONTAINER_NAME) -d -p 8080:80 -p 8081:443 --env-file docker/.env $(DOCKER_IMAGE):$(DOCKER_TAG)
purge-container:
if docker images | grep $(DOCKER_IMAGE); then \
docker rm -f $(CONTAINER_NAME) && docker rmi $(DOCKER_IMAGE):$(DOCKER_TAG) || true;\
fi;
builddirs:
mkdir -p $(CURDIR)/build $(CURDIR)/build/img
ifneq (,$(findstring php,$(MODULES)))

15
README.md

@ -26,16 +26,19 @@ See the real world site at [uguu.se](https://uguu.se).
## Requirements
Original development environment is Nginx + PHP8.1 + SQLite, but is confirmed to
work with Apache and older PHP versions like PHP7.4.
Tested and working with Nginx + PHP-8.0/8.1 + SQLite/MySQL.
Node is used to compile Uguu.
Node is used to compile Uguu, after that it runs on PHP.
## Installation
Installation and configuration can be found at [Uguu Documentation](https://docs.uguu.se).
If you need a admin panel check out [Moe Panel](https://github.com/pomf/MoePanel).
If you need a admin panel check out [Moe Panel](https://git.pomf.se/Pomf/MoePanel).
## Docker
For Docker read [this guide](https://git.pomf.se/Pomf/uguu/wiki/Deploying-using-Docker).
## Getting help
@ -52,9 +55,11 @@ coding style guides. We use ESLint and PHPCS tools to enforce these standards.
You can also help by sending us feature requests or writing documentation and
tests.
The Uguu repo has changed home and now resides at [Pomf Git](https://git.pomf.se/Pomf/Uguu).
## Credits
Uguu is based on [Pomf](http://github.com/pomf/pomf) which was written by Emma Lejack & Eric Johansson (nekunekus) and with help from the open source community.
Uguu is based on [Pomf](http://github.com/pomf/pomf) which was written by Emma Lejack & Go Johansson (nekunekus) and with help from the open source community.
## License

2
dist.json

@ -3,7 +3,7 @@
"allowErrors": false
},
"dest": "dist",
"pkgVersion": "1.4.0",
"pkgVersion": "1.5.3",
"banners": [
"banners/malware_scans.swig",
"banners/donations.swig"

23
docker/.env

@ -0,0 +1,23 @@
GEN_ROBOTS_TXT=false
GEN_SITE_MAP=false
MAX_UPLOAD_SIZE=128
PROD=false
SITE_NAME=UGUU
SITE_URL=https://localhost
ABUSE_CONTACT=abuse@example.com
INFO_CONTACT=info@example.com
SERVER_CN_LOC=Sweden
SITE_META_INFO=SITENAME is a temporary file hosting service, upload files up to 128MiB for 24 hours.
PAYPAL_URL=
BTC_ADDR=
FLATTR_URL=
DB_PATH=/var/www/db/uguu.sq3
FILES_ROOT=/var/www/files/
LOG_IP=false
DB_USER=NULL
DB_PASS=NULL
ANTI_DUPE=false
FILES_RETRIES=15
SSL=true
NAME_LENGTH=8
URL=https://filesdomain

70
docker/Dockerfile

@ -0,0 +1,70 @@
FROM alpine:latest
ARG VERSION
# Install the needed software
RUN apk add --no-cache curl nginx php8-fpm php8-sqlite3 php8-opcache sqlite nodejs git npm bash build-base supervisor
# Create the www-data user and group
RUN set -x ; \
addgroup -g 82 -S www-data ; \
adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1
# Link php bin
RUN ln -s /usr/bin/php8 /usr/bin/php
# Copy supervisor conf file
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Set default workdir
WORKDIR /var/www/
COPY docker/docker-entrypoint.sh .
# Download Uguu
ADD https://git.pomf.se/Pomf/uguu/archive/v${VERSION}.tar.gz v${VERSION}.tar.gz
RUN tar xvf v${VERSION}.tar.gz
# Create the needed directories
RUN mkdir /var/www/uguu/dist && \
mkdir /var/www/db && \
mkdir /var/www/files
# Create the Sqlite DB
RUN sqlite3 /var/www/db/uguu.sq3 -init /var/www/uguu/sqlite_schema.sql && \
chown -R www-data:www-data /var/www && \
chmod -R 775 /var/www/
# Fix script paths
RUN chmod a+x /var/www/uguu/checkdb.sh && \
chmod a+x /var/www/uguu/checkfiles.sh && \
sed -i 's#/path/to/files/#/var/www/uguu/files/#g' /var/www/uguu/checkfiles.sh && \
sed -i 's#/path/to/db/uguu.sq3#/var/www/db/uguu.sq3#g' /var/www/uguu/checkdb.sh
# Add scripts to cron
RUN echo "0,30 * * * * bash /var/www/uguu/checkfiles.sh" >> /var/spool/cron/crontabs/www-data && \
echo "0,30 * * * * bash /var/www/uguu/checkdb.sh" >> /var/spool/cron/crontabs/www-data
# Copy Nginx Server conf
COPY docker/uguu.conf /etc/nginx/http.d/
# Copy SSL certs
COPY docker/ssl /etc/ssl
# Copy Uguu config
COPY dist.json /var/www/uguu/dist.json
# Give permissions to www-data
RUN chown -R www-data:www-data /run /var/lib/php8 /var/lib/nginx /var/log/nginx /var/log/php8 /etc/nginx /etc/php8
# Change user to www-data
USER www-data
# Expose port 80 from the container
EXPOSE 80
# Expose port 443 from the container
EXPOSE 443
# Load entrypoint
ENTRYPOINT [ "bash", "/var/www/docker-entrypoint.sh" ]

70
docker/dist.json

@ -0,0 +1,70 @@
{
"init": {
"allowErrors": false
},
"dest": "dist",
"pkgVersion": "1.5.3",
"banners": [
"banners/malware_scans.swig",
"banners/donations.swig"
],
"src": [
"templates/index.swig",
"templates/faq.swig",
"templates/tools.swig"
],
"generateRobotstxt": "${GEN_ROBOTS_TXT}",
"generateSitemap": "${GEN_SITE_MAP}",
"max_upload_size": "${MAX_UPLOAD_SIZE}",
"production": "${PROD}",
"siteName": "${SITE_NAME}",
"siteUrl": "${SITE_URL}",
"abuseContact": "${ABUSE_CONTACT}",
"infoContact": "${INFO_CONTACT}",
"ServerCountryLocation": "${SERVER_CN_LOC}",
"SiteMetaInfo": "${SITE_META_INFO}",
"ToolsDesc": "The following tools might need editing to work on this clone of Uguu, usually editing the URL works.",
"paypalUrl": "${PAYPAL_URL}",
"bitcoinAddress": "${BTC_ADDR}",
"flattrUrl": "${FLATTR_URL}",
"DB_MODE": "sqlite",
"DB_PATH": "${DB_PATH}",
"DB_USER": "${DB_USER}",
"DB_PASS": "${DB_PASS}",
"LOG_IP": "${LOG_IP}",
"ANTI_DUPE": "${ANTI_DUPE}",
"BLACKLIST_DB": true,
"FILTER_MODE": true,
"FILES_ROOT": "${FILES_ROOT}",
"FILES_RETRIES": "${FILES_RETRIES}",
"SSL": "${SSL}",
"URL": "${URL}",
"NAME_LENGTH": "${NAME_LENGTH}",
"ID_CHARSET": "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ",
"BLOCKED_EXTENSIONS": [
"exe",
"scr",
"com",
"vbs",
"bat",
"cmd",
"htm",
"html",
"jar",
"msi",
"apk",
"phtml",
"svg"
],
"BLOCKED_MIME": [
"application/msword",
"text/html",
"application/x-dosexec",
"application/java",
"application/java-archive",
"application/x-executable",
"application/x-mach-binary",
"image/svg+xml"
]
}

5
docker/docker-entrypoint.sh

@ -0,0 +1,5 @@
#!/bin/bash
cd /var/www/uguu/
make
make install
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf

0
docker/ssl/fullchain.pem

0
docker/ssl/privkey.pem

32
docker/supervisord.conf

@ -0,0 +1,32 @@
[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0
pidfile=/run/supervisord.pid
[program:php-fpm]
command=php-fpm8 -F
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=false
startretries=0
[program:nginx]
command=nginx -g 'daemon off;'
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=false
startretries=0
[program:crond]
command=crond -b
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autorestart=false
startretries=0

64
docker/uguu.conf

@ -0,0 +1,64 @@
server {
listen 80;
server_name localhost;
return 301 https://localhost$request_uri;
}
server {
listen 80;
server_name filesdomain;
return 301 https://filesdomain$request_uri;
}
server{
listen 443 ssl;
server_name localhost;
ssl on;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_ecdh_curve secp384r1;
root /var/www/uguu/dist/;
autoindex on;
access_log on;
index index.html index.php;
location ~* \.(css|js|jpg|jpeg|gif|png|ico|xml|eot|woff|woff2|ttf|svg|otf|x-icon|avif|webp|apng)$ {
expires 30d;
}
gzip on;
gzip_min_length 1000;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/css text/js text/javascript application/javascript application/x-javascript;
location ~* \.php$ {
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
server {
listen 443 ssl;
server_name filesdomain;
ssl on;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_ecdh_curve secp384r1;
root /var/www/files/;
autoindex off;
access_log off;
index index.html;
}

8
docker_build.sh

@ -0,0 +1,8 @@
#!/bin/bash
echo ">>> BUILDING UGUU CONTAINER <<<"
make UGUU_RELEASE_VER=$(cat package.json | grep version | cut -d '"' -f4) DOCKER_TAG=$(cat package.json | grep version | cut -d '"' -f4) build-image
echo ">>> DONE! <<<"
echo ">>> Starting Uguu container! <<<"
make DOCKER_TAG=$(cat package.json | grep version | cut -d '"' -f4) CONTAINER_NAME=uguu run-container
echo ">>> DONE! <<<"

2
docker_purge.sh

@ -0,0 +1,2 @@
#!/bin/bash
make DOCKER_TAG=$(cat package.json | grep version | cut -d '"' -f4) CONTAINER_NAME=uguu purge-container

8
package.json

@ -1,18 +1,18 @@
{
"name": "uguu",
"version": "1.4.0",
"version": "1.5.3",
"description": "Kawaii file host",
"homepage": "https://uguu.se/",
"repository": {
"type": "git",
"url": "https://github.com/nokonoko/pomf"
"url": "https://github.com/nokonoko/uguu"
},
"author": "Eric Johansson <neku@pomf.se>",
"author": "Go Johansson <neku@pomf.se>",
"contributors": [
"Pomf Community <github.com/pomf/pomf>",
"Uguu Community <github.com/nokonoko/uguu>"
],
"license": "MIT",
"license": "GPLV3",
"bugs": {
"url": "https://github.com/nokonoko/uguu/issues"
},

16
static/php/includes/Core.namespace.php

@ -87,7 +87,7 @@ namespace Core {
} catch (Exception) {
throw new Exception('Cant populate settings.', 500);
}
(new Database())->assemblePDO();
Database::assemblePDO();
}
}
@ -283,7 +283,7 @@ namespace Core {
/**
* @throws Exception
*/
public function dbCheckNameExists()
public static function dbCheckNameExists()
{
try {
$q = Settings::$DB->prepare('SELECT COUNT(filename) FROM files WHERE filename = (:name)');
@ -298,7 +298,7 @@ namespace Core {
/**
* @throws Exception
*/
public function checkFileBlacklist()
public static function checkFileBlacklist()
{
try {
$q = Settings::$DB->prepare('SELECT hash, COUNT(*) AS count FROM blacklist WHERE hash = (:hash)');
@ -316,7 +316,7 @@ namespace Core {
/**
* @throws Exception
*/
public function antiDupe()
public static function antiDupe()
{
try {
$q = Settings::$DB->prepare(
@ -327,7 +327,9 @@ namespace Core {
$q->execute();
$result = $q->fetch();
if ($result['count'] > 0) {
return $result['filename'];
Upload::$NEW_NAME_FULL = $result['filename'];
} else {
Upload::generateName();
}
} catch (Exception) {
throw new Exception('Cant check for dupes in DB.', 500);
@ -337,7 +339,7 @@ namespace Core {
/**
* @throws Exception
*/
public function newIntoDB()
public static function newIntoDB()
{
try {
$q = Settings::$DB->prepare(
@ -345,7 +347,7 @@ namespace Core {
'VALUES (:hash, :orig, :name, :size, :date, :ip)'
);
$q->bindValue(':hash', Upload::$SHA1, PDO::PARAM_STR);
$q->bindValue(':orig', strip_tags(Upload::$FILE_NAME), PDO::PARAM_STR);
$q->bindValue(':orig', Upload::$FILE_NAME, PDO::PARAM_STR);
$q->bindValue(':name', Upload::$NEW_NAME_FULL, PDO::PARAM_STR);
$q->bindValue(':size', Upload::$FILE_SIZE, PDO::PARAM_INT);
$q->bindValue(':date', time(), PDO::PARAM_STR);

78
static/php/includes/Upload.class.php

@ -28,24 +28,24 @@ class Upload
{
public static string $FILE_NAME;
public static string $FILE_EXTENSION;
public static mixed $FILE_EXTENSION;
public static string $FILE_MIME;
public static string $SHA1;
public static string $NEW_NAME;
public static string $NEW_NAME_FULL;
public static string $IP;
public static mixed $IP;
public static string $FILE_SIZE;
public static string $TEMP_FILE;
public function reFiles($files): array
public static function reFiles($files): array
{
$result = [];
$files = self::diverseArray($files);
foreach ($files as $file) {
self::$FILE_NAME = $file['name'];
self::$FILE_NAME = strip_tags($file['name']);
self::$FILE_SIZE = $file['size'];
self::$TEMP_FILE = $file['tmp_name'];
self::$SHA1 = sha1_file(self::$TEMP_FILE);
@ -54,7 +54,7 @@ class Upload
return $result;
}
public function diverseArray($files): array
public static function diverseArray($files): array
{
$result = [];
@ -69,31 +69,28 @@ class Upload
/**
* @throws Exception
*/
public function uploadFile(): array
public static function uploadFile(): array
{
(new Settings())->loadConfig();
(new Upload())->fileInfo();
Settings::loadConfig();
self::fileInfo();
if (Settings::$BLACKLIST_DB) {
(new Database())->checkFileBlacklist();
Database::checkFileBlacklist();
}
if (Settings::$FILTER_MODE) {
self::checkMimeBlacklist();
self::checkExtensionBlacklist();
if(!is_null(self::$FILE_EXTENSION)){
self::checkExtensionBlacklist();
}
}
if (Settings::$ANTI_DUPE) {
$result = (new Database())->antiDupe();
if (isset($result)) {
self::$NEW_NAME_FULL = $result;
} else {
(new Upload())->generateName();
}
Database::antiDupe();
}
if (!Settings::$ANTI_DUPE) {
(new Upload())->generateName();
self::generateName();
}
if (!is_dir(Settings::$FILES_ROOT)) {
@ -108,7 +105,7 @@ class Upload
throw new Exception('Failed to change file permissions', 500);
}
(new Database())->newIntoDB();
Database::newIntoDB();
if (Settings::$SSL) {
$preURL = 'https://';
@ -124,19 +121,37 @@ class Upload
];
}
public function fileInfo()
public static function getIP()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
self::$IP = $_SERVER['HTTP_CLIENT_IP'];
}
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
self::$IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if (!isset(self::$IP)) {
self::$IP = $_SERVER['REMOTE_ADDR'];
}
}
public static function fileInfo()
{
if (isset($_FILES['files'])) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
self::$FILE_MIME = finfo_file($finfo, self::$TEMP_FILE);
$extension = explode('.', self::$FILE_NAME, 2);
self::$FILE_EXTENSION = $extension['1'];
finfo_close($finfo);
$extension = explode('.', self::$FILE_NAME);
if(substr_count(self::$FILE_NAME, '.') > 0) {
self::$FILE_EXTENSION = $extension[count($extension)-1];
} else {
self::$FILE_EXTENSION = null;
}
if (Settings::$LOG_IP) {
self::$IP = $_SERVER['REMOTE_ADDR'];
self::getIP();
} else {
self::$IP = '0';
self::$IP = null;
}
}
}
@ -144,7 +159,7 @@ class Upload
/**
* @throws Exception
*/
public function checkMimeBlacklist()
public static function checkMimeBlacklist()
{
if (in_array(self::$FILE_MIME, Settings::$BLOCKED_MIME)) {
throw new Exception('Filetype not allowed.', 415);
@ -152,9 +167,12 @@ class Upload
}
/**
* Check if file extension is blacklisted
* if it does throw an exception.
*
* @throws Exception
*/
public function checkExtensionBlacklist()
public static function checkExtensionBlacklist()
{
if (in_array(self::$FILE_EXTENSION, Settings::$BLOCKED_EXTENSIONS)) {
throw new Exception('Filetype not allowed.', 415);
@ -164,7 +182,7 @@ class Upload
/**
* @throws Exception
*/
public function generateName(): string
public static function generateName()
{
do {
if (Settings::$FILES_RETRIES === 0) {
@ -176,12 +194,12 @@ class Upload
self::$NEW_NAME .= Settings::$ID_CHARSET[mt_rand(0, strlen(Settings::$ID_CHARSET))];
}
if (isset(self::$FILE_EXTENSION)) {
self::$NEW_NAME_FULL = self::$NEW_NAME;
self::$NEW_NAME_FULL = self::$NEW_NAME;
if (!is_null(self::$FILE_EXTENSION)) {
self::$NEW_NAME_FULL .= '.' . self::$FILE_EXTENSION;
}
} while ((new Database())->dbCheckNameExists() > 0);
return self::$NEW_NAME_FULL;
} while (Database::dbCheckNameExists() > 0);
}
}

4
static/php/upload.php

@ -24,11 +24,11 @@ $type = $_GET['output'] ?? 'json';
$response = (new Core\Response($type));
if (isset($_FILES['files'])) {
$uploads = (new Upload())->reFiles($_FILES['files']);
$uploads = Upload::reFiles($_FILES['files']);
try {
foreach ($uploads as $upload) {
$res[] = (new Upload())->uploadFile();
$res[] = Upload::uploadFile();
}
if (isset($res)) {
$response->send($res);

Loading…
Cancel
Save