Продолжение разработки 23.10.31
Добавлен .gitignore, скрыты несколько нинужных файлов, в целом продолжен запил основных частей функционала, начат микрорефакторинг (теперь концентрация индусского кода будет чуть меньше).
This commit is contained in:
parent
e487ed79c4
commit
12143c148d
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
_temp/
|
||||
front/styles/bg_pattern_peace_old.png
|
||||
test.png
|
||||
TODO.md
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once("_db.php"); //("api/_db.php");
|
||||
// Includes
|
||||
require_once("_db.php");
|
||||
|
||||
|
||||
|
||||
|
@ -22,4 +22,16 @@ if (!$Config) {
|
||||
die("invalid configuration file");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Checking paths on existence
|
||||
|
||||
function CreateDirIfNotExist ($path) {
|
||||
if (!is_dir($path))
|
||||
mkdir($path, 0755, true);
|
||||
}
|
||||
|
||||
CreateDirIfNotExist("../" . $Config["media"]["pics_path"]);
|
||||
CreateDirIfNotExist("../" . $Config["media"]["prevs_path"]);
|
||||
|
||||
?>
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
// Internal errors
|
||||
$Err_Int_JSONEncode = "int.jsonencode"; // Failed to encode JSON data
|
||||
$Err_Int_Unexpected = "int.unexpected"; // Unexpected result
|
||||
|
||||
// Request data parsing errors
|
||||
$Err_RDP_InvalidID = "rdp.invalidid"; // Requested ID of resource is invalid
|
||||
$Err_RDP_InvalidArgs = "rdp.invalidargs"; // Invalid arguments supplied to method
|
||||
|
||||
// Data processing errors
|
||||
$Err_DP_IDNotFound = "dp.idnotfound"; // Resource not found by requested ID
|
||||
$Err_DP_AlreadyLoggedIn = "dp.alreadyloggedin"; // User already logged into account
|
||||
$Err_DP_RegClosed = "dp.regclosed"; // Registration is closed
|
||||
$Err_DP_NotEnoughRole = "dp.notenoughrole"; // Power level is not enough for performing action
|
||||
$Err_DP_FileTooLarge = "dp.filetoolarge"; // Size of file in request is too large
|
||||
$Err_DP_FileWrongType = "dp.filewrongtype"; // Type of file is invalid
|
||||
$Err_DP_ImageWrongRes = "dp.imagewrongres"; // Resolution of image is invalid
|
||||
?>
|
104
api/_errorslist.php
Normal file
104
api/_errorslist.php
Normal file
@ -0,0 +1,104 @@
|
||||
<?php // All existing errors
|
||||
|
||||
|
||||
|
||||
// All existing error codes as integers
|
||||
const E_NOERROR = 0; // No error
|
||||
// Unknown (unspecific) errors
|
||||
const E_UNS_UNEXPECTED = 101; // Unexpected result
|
||||
const E_UNS_NOTFOUND = 102; // Object not found
|
||||
const E_UNS_INTERNAL = 103; // Internal error occured
|
||||
const E_UNS_JSONBADINP = 104; // Cant encode object to JSON string
|
||||
const E_UNS_NOTIMPL = 105; // Not yet implemented
|
||||
// User input errors
|
||||
const E_UIN_WRONGID = 201; // Wrong object id (not found)
|
||||
const E_UIN_WRONGPATH = 202; // Wrong object path (not found)
|
||||
const E_UIN_FILE2LARGE = 203; // File size is too large
|
||||
const E_UIN_FILETYPE = 204; // Wrong file type
|
||||
const E_UIN_IMGBADRES = 205; // Invalid image resolution
|
||||
const E_UIN_INSUFARGS = 206; // Not enough arguments was supplied to method
|
||||
const E_UIN_BADARGS = 207; // Bad arguments
|
||||
// Authentication errors
|
||||
const E_AUT_ALRLOGIN = 301; // User is already logged in
|
||||
const E_AUT_REGCLOSED = 302; // Registrations are closed
|
||||
const E_AUT_PWD2WEAK = 303; // Password is too weak
|
||||
const E_AUT_NOTAUTHED = 304; // Not authenticated
|
||||
// Access errors
|
||||
const E_ACS_PERMDENIED = 401; // Permission to object denied
|
||||
const E_ACS_INSUFROLE = 402; // Insufficient role
|
||||
// Database-related errors
|
||||
const E_DBE_INSERTFAIL = 501; // INSERT query failed
|
||||
const E_DBE_SELECTFAIL = 502; // SELECT query failed
|
||||
const E_DBE_DELETEFAIL = 503; // DELETE query failed
|
||||
|
||||
|
||||
|
||||
// All existing errors as two-dimensional array
|
||||
$Errors_Enum = array(
|
||||
array("noerror", E_NOERROR, "no error"),
|
||||
// Unspecific errors
|
||||
array("uns.unexpected", E_UNS_UNEXPECTED, "unexpected result"),
|
||||
array("uns.notfound", E_UNS_NOTFOUND, "object not found"),
|
||||
array("uns.internal", E_UNS_INTERNAL, "internal error occured"),
|
||||
array("uns.jsonbadinp", E_UNS_JSONBADINP, "cant encode object to json string"),
|
||||
array("uns.notimpl", E_UNS_NOTIMPL, "not yet implemented"),
|
||||
// User input errors
|
||||
array("uin.wrongid", E_UIN_WRONGID, "wrong object id (not found)"),
|
||||
array("uin.wrongpath", E_UIN_WRONGPATH, "wrong object path (not found)"),
|
||||
array("uin.file2large", E_UIN_FILE2LARGE, "file size is too large"),
|
||||
array("uin.filetype", E_UIN_FILETYPE, "wrong file type"),
|
||||
array("uin.imgbadres", E_UIN_IMGBADRES, "invalid image resolution"),
|
||||
array("uin.insufargs", E_UIN_INSUFARGS, "not enough arguments was supplied to method"),
|
||||
array("uin.badargs", E_UIN_BADARGS, "bad arguments"),
|
||||
// Authentication errors
|
||||
array("aut.alrlogin", E_AUT_ALRLOGIN, "already logged in"),
|
||||
array("aut.regclosed", E_AUT_REGCLOSED, "registrations are closed"),
|
||||
array("aut.pwd2weak", E_AUT_PWD2WEAK, "password is too weak"),
|
||||
array("aut.notauthed", E_AUT_NOTAUTHED, "not authenticated"),
|
||||
// Access errors
|
||||
array("acs.permdenied", E_ACS_PERMDENIED, "permission denied"),
|
||||
array("acs.insufrole", E_ACS_INSUFROLE, "insufficient role"),
|
||||
// Database-related errors
|
||||
array("dbe.insertfail", E_DBE_INSERTFAIL, "insert query failed"),
|
||||
array("dbe.selectfail", E_DBE_SELECTFAIL, "select query failed"),
|
||||
array("dbe.deletefail", E_DBE_DELETEFAIL, "delete query failed")
|
||||
);
|
||||
|
||||
|
||||
|
||||
// Get error code by its name
|
||||
function Errors_ResolveCodeByName (string $name): int {
|
||||
global $Errors_Enum;
|
||||
$m = count($Errors_Enum);
|
||||
for ($i = 0; $i < $m; ++$i) {
|
||||
if ($Errors_Enum[$i][0] === $name)
|
||||
return $Errors_Enum[$i][1];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get error name by its code
|
||||
function Errors_ResolveNameByCode (int $id): string {
|
||||
global $Errors_Enum;
|
||||
$m = count($Errors_Enum);
|
||||
for ($i = 0; $i < $m; ++$i) {
|
||||
if ($Errors_Enum[$i][1] === $id)
|
||||
return $Errors_Enum[$i][0];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get error short description by its code
|
||||
function Errors_ResolveDescByCode (int $id): string {
|
||||
global $Errors_Enum;
|
||||
$m = count($Errors_Enum);
|
||||
for ($i = 0; $i < $m; ++$i) {
|
||||
if ($Errors_Enum[$i][1] === $id)
|
||||
return $Errors_Enum[$i][2];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
@ -1,24 +1,42 @@
|
||||
<?php
|
||||
<?php // JSON-related functions
|
||||
|
||||
require_once("_errors.php");
|
||||
// Includes
|
||||
require_once("_errorslist.php");
|
||||
|
||||
|
||||
|
||||
function ReturnJSONData ($arr) {
|
||||
// Write valid JSON data to stdout and exit
|
||||
function JSON_ReturnData ($arr) {
|
||||
$data = json_encode($arr);
|
||||
if (!$data) {
|
||||
$data = json_encode(array("error" => $Err_Int_JSONEncode));
|
||||
$data = json_encode(
|
||||
array(
|
||||
"error" => Errors_ResolveNameByCode(E_UNS_JSONBADINP)
|
||||
)
|
||||
);
|
||||
}
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo $data;
|
||||
exit;
|
||||
}
|
||||
|
||||
function ReturnJSONError ($err, $desc) {
|
||||
ReturnJSONData(array(
|
||||
"error" => $err,
|
||||
"description" => $desc
|
||||
// Return error as JSON data to stdout and exit
|
||||
function JSON_ReturnError (int $code = -1, string $name = "", string $desc = "") {
|
||||
if ($code === -1 && empty($name))
|
||||
JSON_ReturnError(code: E_UNS_INTERNAL, desc: "cant return error without specified code or name");
|
||||
else if ($code === -1)
|
||||
$code = Errors_ResolveCodeByName($name);
|
||||
else if (empty($name))
|
||||
$name = Errors_ResolveNameByCode($code);
|
||||
|
||||
JSON_ReturnData(array(
|
||||
"error" => $name, // Name
|
||||
"error_code" => $code, // Code
|
||||
"error_hum" => Errors_ResolveDescByCode($code), // Common description
|
||||
"description" => $desc // Detailed decription
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
91
api/_types.php
Normal file
91
api/_types.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php // Necessary functions, types and other stuff
|
||||
|
||||
// Includes
|
||||
require_once("_errorslist.php");
|
||||
require_once("_json.php");
|
||||
|
||||
|
||||
|
||||
final class ErrorT {
|
||||
private int $Code;
|
||||
private string $Name;
|
||||
private string $Description;
|
||||
|
||||
|
||||
// Ctor
|
||||
public function __construct(int $code = -1, string $name = "", string $desc = "") {
|
||||
if ($code === -1 && empty($name))
|
||||
JSON_ReturnError(code: E_UNS_INTERNAL, desc: "cant construct ErrorT without at least error code or name");
|
||||
else if ($code === -1)
|
||||
$code = Errors_ResolveCodeByName($name);
|
||||
else if (empty($name))
|
||||
$name = Errors_ResolveNameByCode($code);
|
||||
|
||||
$this->Code = $code;
|
||||
$this->Name = $name;
|
||||
$this->Description = $desc;
|
||||
}
|
||||
|
||||
// Getter for error code
|
||||
public function GetCode (): int {
|
||||
return $this->Code;
|
||||
}
|
||||
// Getter for error name
|
||||
public function GetName (): string {
|
||||
return $this->Name;
|
||||
}
|
||||
// Getter for error description
|
||||
public function GetDescription (): string {
|
||||
return $this->Description;
|
||||
}
|
||||
|
||||
// Stringify error
|
||||
public function Stringify (): string {
|
||||
if (isset($this->Description))
|
||||
return "error " . $this->Name . " (" . strval($this->Code) . "): " . $this->Description;
|
||||
else
|
||||
return "error " . $this->Name . " (" . strval($this->Code) . ")";
|
||||
}
|
||||
}
|
||||
|
||||
// Return type of API method
|
||||
final class ReturnT {
|
||||
private ErrorT $ErrorObj;
|
||||
private $Data;
|
||||
|
||||
|
||||
// Ctor
|
||||
public function __construct($data = null, int $err_code = 0, string $err_name = "", string $err_desc = "") {
|
||||
$this->ErrorObj = new ErrorT($err_code, $err_name, $err_desc);
|
||||
$this->Data = $data;
|
||||
}
|
||||
|
||||
// Setter/getter for data
|
||||
public function SetData ($d) {
|
||||
$this->Data = $d;
|
||||
}
|
||||
public function GetData () {
|
||||
return $this->Data;
|
||||
}
|
||||
|
||||
// Get string representation of error
|
||||
public function GetError (): string {
|
||||
return $this->ErrorObj->Stringify();
|
||||
}
|
||||
|
||||
// Is there any error
|
||||
public function IsError (): bool {
|
||||
return $this->ErrorObj->GetCode() !== E_NOERROR;
|
||||
}
|
||||
|
||||
// Throw JSON error
|
||||
function ThrowJSONError () {
|
||||
JSON_ReturnError(
|
||||
$this->ErrorObj->GetCode(),
|
||||
$this->ErrorObj->GetName(),
|
||||
$this->ErrorObj->Stringify()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -1,12 +1,14 @@
|
||||
<?php // Utility functions
|
||||
|
||||
|
||||
|
||||
// Check if request was to specified file
|
||||
function ThisFileIsRequested ($fullpath): bool {
|
||||
function Utils_ThisFileIsRequested ($fullpath): bool {
|
||||
return substr($fullpath, -strlen($_SERVER["SCRIPT_NAME"])) === $_SERVER["SCRIPT_NAME"];
|
||||
}
|
||||
|
||||
// Generate secure random string
|
||||
function GenerateRandomString (int $length, string $keyspace = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"): string {
|
||||
function Utils_GenerateRandomString (int $length, string $keyspace = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"): string {
|
||||
if ($length < 1) {
|
||||
die("cant generate random string of size less than 1");
|
||||
}
|
||||
@ -18,11 +20,22 @@ function GenerateRandomString (int $length, string $keyspace = "abcdefghijklmnop
|
||||
return implode('', $pieces);
|
||||
}
|
||||
|
||||
// Get aspect ratio from width and height
|
||||
function GetAspectRatio ($x, $y) {
|
||||
// Get ratio from two values
|
||||
function Utils_GetRatio ($x, $y) {
|
||||
if ($x === $y)
|
||||
return 1;
|
||||
return max($x, $y) / min($x, $y);
|
||||
}
|
||||
|
||||
// Join two or more paths pieces to single
|
||||
function Utils_JoinPaths () {
|
||||
$paths = array();
|
||||
foreach (func_get_args() as $arg) {
|
||||
if ($arg !== '') { $paths[] = $arg; }
|
||||
}
|
||||
return preg_replace('#/+#','/',join('/', $paths));
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
47
api/comments/index.php
Normal file
47
api/comments/index.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php // Get all comments from comment section by ID and base methods for managing comment sections
|
||||
|
||||
require_once("../_auth.php");
|
||||
require_once("../_utils.php");
|
||||
|
||||
|
||||
|
||||
// Get comments from range of selected comment section
|
||||
function ComSec_Get ($sec_id, $ts_from, $ts_to) {
|
||||
global $db;
|
||||
|
||||
$result = array();
|
||||
|
||||
$s = $db->prepare("SELECT * FROM posts WHERE id = ?");
|
||||
$s->bind_param("s", $id);
|
||||
$s->execute();
|
||||
$d = $s->get_result()->fetch_assoc();
|
||||
|
||||
if (!(bool)$d) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ThisFileIsRequested(__FILE__)) {
|
||||
require_once("../_json.php");
|
||||
|
||||
$SectionID = null;
|
||||
|
||||
if (isset($_REQUEST["id"])) {
|
||||
if (!ctype_digit($_REQUEST["id"]))
|
||||
ReturnJSONError($Err_RDP_InvalidID, "id must be numeric");
|
||||
$SectionID = intval($_REQUEST["id"]);
|
||||
} else {
|
||||
ReturnJSONError($Err_RDP_InvalidID, "id must be specified");
|
||||
}
|
||||
|
||||
/*
|
||||
$ResponseData = ComSec_GetComms($SectionID);
|
||||
if ($ResponseData)
|
||||
ReturnJSONData($ResponseData);
|
||||
else
|
||||
ReturnJSONError($Err_DP_IDNotFound, "wrong id");
|
||||
*/
|
||||
}
|
||||
|
||||
?>
|
@ -1,25 +1,96 @@
|
||||
<?php // Create new post
|
||||
|
||||
// Includes
|
||||
require_once("../_auth.php");
|
||||
require_once("../_utils.php");
|
||||
require_once("../_types.php");
|
||||
require_once("../user/index.php");
|
||||
|
||||
|
||||
|
||||
// Create single publication
|
||||
function Post_Create ($author, $tags, $pic_path, $title = null, $prev_path = null, $comms_enabled = false, $edit_lock = false) {
|
||||
/*
|
||||
* FUNCTION
|
||||
* Check if image size properties are valid
|
||||
*/
|
||||
function ImageSizeIsValid ($x, $y) {
|
||||
global $Config;
|
||||
|
||||
return ($x <= $Config["media"]["max_pic_res"]["x"])
|
||||
&& ($y <= $Config["media"]["max_pic_res"]["y"])
|
||||
&& (GetRatio($x, $y) <= $Config["media"]["max_pic_res"]["ratio"]);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION
|
||||
* Create preview version of image
|
||||
*/
|
||||
function Post_CreatePreviewFromImage ($src, $dst) {
|
||||
$img = null;
|
||||
|
||||
// Reading image from source path
|
||||
switch (mime_content_type($src)) {
|
||||
case "image/jpeg":
|
||||
$img = imagecreatefromjpeg($src);
|
||||
break;
|
||||
case "image/png":
|
||||
$img = imagecreatefrompng($src);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("invalid mime type");
|
||||
}
|
||||
|
||||
// Saving it as LQ JPEG
|
||||
imagejpeg($img, $dst, 30);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION
|
||||
* Store image
|
||||
*/
|
||||
function Post_StoreImage ($path, $preview = true) {
|
||||
global $Config;
|
||||
|
||||
// Paths
|
||||
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
|
||||
$fileName = strval(time()) . "_" . GenerateRandomString(4);
|
||||
$targetDir = "../../" . $Config["media"]["pics_path"];
|
||||
$targetPath = JoinPaths($targetDir, $fileName . "." . $ext);
|
||||
|
||||
// Creating preview file
|
||||
if ($Config["media"]["previews_enabled"] && $preview) {
|
||||
$previewDir = "../../" . $Config["media"]["prevs_path"];
|
||||
$previewPath = JoinPaths($previewDir, $fileName . ".jpg");
|
||||
Post_CreatePreviewFromImage($path, $previewPath);
|
||||
}
|
||||
|
||||
move_uploaded_file($path, $targetPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* METHOD
|
||||
* Create single publication
|
||||
*/
|
||||
function Post_Create ($author, $tags, $pic_path, $title = null, $prev_path = null, $comms_enabled = false, $edit_lock = false): ReturnT {
|
||||
global $db;
|
||||
|
||||
// $s = $db->prepare("INSERT ...");
|
||||
// $s->bind_param("s", $author);
|
||||
// $s->execute();
|
||||
// $d = $s->get_result()->fetch_assoc();
|
||||
//
|
||||
// if (!(bool)$d) {
|
||||
// return null;
|
||||
// }
|
||||
$result = null;
|
||||
|
||||
return $result;
|
||||
// Check post params
|
||||
// Author ID should exist
|
||||
if (!User_IDExist($author))
|
||||
// TODO
|
||||
|
||||
// Performing SQL query
|
||||
$s = $db->prepare("INSERT INTO posts (author_id,comment_section_id,tags,title,pic_path,preview_path,comments_enabled,edit_lock) VALUES (?,?,?,?,?,?,?,?)");
|
||||
$s->bind_param("ssssssss", $author, null, $tags, $title, $pic_path, $prev_path, $comms_enabled, $edit_lock);
|
||||
|
||||
if ($s->execute() !== true) {
|
||||
return new ReturnT(null, 601, "failed to create post record in DB");
|
||||
}
|
||||
|
||||
return new ReturnT($result);
|
||||
}
|
||||
|
||||
|
||||
@ -54,8 +125,16 @@ if (ThisFileIsRequested(__FILE__)) {
|
||||
|
||||
// Check if resolution is bigger than allowed or have unacceptable aspect ratio
|
||||
list($SzX, $SzY, $Type, $Attr) = getimagesize($TmpFilePath);
|
||||
if ($SzX > $Config["media"]["max_pic_res"]["x"] || $SzY > $Config["media"]["max_pic_res"]["y"] || (GetAspectRatio($SzX, $SzY) > $Config["media"]["max_pic_res"]["ratio"]))
|
||||
if (!Post_ImageIsValid($SzX, $SzY))
|
||||
ReturnJSONError($Err_DP_ImageWrongRes, "image with that resolution or aspect ratio cant be accepted");
|
||||
|
||||
// TODO: delete image if unacceptable
|
||||
|
||||
// Copy picture to storage folder
|
||||
Post_StoreImage($TmpFilePath, $Config)
|
||||
|
||||
// Create post
|
||||
//$success = Post_Create(
|
||||
}
|
||||
|
||||
?>
|
@ -1,23 +1,26 @@
|
||||
<?php // Start session as any user
|
||||
// ATTENTION: FOR DEBUG PURPOSES ONLY!
|
||||
|
||||
// Includes
|
||||
require_once("../_auth.php");
|
||||
require_once("../_utils.php");
|
||||
require_once("../_errorslist.php");
|
||||
|
||||
|
||||
|
||||
if (ThisFileIsRequested(__FILE__)) {
|
||||
if (Utils_ThisFileIsRequested(__FILE__)) {
|
||||
require_once("../_json.php");
|
||||
|
||||
if (!$Config["debug"])
|
||||
ReturnJSONError(null, "you need to enable debug mode in configuration file first");
|
||||
JSON_ReturnError(code: E_UNS_INTERNAL, desc: "you need to enable debug mode in configuration file first");
|
||||
|
||||
if (!isset($_REQUEST["id"]))
|
||||
ReturnJSONError($Err_RDP_InvalidID, "valid id must be specified");
|
||||
JSON_ReturnError(code: E_UIN_WRONGID, desc: "valid id must be specified");
|
||||
|
||||
if (!isset($_SESSION["userid"]))
|
||||
session_start();
|
||||
|
||||
$_SESSION["userid"] = intval($_REQUEST["id"]);
|
||||
ReturnJSONData($_SESSION);
|
||||
JSON_ReturnData($_SESSION);
|
||||
}
|
||||
?>
|
@ -1,16 +1,85 @@
|
||||
<?php // Creating account
|
||||
|
||||
// Includes
|
||||
require_once("../_auth.php");
|
||||
require_once("../_utils.php");
|
||||
require_once("./index.php");
|
||||
require_once("../_errorslist.php");
|
||||
require_once("../_types.php");
|
||||
require_once("index.php");
|
||||
|
||||
|
||||
|
||||
// Create new user account
|
||||
function User_Create ($login, $password, $email = null, $invite_id = null, $avatar_path = null): bool {
|
||||
global $db;
|
||||
// Methods
|
||||
|
||||
$salt = GenerateRandomString(8);
|
||||
/*
|
||||
* METHOD
|
||||
* Create new user account
|
||||
*/
|
||||
function User_Create_Method (array $req): ReturnT {
|
||||
global $db, $Config, $LOGGED_IN;
|
||||
|
||||
$login = null;
|
||||
$password = null;
|
||||
$email = null;
|
||||
$invite_id = null;
|
||||
$avatar_path = null;
|
||||
|
||||
// Input sanity checks
|
||||
|
||||
// If registration turned off
|
||||
if (!$Config["registration"]["active"])
|
||||
return new ReturnT(err_code: E_AUT_REGCLOSED);
|
||||
|
||||
// If user is logged in, then we should not allow creation of account
|
||||
if ($LOGGED_IN)
|
||||
return new ReturnT(err_code: E_AUT_ALRLOGIN);
|
||||
|
||||
// If we have some base data
|
||||
if (isset($req["login"]) && isset($req["password"])) {
|
||||
$login = $req["login"];
|
||||
$password = $req["password"];
|
||||
|
||||
// If password is too weak
|
||||
if (strlen($password) < 8)
|
||||
return new ReturnT(err_code: E_AUT_PWD2WEAK);
|
||||
|
||||
// If we need email but it isnt supplied
|
||||
if ($Config["registration"]["need_email"] && !isset($req["email"])) {
|
||||
return new ReturnT(err_code: E_UIN_INSUFARGS, err_desc: "email is necessary");
|
||||
} elseif (isset($req["email"])) {
|
||||
// Validation of email
|
||||
if (!filter_var($req["email"], FILTER_VALIDATE_EMAIL))
|
||||
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "email is invalid");
|
||||
$email = $req["email"];
|
||||
}
|
||||
// If we need invite but it isnt supplied
|
||||
if ($Config["registration"]["need_invite"] && !isset($req["invite_id"])) {
|
||||
return new ReturnT(err_code: E_UIN_INSUFARGS, err_desc: "registrations are invite-only, you need to specify invite ID");
|
||||
} elseif (isset($req["invite_id"])) {
|
||||
// TODO: check invite and reject if it invalid
|
||||
//$invite_id = $req["invite_id"];
|
||||
return new ReturnT(err_code: E_UNS_NOTIMPL, err_desc: "invitations are not implemented");
|
||||
}
|
||||
|
||||
// Check login and password for pattern match
|
||||
$preg_str = "/[^" . $Config["registration"]["allowed_syms"] . "]/";
|
||||
if (preg_match($preg_str, $login) || preg_match($preg_str, $password))
|
||||
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "only allowed symbols are: " . $Config["registration"]["allowed_syms"]);
|
||||
|
||||
// Check if login already exists
|
||||
if (User_LoginExist($login))
|
||||
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "login already exists");
|
||||
|
||||
// TODO: check $avatar_path
|
||||
} else { // Not enough arguments
|
||||
return new ReturnT(err_code: E_UIN_INSUFARGS, err_desc: "not enough or no arguments were supplied");
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
$result = null;
|
||||
|
||||
$salt = Utils_GenerateRandomString(8);
|
||||
$pwd_hash = hash("sha256", $password . $salt, true);
|
||||
|
||||
// TODO: process invite
|
||||
@ -18,71 +87,31 @@ function User_Create ($login, $password, $email = null, $invite_id = null, $avat
|
||||
$s = $db->prepare("INSERT INTO users (login,email,password_hash,salt,avatar_path,role,invite_id) VALUES (?,?,?,?,?,?,?)");
|
||||
$role = "newbie";
|
||||
$s->bind_param("sssssss", $login, $email, $pwd_hash, $salt, $avatar_path, $role, $invite_id);
|
||||
return $s->execute() !== false;
|
||||
$result = ($s->execute() !== false);
|
||||
|
||||
if (!$result)
|
||||
return new ReturnT(err_code: E_DBE_INSERTFAIL, err_desc: "cant insert record to users DB");
|
||||
|
||||
return new ReturnT(data: $result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ThisFileIsRequested(__FILE__)) {
|
||||
if (Utils_ThisFileIsRequested(__FILE__)) {
|
||||
require_once("../_json.php");
|
||||
|
||||
// Dirty hack for debugging purposes. Will be removed later
|
||||
// HACK: for debugging purposes. Will be removed later
|
||||
if ($Config["debug"])
|
||||
$_POST = $_REQUEST;
|
||||
|
||||
// If registration turned off
|
||||
if (!$Config["registration"]["active"]) {
|
||||
ReturnJSONError($Err_DP_RegClosed, "registrations are closed");
|
||||
}
|
||||
// Create account
|
||||
$result = User_Create_Method($_POST);
|
||||
|
||||
// If user is logged in, then we should not allow creation of account
|
||||
if ($LOGGED_IN)
|
||||
ReturnJSONError($Err_DP_AlreadyLoggedIn, "you are already logged in");
|
||||
|
||||
// If we have some POST data
|
||||
if (isset($_POST["login"]) && isset($_POST["password"])) {
|
||||
$login = $_POST["login"];
|
||||
$password = $_POST["password"];
|
||||
$email = null;
|
||||
$invite = null;
|
||||
|
||||
// If password is too weak
|
||||
if (strlen($password) < 8)
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "password too weak");
|
||||
|
||||
// If we need email but it isnt supplied
|
||||
if ($Config["registration"]["need_email"] && !isset($_POST["email"])) {
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "email is necessary");
|
||||
} elseif (isset($_POST["email"])) {
|
||||
// Validation of email
|
||||
if (!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL))
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "email is invalid");
|
||||
$email = $_POST["email"];
|
||||
}
|
||||
// If we need invite but it isnt supplied
|
||||
if ($Config["registration"]["need_invite"] && !isset($_POST["invite_id"])) {
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "registrations are invite-only");
|
||||
} elseif (isset($_POST["invite_id"])) {
|
||||
// TODO: check invite and reject if it invalid
|
||||
//$invite = $_POST["invite_id"];
|
||||
}
|
||||
|
||||
// Check login and password for pattern match
|
||||
$preg_str = "/[^" . $Config["registration"]["allowed_syms"] . "]/";
|
||||
if (preg_match($preg_str, $login) || preg_match($preg_str, $password)) {
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "only allowed symbols are: " . $Config["registration"]["allowed_syms"]);
|
||||
}
|
||||
|
||||
// Check if login already exists
|
||||
if (User_LoginExist($login))
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "login already exists");
|
||||
|
||||
// Create account
|
||||
$result = User_Create($login, $password, $email, $invite);
|
||||
ReturnJSONData(["success" => $result]);
|
||||
} else { // Not enough arguments
|
||||
ReturnJSONError($Err_RDP_InvalidArgs, "not enough or no arguments were supplied");
|
||||
}
|
||||
// Checking result
|
||||
if ($result->IsError())
|
||||
$result->ThrowJSONError();
|
||||
else
|
||||
JSON_ReturnData(["success" => $result->GetData()]);
|
||||
}
|
||||
|
||||
?>
|
@ -1,48 +1,66 @@
|
||||
<?php // Deleting existing account
|
||||
|
||||
// Includes
|
||||
require_once("../_auth.php");
|
||||
require_once("../_utils.php");
|
||||
require_once("../_errorslist.php");
|
||||
require_once("./index.php");
|
||||
|
||||
|
||||
|
||||
// Delete existing account
|
||||
function User_Delete ($id) {
|
||||
global $db;
|
||||
$s = $db->prepare("delete from users where id = ?");
|
||||
$s->bind_param("s", $id);
|
||||
return $s->execute() !== false;
|
||||
}
|
||||
// Methods
|
||||
|
||||
/*
|
||||
* METHOD
|
||||
* Delete existing account
|
||||
*/
|
||||
function User_Delete_Method (array $req): ReturnT {
|
||||
global $db, $LOGGED_IN, $THIS_USER;
|
||||
|
||||
$id = null;
|
||||
|
||||
if (ThisFileIsRequested(__FILE__)) {
|
||||
require_once("../_json.php");
|
||||
// Input sanity checks
|
||||
|
||||
// Dirty hack for debugging purposes. Will be removed later
|
||||
if ($Config["debug"])
|
||||
$_POST = $_REQUEST;
|
||||
|
||||
if (isset($_POST["id"]) && $LOGGED_IN) {
|
||||
if (!ctype_digit($_POST["id"]))
|
||||
ReturnJSONError($Err_RDP_InvalidID, "id must be numeric");
|
||||
$UserID = intval($_POST["id"]);
|
||||
} elseif (!isset($_POST["id"]) && $LOGGED_IN) {
|
||||
$UserID = $_SESSION["userid"];
|
||||
if (isset($req["id"]) && $LOGGED_IN) {
|
||||
if (!ctype_digit($req["id"]))
|
||||
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "id must be numeric");
|
||||
$id = intval($req["id"]);
|
||||
} elseif (!isset($req["id"]) && $LOGGED_IN) {
|
||||
$id = $THIS_USER;
|
||||
} else {
|
||||
ReturnJSONError($Err_RDP_InvalidID, "valid session must be provided");
|
||||
return new ReturnT(err_code: E_AUT_NOTAUTHED, err_desc: "valid session must be provided");
|
||||
}
|
||||
|
||||
// If its attempt to delete other account
|
||||
if (!User_HasRole($_SESSION["userid"], "admin") && $_SESSION["userid"] !== $UserID)
|
||||
ReturnJSONError($Err_DP_NotEnoughRole, "you need to be admin to delete other accounts");
|
||||
if (!User_HasRole($THIS_USER, "admin") && $THIS_USER !== $id)
|
||||
return new ReturnT(err_code: E_ACS_INSUFROLE, err_desc: "you must be admin to delete other accounts");
|
||||
|
||||
$result = User_Delete($UserID);
|
||||
// Actions
|
||||
|
||||
// If it was self-deletion
|
||||
if ($UserID === $_SESSION["userid"])
|
||||
EndSession();
|
||||
$s = $db->prepare("delete from users where id = ?");
|
||||
$s->bind_param("s", $id);
|
||||
|
||||
ReturnJSONData(["success" => $result]);
|
||||
return new ReturnT(data: ($s->execute() !== false));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Utils_ThisFileIsRequested(__FILE__)) {
|
||||
require_once("../_json.php");
|
||||
|
||||
// HACK: for debugging purposes. Will be removed later
|
||||
if ($Config["debug"])
|
||||
$_POST = $_REQUEST;
|
||||
|
||||
$result = User_Delete_Method($_POST);
|
||||
|
||||
if ($result->IsError()) {
|
||||
$result->ThrowJSONError();
|
||||
} else {
|
||||
// If it was self-deletion
|
||||
if ($id === $THIS_USER)
|
||||
EndSession();
|
||||
JSON_ReturnData(["success" => $result->GetData()]);
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,11 +1,19 @@
|
||||
<?php // Viewing account data
|
||||
|
||||
// Includes
|
||||
require_once("../_auth.php");
|
||||
require_once("../_utils.php");
|
||||
require_once("../_errorslist.php");
|
||||
require_once("../_types.php");
|
||||
|
||||
|
||||
|
||||
// Check if user with supplied login exists
|
||||
// Functions
|
||||
|
||||
/*
|
||||
* FUNCTION
|
||||
* Check if user with supplied login exists
|
||||
*/
|
||||
function User_LoginExist ($login): bool {
|
||||
global $db;
|
||||
|
||||
@ -16,7 +24,24 @@ function User_LoginExist ($login): bool {
|
||||
return (bool)$s->get_result()->fetch_assoc();
|
||||
}
|
||||
|
||||
// Check if user has specified role
|
||||
/*
|
||||
* FUNCTION
|
||||
* Check if user with supplied ID exists
|
||||
*/
|
||||
function User_IDExist ($id): bool {
|
||||
global $db;
|
||||
|
||||
$s = $db->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$s->bind_param("s", $id);
|
||||
$s->execute();
|
||||
|
||||
return (bool)$s->get_result()->fetch_assoc();
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION
|
||||
* Check if user has specified role
|
||||
*/
|
||||
function User_HasRole ($id, $role) {
|
||||
global $db;
|
||||
|
||||
@ -25,18 +50,19 @@ function User_HasRole ($id, $role) {
|
||||
$s->execute();
|
||||
$d = $s->get_result()->fetch_assoc();
|
||||
|
||||
if (!(bool)$d) {
|
||||
if (!(bool)$d)
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($d["role"] == $role) {
|
||||
if ($d["role"] == $role)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if user is moderator
|
||||
/*
|
||||
* FUNCTION
|
||||
* Check if user is moderator (or higher)
|
||||
*/
|
||||
function User_IsMod ($id) {
|
||||
global $db;
|
||||
|
||||
@ -52,9 +78,32 @@ function User_IsMod ($id) {
|
||||
return in_array($d["role"], array("mod", "admin"));
|
||||
}
|
||||
|
||||
// Get user information from DB
|
||||
function User_GetInfoByID ($id) {
|
||||
global $db, $THIS_USER;
|
||||
|
||||
|
||||
// Methods
|
||||
|
||||
/*
|
||||
* METHOD
|
||||
* Get user information from DB
|
||||
*/
|
||||
function User_GetInfoByID_Method (array $req): ReturnT {
|
||||
global $db, $THIS_USER, $LOGGED_IN;
|
||||
|
||||
// Input sanity checks
|
||||
|
||||
$id = null;
|
||||
if (isset($req["id"])) {
|
||||
if (!ctype_digit($req["id"]))
|
||||
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "id must be numeric");
|
||||
$id = intval($req["id"]);
|
||||
} else {
|
||||
if ($LOGGED_IN)
|
||||
$id = $THIS_USER;
|
||||
else
|
||||
return new ReturnT(err_code: E_UIN_BADARGS, err_desc: "id must be specified or valid session must be provided");
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
$result = array();
|
||||
|
||||
@ -63,9 +112,9 @@ function User_GetInfoByID ($id) {
|
||||
$s->execute();
|
||||
$d = $s->get_result()->fetch_assoc();
|
||||
|
||||
if (!(bool)$d) {
|
||||
return null;
|
||||
}
|
||||
if (!(bool)$d)
|
||||
return new ReturnT(err_code: E_UIN_WRONGID, err_desc: "user not found in database");
|
||||
//return new ReturnT(err_code: E_DBE_SELECTFAIL, err_desc: "failed to get user record");
|
||||
|
||||
$result["id"] = $d["id"];
|
||||
$result["created_at"] = $d["created_at"];
|
||||
@ -78,32 +127,22 @@ function User_GetInfoByID ($id) {
|
||||
$result["invite_id"] = $d["invite_id"];
|
||||
}
|
||||
|
||||
return $result;
|
||||
return new ReturnT(data: $result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (ThisFileIsRequested(__FILE__)) {
|
||||
if (Utils_ThisFileIsRequested(__FILE__)) {
|
||||
require_once("../_json.php");
|
||||
|
||||
$UserID = null;
|
||||
$result = User_GetInfoByID_Method($_REQUEST);
|
||||
|
||||
if (isset($_REQUEST["id"])) {
|
||||
if (!ctype_digit($_REQUEST["id"]))
|
||||
ReturnJSONError($Err_RDP_InvalidID, "id must be numeric");
|
||||
$UserID = intval($_REQUEST["id"]);
|
||||
} else {
|
||||
if ($LOGGED_IN)
|
||||
$UserID = $THIS_USER;
|
||||
else
|
||||
ReturnJSONError($Err_RDP_InvalidID, "id must be specified or valid session must be provided");
|
||||
}
|
||||
|
||||
$ResponseData = User_GetInfoByID($UserID);
|
||||
if ($ResponseData)
|
||||
ReturnJSONData($ResponseData);
|
||||
if ($result->IsError())
|
||||
$result->ThrowJSONError();
|
||||
else
|
||||
ReturnJSONError($Err_DP_IDNotFound, "wrong id");
|
||||
JSON_ReturnData($result->GetData());
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
@ -16,6 +16,9 @@
|
||||
"external_avatars": false
|
||||
},
|
||||
"media": {
|
||||
"pics_path": "media/pics/",
|
||||
"prevs_path": "media/prevs/",
|
||||
"previews_enabled": true,
|
||||
"max_pic_size": 56623104,
|
||||
"max_pic_res": {
|
||||
"x": 8192,
|
||||
|
Loading…
Reference in New Issue
Block a user