Webservices
This commit is contained in:
27
services/www/api/authenticator.php
Normal file
27
services/www/api/authenticator.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
class Authenticator {
|
||||
|
||||
private $db;
|
||||
|
||||
function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function authenticate() {
|
||||
$token = $_SERVER['HTTP_AUTHENTICATION'];
|
||||
$query = "SELECT user_id FROM token WHERE token=:token AND expires>NOW() LIMIT 1";
|
||||
$stmt = $this->db->prepare($query);
|
||||
$stmt->bindParam(":token", $token);
|
||||
if($stmt->execute()){
|
||||
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// Token found
|
||||
return $row['user_id'];
|
||||
}
|
||||
}
|
||||
http_response_code(401);
|
||||
echo json_encode(array("error" => "Unauthorized"));
|
||||
exit();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
1
services/www/api/gallery_item/.htaccess
Normal file
1
services/www/api/gallery_item/.htaccess
Normal file
@@ -0,0 +1 @@
|
||||
LimitRequestBody 20480000
|
||||
82
services/www/api/gallery_item/read.php
Normal file
82
services/www/api/gallery_item/read.php
Normal 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);
|
||||
192
services/www/api/gallery_item/upload.php
Normal file
192
services/www/api/gallery_item/upload.php
Normal 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);
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
56
services/www/api/like/create.php
Normal file
56
services/www/api/like/create.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
header("Access-Control-Allow-Methods: POST");
|
||||
header("Access-Control-Max-Age: 3600");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||
|
||||
include_once '../../config/database.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();
|
||||
|
||||
// get posted data
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
if(!empty($data->gallery_id)) {
|
||||
$existentLike = Like::get($db, $userId, $data->gallery_id);
|
||||
if ($existentLike) {
|
||||
// Like already exists, return the existent one
|
||||
http_response_code(201);
|
||||
echo json_encode($existentLike);
|
||||
return;
|
||||
}
|
||||
|
||||
$like = new Like($db);
|
||||
$like->user_id = $userId;
|
||||
$like->gallery_id = $data->gallery_id;
|
||||
|
||||
$id = $like->create();
|
||||
if($id){
|
||||
$like->id = $id;
|
||||
// set response code - 201 created
|
||||
http_response_code(201);
|
||||
echo json_encode($like);
|
||||
} else {
|
||||
// unable to create
|
||||
http_response_code(500);
|
||||
echo json_encode(array("error" => "Unable to create Like."));
|
||||
}
|
||||
} else {
|
||||
// Missing parameters
|
||||
http_response_code(400);
|
||||
echo json_encode(array("error" => "Unable to create Like. Missing gallery_id."));
|
||||
}
|
||||
|
||||
?>
|
||||
50
services/www/api/like/delete.php
Normal file
50
services/www/api/like/delete.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
header("Access-Control-Allow-Methods: POST");
|
||||
header("Access-Control-Max-Age: 3600");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||
|
||||
include_once '../../config/database.php';
|
||||
include_once '../objects/like.php';
|
||||
include_once '../authenticator.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'DELETE') {
|
||||
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();
|
||||
|
||||
if(array_key_exists("id", $_GET) && $_GET["id"]) {
|
||||
$db->beginTransaction();
|
||||
// Get like before deleting
|
||||
$existentLike = Like::byUserAndId($db, $userId, $_GET["id"]);
|
||||
if(!$existentLike) {
|
||||
http_response_code(404);
|
||||
return;
|
||||
}
|
||||
|
||||
$success = Like::delete($db, $_GET["id"]);
|
||||
$db->commit();
|
||||
if($success){
|
||||
// set response code - 200 ok
|
||||
echo json_encode($existentLike);
|
||||
http_response_code(200);
|
||||
} else {
|
||||
// unable to create
|
||||
http_response_code(500);
|
||||
echo json_encode(array("error" => "Unable to delete Like."));
|
||||
}
|
||||
} else {
|
||||
// Missing parameters
|
||||
http_response_code(400);
|
||||
echo json_encode(array("error" => "Unable to delete Like. Missing id."));
|
||||
}
|
||||
|
||||
?>
|
||||
128
services/www/api/objects/gallery_item.php
Normal file
128
services/www/api/objects/gallery_item.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
class GalleryItem {
|
||||
|
||||
private const table_name = "gallery";
|
||||
private const select = "
|
||||
SELECT
|
||||
g.*,
|
||||
(select count(id) from gallery_like where gallery_id = g.id) as likes,
|
||||
|
||||
lu.id as lu_id,
|
||||
lu.name as lu_name,
|
||||
lu.surname as lu_surname,
|
||||
lu.code as lu_code,
|
||||
lu.picture as lu_picture,
|
||||
lu.admin as lu_admin,
|
||||
lu.table as lu_table,
|
||||
lu.witness as lu_witness,
|
||||
lu.invited_by as lu_invited_by,
|
||||
|
||||
au.id as au_id,
|
||||
au.name as au_name,
|
||||
au.surname as au_surname,
|
||||
au.code as au_code,
|
||||
au.picture as au_picture,
|
||||
au.admin as au_admin,
|
||||
au.table as au_table,
|
||||
au.witness as au_witness,
|
||||
au.invited_by as au_invited_by,
|
||||
|
||||
glcu.id as glcu_id,
|
||||
glcu.gallery_id as glcu_gallery_id,
|
||||
glcu.user_id as glcu_user_id,
|
||||
glcu.created as glcu_created
|
||||
|
||||
FROM " . self::table_name . " g
|
||||
-- Author
|
||||
LEFT JOIN `user` au
|
||||
ON au.id = g.author
|
||||
-- First liked user
|
||||
LEFT JOIN gallery_like gl
|
||||
ON gl.gallery_id = g.id
|
||||
LEFT JOIN `user` lu
|
||||
ON lu.id = gl.user_id
|
||||
-- Like from current user
|
||||
LEFT JOIN gallery_like glcu
|
||||
ON glcu.gallery_id = g.id
|
||||
AND glcu.user_id = :uid
|
||||
";
|
||||
|
||||
static function read($db, $uid, $page, $elemPerPage){
|
||||
$start = $page * $elemPerPage;
|
||||
$limit = $elemPerPage + 1; // Retrieve one more item to know if there are elements and compute "more" value
|
||||
$query = self::select . "
|
||||
GROUP BY g.id
|
||||
ORDER BY created DESC
|
||||
LIMIT :start,:limit";
|
||||
|
||||
// prepare query statement
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
$stmt->bindParam(":start", $start, PDO::PARAM_INT);
|
||||
$stmt->bindParam(":limit", $limit, PDO::PARAM_INT);
|
||||
|
||||
// execute query
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
static function readById($db, $uid, $id){
|
||||
$query = self::select . "
|
||||
WHERE g.id = :id
|
||||
GROUP BY g.id
|
||||
ORDER BY created DESC
|
||||
";
|
||||
// prepare query statement
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":id", $id);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
|
||||
// execute query
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
static function create($db, $item){
|
||||
$query = "INSERT INTO " . self::table_name . "
|
||||
SET image_url=:imageUrl, image_thumb_url=:imageThumbUrl, description=:description, author=:author";
|
||||
|
||||
// prepare query
|
||||
$stmt = $db->prepare($query);
|
||||
|
||||
// sanitize
|
||||
$imageUrl=htmlspecialchars(strip_tags($item['imageUrl']));
|
||||
$imageThumbUrl=htmlspecialchars(strip_tags($item['imageThumbUrl']));
|
||||
$description=htmlspecialchars(strip_tags($item['description']));
|
||||
$author=htmlspecialchars(strip_tags($item['author']));
|
||||
|
||||
// bind values
|
||||
$stmt->bindParam(":imageUrl", $imageUrl);
|
||||
$stmt->bindParam(":imageThumbUrl", $imageThumbUrl);
|
||||
$stmt->bindParam(":description", $description);
|
||||
$stmt->bindParam(":author", $author);
|
||||
|
||||
// execute query
|
||||
if($stmt->execute()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function fromRow($row) {
|
||||
return array(
|
||||
"id" => $row['id'],
|
||||
"imageUrl" => $row['image_url'],
|
||||
"imageThumbUrl" => $row['image_thumb_url'],
|
||||
"likes" => $row['likes'],
|
||||
"firstUserLiked" => User::createFromRow($row, 'lu'),
|
||||
"description" => $row['description'],
|
||||
"author" => User::createFromRow($row, 'au'),
|
||||
"created" => $row['created'],
|
||||
"currentUserLike" => Like::createFromRow($row, 'glcu'),
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
101
services/www/api/objects/like.php
Normal file
101
services/www/api/objects/like.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
class Like {
|
||||
private $conn;
|
||||
private const table_name = "gallery_like";
|
||||
|
||||
public $id;
|
||||
public $gallery_id;
|
||||
public $user_id;
|
||||
public $created;
|
||||
|
||||
public function __construct($db){
|
||||
$this->conn = $db;
|
||||
}
|
||||
|
||||
function create() {
|
||||
$query = "INSERT INTO " . self::table_name . "
|
||||
SET gallery_id=:galleryId, user_id=:userId";
|
||||
|
||||
// prepare query
|
||||
$stmt = $this->conn->prepare($query);
|
||||
|
||||
$this->created=(new \DateTime())->format('Y-m-d H:i:s');
|
||||
|
||||
// bind values
|
||||
$stmt->bindParam(":userId", $this->user_id);
|
||||
$stmt->bindParam(":galleryId", $this->gallery_id);
|
||||
|
||||
// execute query
|
||||
if($stmt->execute()){
|
||||
return $this->conn->lastInsertId();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function delete($db, $id) {
|
||||
$query = "DELETE FROM " . self::table_name . " WHERE id = :id";
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":id", $id);
|
||||
if($stmt->execute()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function createFromRow($row, $prefix = '') {
|
||||
if ($prefix)
|
||||
$prefix = $prefix . '_';
|
||||
else
|
||||
$prefix = '';
|
||||
|
||||
if (!$row[$prefix . 'id'])
|
||||
return null;
|
||||
|
||||
$instance = new self(null);
|
||||
$instance->id = $row[$prefix . 'id'];
|
||||
$instance->gallery_id = $row[$prefix . 'gallery_id'];
|
||||
$instance->user_id = $row[$prefix . 'user_id'];
|
||||
$instance->created = $row[$prefix . 'created'];
|
||||
return $instance;
|
||||
}
|
||||
|
||||
public static function get($db, $uid, $gid) {
|
||||
$q = "
|
||||
SELECT *
|
||||
FROM " . self::table_name . "
|
||||
WHERE
|
||||
user_id = :uid AND
|
||||
gallery_id = :gid
|
||||
";
|
||||
$stmt = $db->prepare($q);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
$stmt->bindParam(":gid", $gid);
|
||||
$stmt->execute();
|
||||
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row)
|
||||
return self::createFromRow($row);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function byUserAndId($db, $uid, $id) {
|
||||
$q = "
|
||||
SELECT *
|
||||
FROM " . self::table_name . "
|
||||
WHERE
|
||||
user_id = :uid AND
|
||||
id = :id
|
||||
";
|
||||
$stmt = $db->prepare($q);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
$stmt->bindParam(":id", $id);
|
||||
$stmt->execute();
|
||||
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row)
|
||||
return self::createFromRow($row);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
65
services/www/api/objects/presence.php
Normal file
65
services/www/api/objects/presence.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
class Presence {
|
||||
|
||||
// database connection and table name
|
||||
private $conn;
|
||||
private $table_name = "presence";
|
||||
|
||||
// object properties
|
||||
public $id;
|
||||
public $userId;
|
||||
public $willBePresent = false;
|
||||
public $notes = null;
|
||||
public $created;
|
||||
|
||||
// constructor with $db as database connection
|
||||
public function __construct($db){
|
||||
$this->conn = $db;
|
||||
}
|
||||
|
||||
static function read($db, $uid){
|
||||
$query = "
|
||||
SELECT will_be_present, notes
|
||||
FROM presence
|
||||
WHERE user_id = :uid
|
||||
ORDER BY created DESC
|
||||
LIMIT 1";
|
||||
|
||||
// prepare query statement
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
|
||||
// execute query
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function create(){
|
||||
|
||||
$query = "INSERT INTO " . $this->table_name . "
|
||||
SET user_id=:userId, will_be_present=:willBePresent, notes=:notes";
|
||||
|
||||
// prepare query
|
||||
$stmt = $this->conn->prepare($query);
|
||||
|
||||
// sanitize
|
||||
$this->userId=$this->userId;
|
||||
$this->created=(new \DateTime())->format('Y-m-d H:i:s');
|
||||
|
||||
|
||||
// bind values
|
||||
$stmt->bindParam(":userId", $this->userId);
|
||||
$wbp = $this->willBePresent ? 1 : 0;
|
||||
$stmt->bindParam(":willBePresent", $wbp);
|
||||
$stmt->bindParam(":notes", $this->notes);
|
||||
|
||||
// execute query
|
||||
if($stmt->execute()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
43
services/www/api/objects/token.php
Normal file
43
services/www/api/objects/token.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
class Token {
|
||||
private $conn;
|
||||
private $table_name = "token";
|
||||
|
||||
public $userId;
|
||||
public $user;
|
||||
public $token;
|
||||
public $created;
|
||||
public $expires;
|
||||
|
||||
// constructor with $db as database connection
|
||||
public function __construct($db){
|
||||
$this->conn = $db;
|
||||
}
|
||||
|
||||
function create(){
|
||||
$params = "user_id=:userId, token=:token, created=:created, expires=:expires";
|
||||
$query = "INSERT INTO " . $this->table_name . "
|
||||
SET " . $params;
|
||||
|
||||
// prepare query
|
||||
$stmt = $this->conn->prepare($query);
|
||||
|
||||
$this->created=(new \DateTime())->format('Y-m-d H:i:s');
|
||||
$this->expires=(new \DateTime())->add(new DateInterval('P1Y3M'))->format('Y-m-d H:i:s');
|
||||
$this->token=md5(sprintf('%d-%s', $this->userId, $this->expires));
|
||||
|
||||
// bind values
|
||||
$stmt->bindParam(":userId", $this->userId);
|
||||
$stmt->bindParam(":token", $this->token);
|
||||
$stmt->bindParam(":created", $this->created);
|
||||
$stmt->bindParam(":expires", $this->expires);
|
||||
|
||||
// execute query
|
||||
if($stmt->execute()){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
62
services/www/api/objects/user.php
Normal file
62
services/www/api/objects/user.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
class User {
|
||||
private $conn;
|
||||
private $table_name = "user";
|
||||
|
||||
public $id;
|
||||
public $name;
|
||||
public $surname;
|
||||
public $code;
|
||||
public $picture;
|
||||
public $admin;
|
||||
public $table;
|
||||
public $witness;
|
||||
public $invited_by;
|
||||
|
||||
// constructor with $db as database connection
|
||||
public function __construct($db){
|
||||
$this->conn = $db;
|
||||
}
|
||||
|
||||
static function get($db, $uid){
|
||||
$query = "
|
||||
SELECT *
|
||||
FROM user AS u
|
||||
WHERE u.id = :uid;
|
||||
";
|
||||
|
||||
// prepare query statement
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
|
||||
// execute query
|
||||
$stmt->execute();
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
public static function createFromRow($row, $prefix = '') {
|
||||
if ($prefix)
|
||||
$prefix = $prefix . '_';
|
||||
else
|
||||
$prefix = '';
|
||||
|
||||
// If user is null
|
||||
if (!$row[$prefix . 'id'])
|
||||
return null;
|
||||
|
||||
$instance = new self(null);
|
||||
$instance->id = $row[$prefix . 'id'];
|
||||
$instance->name = $row[$prefix . 'name'];
|
||||
$instance->surname = $row[$prefix . 'surname'];
|
||||
$instance->code = $row[$prefix . 'code'];
|
||||
$instance->picture = $row[$prefix . 'picture'];
|
||||
$instance->admin = $row[$prefix . 'admin'] ? true : false;
|
||||
$instance->table = $row[$prefix . 'table'];
|
||||
$instance->witness = $row[$prefix . 'witness'] ? true : false;
|
||||
$instance->invited_by = $row[$prefix . 'invited_by'];
|
||||
return $instance;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
42
services/www/api/presence/create.php
Normal file
42
services/www/api/presence/create.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
header("Access-Control-Allow-Methods: POST");
|
||||
header("Access-Control-Max-Age: 3600");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||
|
||||
include_once '../../config/database.php';
|
||||
include_once '../objects/presence.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();
|
||||
|
||||
// get posted data
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
|
||||
$p = new Presence($db);
|
||||
$p->userId = $userId;
|
||||
$p->willBePresent = $data->willBePresent;
|
||||
$p->notes = $data->notes;
|
||||
|
||||
if($p->create()){
|
||||
// set response code - 201 created
|
||||
http_response_code(201);
|
||||
echo json_encode($p);
|
||||
} else {
|
||||
// unable to create
|
||||
http_response_code(500);
|
||||
echo json_encode(array("error" => "Unable to create Presence."));
|
||||
}
|
||||
|
||||
?>
|
||||
51
services/www/api/presence/read.php
Normal file
51
services/www/api/presence/read.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Returns the current user response to the presence question.
|
||||
* Works as a list because the id should not be needed for the query.
|
||||
*/
|
||||
|
||||
// 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/presence.php';
|
||||
include_once '../objects/user.php';
|
||||
include_once '../authenticator.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'GET') {
|
||||
http_response_code(400);
|
||||
echo json_encode(array("error" => "Method not accepted."));
|
||||
exit();
|
||||
}
|
||||
|
||||
// instantiate database and product object
|
||||
$database = new Database();
|
||||
$db = $database->getConnection();
|
||||
|
||||
$auth = new Authenticator($db);
|
||||
$uid = $auth->authenticate();
|
||||
|
||||
// query products
|
||||
$stmt = Presence::read($db, $uid);
|
||||
|
||||
$resp=array();
|
||||
$resp["records"]=array();
|
||||
$resp["page"]=1;
|
||||
$resp["more"]=FALSE;
|
||||
|
||||
$presence = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($presence) {
|
||||
$resp["records"][] = [
|
||||
'willBePresent' => $presence['will_be_present'] ? true : false,
|
||||
'notes' => $presence['notes']
|
||||
];
|
||||
}
|
||||
|
||||
// set response code - 200 OK
|
||||
http_response_code(200);
|
||||
|
||||
// show products data in json format
|
||||
echo json_encode($resp);
|
||||
71
services/www/api/table/get.php
Normal file
71
services/www/api/table/get.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
// 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 '../authenticator.php';
|
||||
|
||||
/**
|
||||
* select all users (name, surname, table) sharing the same table
|
||||
*/
|
||||
function getTablePeople($db, $uid) {
|
||||
$q = '
|
||||
SELECT name, surname, `table`
|
||||
FROM `user` u
|
||||
WHERE
|
||||
u.`table` = (
|
||||
SELECT `table` FROM `user` WHERE id = :uid
|
||||
) AND
|
||||
u.id <> :uid
|
||||
';
|
||||
|
||||
// prepare query statement
|
||||
$stmt = $db->prepare($q);
|
||||
$stmt->bindParam(":uid", $uid);
|
||||
|
||||
// execute query
|
||||
$stmt->execute();
|
||||
$result = [
|
||||
'count' => 0,
|
||||
'people' => [],
|
||||
'table' => null,
|
||||
];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
|
||||
$result['count']++;
|
||||
$result['people'][] = [
|
||||
'name' => $row['name'],
|
||||
'surname' => $row['surname'],
|
||||
];
|
||||
$result['table'] = $row['table'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method implementation
|
||||
*/
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'GET') {
|
||||
http_response_code(400);
|
||||
echo json_encode(array("error" => "Method not accepted."));
|
||||
exit();
|
||||
}
|
||||
|
||||
// instantiate database
|
||||
$database = new Database();
|
||||
$db = $database->getConnection();
|
||||
|
||||
$auth = new Authenticator($db);
|
||||
$uid = $auth->authenticate();
|
||||
|
||||
$result = getTablePeople($db, $uid);
|
||||
|
||||
// set response code - 200 OK
|
||||
http_response_code(200);
|
||||
|
||||
// show products data in json format
|
||||
echo json_encode($result);
|
||||
61
services/www/api/token/create.php
Normal file
61
services/www/api/token/create.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Content-Type: application/json; charset=UTF-8");
|
||||
header("Access-Control-Allow-Methods: POST");
|
||||
header("Access-Control-Max-Age: 3600");
|
||||
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
|
||||
|
||||
include_once '../../config/database.php';
|
||||
include_once '../objects/token.php';
|
||||
include_once '../objects/user.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();
|
||||
|
||||
$token = new Token($db);
|
||||
|
||||
// get posted data
|
||||
$data = json_decode(file_get_contents("php://input"));
|
||||
|
||||
if(!empty($data->code)){
|
||||
// Check user existence
|
||||
$query = "SELECT * FROM user WHERE UPPER(code) = UPPER(:code) LIMIT 1";
|
||||
$stmt = $db->prepare($query);
|
||||
$stmt->bindParam(":code", $data->code);
|
||||
if($stmt->execute()){
|
||||
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
// User found
|
||||
$token->userId = $row['id'];
|
||||
$token->user = User::createFromRow($row);
|
||||
if($token->create()){
|
||||
// set response code - 201 created
|
||||
http_response_code(201);
|
||||
echo json_encode($token);
|
||||
} else {
|
||||
// unable to create
|
||||
http_response_code(500);
|
||||
echo json_encode(array("error" => "Unable to create Token."));
|
||||
}
|
||||
} else {
|
||||
// User not found
|
||||
|
||||
// Wait 5 secs to slow down bruteforce attacks
|
||||
sleep(5);
|
||||
|
||||
http_response_code(404);
|
||||
echo json_encode(array("error" => "Unable to create Token. User not found."));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Missing parameters
|
||||
http_response_code(400);
|
||||
echo json_encode(array("error" => "Unable to create Token. code is mandatory."));
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user