Webservices

This commit is contained in:
2026-01-31 18:01:24 +01:00
parent e1c752fcf8
commit 2d2fc24d71
35 changed files with 3531 additions and 0 deletions

View File

@@ -0,0 +1 @@
LimitRequestBody 20480000

View File

@@ -0,0 +1,82 @@
<?php
const ITEMS_PER_PAGE = 50;
// required headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
// include database and object files
include_once '../../config/database.php';
include_once '../objects/gallery_item.php';
include_once '../objects/user.php';
include_once '../objects/like.php';
include_once '../authenticator.php';
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
// CORS Pre-flight request
header("Access-Control-Allow-Headers: origin, content-type, accept, authentication");
http_response_code(200);
exit();
} else if ($_SERVER['REQUEST_METHOD'] != 'GET') {
http_response_code(400);
echo json_encode(array("error" => "Method not accepted."));
exit();
}
// get params
$page = 0;
if (isset($_GET["page"])) {
if (!is_int($_GET["page"])) {
http_response_code(400);
}
$page = $_GET["page"];
}
$id = null;
if (isset($_GET['id'])) {
if (!is_int($_GET["id"])) {
http_response_code(400);
}
$id = $_GET["id"];
}
// instantiate database and product object
$database = new Database();
$db = $database->getConnection();
$auth = new Authenticator($db);
$uid = $auth->authenticate();
// query products
if ($id)
$stmt = GalleryItem::readById($db, $uid, $id);
else
$stmt = GalleryItem::read($db, $uid, $page, ITEMS_PER_PAGE);
// products array
$gi_arr=array();
$gi_arr["records"]=array();
$gi_arr["page"]=$page;
$gi_arr["more"]=FALSE;
// retrieve our table contents
// fetch() is faster than fetchAll()
// http://stackoverflow.com/questions/2770630/pdofetchall-vs-pdofetch-in-a-loop
$count = 0;
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$count++;
$gallery_item = GalleryItem::fromRow($row);
if ($count <= ITEMS_PER_PAGE) {
array_push($gi_arr["records"], $gallery_item);
} else {
$gi_arr["more"] = TRUE; // If the query returns one more element than ITEMS_PER_PAGE, there is at least another page
}
}
// set response code - 200 OK
http_response_code(200);
// show products data in json format
echo json_encode($gi_arr);

View File

@@ -0,0 +1,192 @@
<?php
/**
* ALERT! Requires settings.json file in the static folder!
*/
const GALLERY_UPLOAD_PATH = "gallery-uploads";
const GALLERY_ITEM_SIZE_THUMB = 720;
const GALLERY_ITEM_SIZE_DIST = 4096;
const SETTINGS_STATIC_JSON_PATH = "../../static/settings.json";
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
include_once '../../config/database.php';
include_once '../objects/gallery_item.php';
include_once '../objects/user.php';
include_once '../objects/like.php';
include_once '../authenticator.php';
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
http_response_code(400);
echo json_encode(array("error" => "Method not accepted."));
exit();
}
$database = new Database();
$db = $database->getConnection();
$auth = new Authenticator($db);
$userId = $auth->authenticate();
// Check the image sharing is already enabled
$settings = json_decode(file_get_contents(SETTINGS_STATIC_JSON_PATH));
if (!$settings->photoSharingEnabled) {
// Sharing not yet enabled: check the user is an Admin
$stmt = User::get($db, $userId);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user || !array_key_exists('admin', $user))
throw new Exception('unable to determine if user ' . $userId . ' is an admin');
if (!$user['admin']) {
http_response_code(403);
echo json_encode(array("error" => "User doesn't have permission to publish an image"));
exit();
}
}
try {
// Undefined | Multiple Files | $_FILES Corruption Attack
// If this request falls under any of them, treat it invalid.
if (
!isset($_FILES['image']['error']) ||
is_array($_FILES['image']['error'])
) {
throw new InvalidArgumentException('Invalid parameters.');
}
// Check $_FILES['image']['error'] value.
switch ($_FILES['image']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}
// DO NOT TRUST $_FILES['image']['mime'] VALUE !!
// Check MIME Type by yourself.
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['image']['tmp_name']),
array(
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
// Create upload directory (if not exists)
$dir = GALLERY_UPLOAD_PATH;
$dirRelPath = '../../' . $dir;
// create new directory with 744 permissions if it does not exist yet
// owner will be the user/group the PHP script is run under
if ( !file_exists($dirRelPath) ) {
if (!mkdir ($dirRelPath, 0744)) {
throw new RuntimeException('Unable to create uploads folder: '.$dirRelPath);
}
}
if ( !file_exists($_FILES['image']['tmp_name'])) {
throw new RuntimeException('Failed not present in temp folder: '.$_FILES['image']['tmp_name']);
}
// Save original image
$destFileName = sha1_file($_FILES['image']['tmp_name']);
$destPath = sprintf('%s/%s.%s',
$dirRelPath,
$destFileName,
$ext
);
if (!move_uploaded_file(
$_FILES['image']['tmp_name'],
$destPath
)) {
throw new RuntimeException('Failed to move uploaded file to '.$destPath);
}
// Create distribution image
$distDestPath = sprintf('%s/%s_dist.%s',
$dirRelPath,
$destFileName,
$ext
);
$retCodeThumb = exec('convert "'.$destPath.'" -auto-orient -resize '.GALLERY_ITEM_SIZE_DIST.'x'.GALLERY_ITEM_SIZE_DIST.' -quality 80 "'.$distDestPath.'"');
if ($retCodeThumb)
throw new RuntimeException("Unable to create distribution image");
// Create thumb
$thumbDestPath = sprintf('%s/%s_thumb.%s',
$dirRelPath,
$destFileName,
$ext
);
$retCodeThumb = exec('convert "'.$destPath.'" -auto-orient -resize '.GALLERY_ITEM_SIZE_THUMB.'x'.GALLERY_ITEM_SIZE_THUMB.' -quality 80 "'.$thumbDestPath.'"');
if ($retCodeThumb)
throw new RuntimeException("Unable to create thumbnail");
// Create gallery item with uploaded photo (only dist and thumb paths are saved to db)
$gi = [];
$gi['imageUrl'] = sprintf('/%s/%s_dist.%s',
$dir,
$destFileName,
$ext
);
$gi['imageThumbUrl'] = sprintf('/%s/%s_thumb.%s',
$dir,
$destFileName,
$ext
);
$gi['likes ']= 0;
$gi['description'] = ""; // TODO
$gi['author'] = $userId;
$db->beginTransaction();
if (!GalleryItem::create($db, $gi)){
throw new RuntimeException("Unable to create GalleryItem.");
}
// Retrieve inserted item
$newGiId = $database->conn->lastInsertId();
$stmt = GalleryItem::readById($db, $userId, $newGiId);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row)
throw new RuntimeException('Inserted row could not be found!');
$result=array(
"success" => TRUE,
"errorMessage" => "",
"filename" => $destFileName,
"filepath" => $destPath,
"record" => GalleryItem::fromRow($row)
);
$db->commit();
// set response code - 200 OK
http_response_code(200);
// show products data in json format
echo json_encode($result);
} catch (RuntimeException $e) {
$err_item=array(
"success" => FALSE,
"errorMessage" => $e->getMessage(),
"filename" => "",
"filepath" => "",
);
echo json_encode($err_item);
}
?>