Most User endpoints
This commit is contained in:
parent
b3c5841e36
commit
4b89a7e9ca
@ -14,11 +14,6 @@ RewriteRule ^phpCourse/exam/vendor/.* index.php [L,NC]
|
|||||||
RewriteRule ^phpCourse/exam/routes/.* index.php [L,NC]
|
RewriteRule ^phpCourse/exam/routes/.* index.php [L,NC]
|
||||||
RewriteRule ^phpCourse/exam/react/.* index.php [L,NC]
|
RewriteRule ^phpCourse/exam/react/.* index.php [L,NC]
|
||||||
|
|
||||||
RewriteCond %{REQUEST_FILENAME} -f
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !/uploads/.*
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !/dist/.*
|
|
||||||
RewriteRule ^ dist [L,NC]
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## API routes
|
## API routes
|
||||||
##
|
##
|
||||||
@ -32,4 +27,10 @@ RewriteRule ^ api/index.php [L,NC,QSA]
|
|||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
RewriteCond %{REQUEST_FILENAME} !/api/docs
|
RewriteCond %{REQUEST_FILENAME} !/api/docs
|
||||||
RewriteCond %{REQUEST_FILENAME} !/dist
|
RewriteCond %{REQUEST_FILENAME} !/dist
|
||||||
RewriteRule ^ dist [L,NC,QSA]
|
RewriteRule ^ dist [L,NC,QSA]
|
||||||
|
|
||||||
|
RewriteCond %{REQUEST_FILENAME} -f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !/storage/.*
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !/dist/.*
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !/api/docs
|
||||||
|
RewriteRule ^ dist [L,NC]
|
||||||
@ -45,4 +45,29 @@ class User
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function postSelf()
|
||||||
|
{
|
||||||
|
$token = Input::header("token");
|
||||||
|
$username = Input::post("username");
|
||||||
|
$password = Input::post("password");
|
||||||
|
$image = Input::file("image");
|
||||||
|
|
||||||
|
try {
|
||||||
|
return json_encode(MUser::getByToken($token)->update($username, $password, $image));
|
||||||
|
} catch (Exception $err) {
|
||||||
|
switch ($err->getMessage()) {
|
||||||
|
case "NotFound":
|
||||||
|
throw new Exception("User not Found", 404);
|
||||||
|
case "FailedUsername":
|
||||||
|
throw new Exception("Failed to update username", 500);
|
||||||
|
case "FailedPassword":
|
||||||
|
throw new Exception("Failed to update password", 500);
|
||||||
|
case "FailedImage":
|
||||||
|
throw new Exception("Failed to update image", 500);
|
||||||
|
default:
|
||||||
|
throw $err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,7 +128,10 @@ paths:
|
|||||||
- User
|
- User
|
||||||
post:
|
post:
|
||||||
summary: Update user
|
summary: Update user
|
||||||
description: Update user with ID. Fields are updated in order username,password,image. If one fails, subsequent are not updated
|
description:
|
||||||
|
Update user with ID. Fields are updated in order username, password, image. If one fails, subsequent are not updated. <br>
|
||||||
|
Use special ID <code>self</code> to update logged in user. <br>
|
||||||
|
Requires logged in user to have admin permissions for any ID other than <code>self</code>. <br>
|
||||||
security:
|
security:
|
||||||
- BasicAuth: []
|
- BasicAuth: []
|
||||||
parameters:
|
parameters:
|
||||||
@ -228,6 +231,7 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
image:
|
image:
|
||||||
type: string
|
type: string
|
||||||
|
format: binary
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
BasicAuth:
|
BasicAuth:
|
||||||
type: apiKey
|
type: apiKey
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -4,6 +4,11 @@ namespace Khofmann\Input;
|
|||||||
|
|
||||||
class Input
|
class Input
|
||||||
{
|
{
|
||||||
|
public static function header($name, $defaultValue = null, $tryParse = true)
|
||||||
|
{
|
||||||
|
return request()->getHeader($name, $defaultValue, $tryParse);
|
||||||
|
}
|
||||||
|
|
||||||
public static function post($index, $defaultValue = null)
|
public static function post($index, $defaultValue = null)
|
||||||
{
|
{
|
||||||
return request()->getInputHandler()->post($index, $defaultValue);
|
return request()->getInputHandler()->post($index, $defaultValue);
|
||||||
|
|||||||
@ -4,6 +4,7 @@ namespace Khofmann\Models\User;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
use DateTime;
|
||||||
use Khofmann\Database\Database;
|
use Khofmann\Database\Database;
|
||||||
use Config\Config;
|
use Config\Config;
|
||||||
use JsonSerializable;
|
use JsonSerializable;
|
||||||
@ -16,8 +17,9 @@ class User implements JsonSerializable
|
|||||||
private string $email;
|
private string $email;
|
||||||
private ?string $image;
|
private ?string $image;
|
||||||
private bool $isAdmin;
|
private bool $isAdmin;
|
||||||
|
private DateTime $memberSince;
|
||||||
|
|
||||||
protected function __construct(int $id, string $username, int $status, string $email, string $image = null, bool $isAdmin = false)
|
protected function __construct(int $id, string $username, int $status, string $email, string $timestamp, string $image, bool $isAdmin)
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
$this->username = $username;
|
$this->username = $username;
|
||||||
@ -25,6 +27,7 @@ class User implements JsonSerializable
|
|||||||
$this->email = $email;
|
$this->email = $email;
|
||||||
$this->image = $image;
|
$this->image = $image;
|
||||||
$this->isAdmin = $isAdmin;
|
$this->isAdmin = $isAdmin;
|
||||||
|
$this->memberSince = new DateTime($timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -35,7 +38,7 @@ class User implements JsonSerializable
|
|||||||
{
|
{
|
||||||
$db = Database::getInstance();
|
$db = Database::getInstance();
|
||||||
$stmt = $db->prepare(
|
$stmt = $db->prepare(
|
||||||
"SELECT benutzer, status, email, image, isadmin FROM egb_benutzer WHERE id = :ID"
|
"SELECT benutzer, status, email, image, isadmin, zeitstempel FROM egb_benutzer WHERE id = :ID"
|
||||||
);
|
);
|
||||||
$stmt->bindValue(":ID", $id);
|
$stmt->bindValue(":ID", $id);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
@ -43,14 +46,14 @@ class User implements JsonSerializable
|
|||||||
|
|
||||||
if (!$data) throw new Exception("NotFound");
|
if (!$data) throw new Exception("NotFound");
|
||||||
|
|
||||||
return new User($id, $data["benutzer"], $data["status"], $data["email"], $data["image"], $data["isadmin"] === 1);
|
return new User($id, $data["benutzer"], $data["status"], $data["email"], $data["zeitstempel"], $data["image"], $data["isadmin"] === 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getByEmail(string $email): User
|
public static function getByEmail(string $email): User
|
||||||
{
|
{
|
||||||
$db = Database::getInstance();
|
$db = Database::getInstance();
|
||||||
$stmt = $db->prepare(
|
$stmt = $db->prepare(
|
||||||
"SELECT id, benutzer, status, image, isadmin FROM egb_benutzer WHERE email = :EMAIL"
|
"SELECT id, benutzer, status, image, isadmin, zeitstempel FROM egb_benutzer WHERE email = :EMAIL"
|
||||||
);
|
);
|
||||||
$stmt->bindValue(":EMAIL", $email);
|
$stmt->bindValue(":EMAIL", $email);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
@ -58,14 +61,14 @@ class User implements JsonSerializable
|
|||||||
|
|
||||||
if (!$data) throw new Exception("NotFound");
|
if (!$data) throw new Exception("NotFound");
|
||||||
|
|
||||||
return new User($data["id"], $data["benutzer"], $data["status"], $email, $data["image"], $data["isadmin"] === 1);
|
return new User($data["id"], $data["benutzer"], $data["status"], $email, $data["zeitstempel"], $data["image"], $data["isadmin"] === 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getByToken(string $token): User
|
public static function getByToken(string $token): User
|
||||||
{
|
{
|
||||||
$db = Database::getInstance();
|
$db = Database::getInstance();
|
||||||
$stmt = $db->prepare(
|
$stmt = $db->prepare(
|
||||||
"SELECT id, benutzer, status, email, image, isadmin FROM egb_benutzer WHERE token = :TOKEN"
|
"SELECT id, benutzer, status, email, image, isadmin, zeitstempel FROM egb_benutzer WHERE token = :TOKEN"
|
||||||
);
|
);
|
||||||
$stmt->bindValue(":TOKEN", $token);
|
$stmt->bindValue(":TOKEN", $token);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
@ -73,7 +76,7 @@ class User implements JsonSerializable
|
|||||||
|
|
||||||
if (!$data) throw new Exception("NotFound");
|
if (!$data) throw new Exception("NotFound");
|
||||||
|
|
||||||
return new User($data["id"], $data["benutzer"], $data["status"], $data["email"], $data["image"], $data["isadmin"] === 1);
|
return new User($data["id"], $data["benutzer"], $data["status"], $data["email"], $data["zeitstempel"], $data["image"], $data["isadmin"] === 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function logIn(string $email, string $password): array
|
public static function logIn(string $email, string $password): array
|
||||||
@ -86,7 +89,7 @@ class User implements JsonSerializable
|
|||||||
$data = $stmt->fetch();
|
$data = $stmt->fetch();
|
||||||
|
|
||||||
if ($data) {
|
if ($data) {
|
||||||
$user = new User($data["id"], $data["benutzer"], $data["status"], $email, $data["image"], $data["isadmin"] === 1);
|
$user = new User($data["id"], $data["benutzer"], $data["status"], $email, $data["zeitstempel"], $data["image"], $data["isadmin"] === 1);
|
||||||
if (password_verify($password, $data["passwort"])) {
|
if (password_verify($password, $data["passwort"])) {
|
||||||
// REHASH for safety should it somehow change
|
// REHASH for safety should it somehow change
|
||||||
if (password_needs_rehash($data["passwort"], PASSWORD_DEFAULT)) {
|
if (password_needs_rehash($data["passwort"], PASSWORD_DEFAULT)) {
|
||||||
@ -156,7 +159,7 @@ class User implements JsonSerializable
|
|||||||
|
|
||||||
if (!empty($image)) {
|
if (!empty($image)) {
|
||||||
$destinationFilename = sprintf('%s.%s', uniqid(), $image->getExtension());
|
$destinationFilename = sprintf('%s.%s', uniqid(), $image->getExtension());
|
||||||
$image->move(Config::getBaseFSPath() . "uploads/profilbilder/$destinationFilename");
|
$image->move(Config::getStoragePath() . "profilbilder/$destinationFilename");
|
||||||
|
|
||||||
$stmt = $db->prepare("UPDATE egb_benutzer SET image = :IMG WHERE id = :ID");
|
$stmt = $db->prepare("UPDATE egb_benutzer SET image = :IMG WHERE id = :ID");
|
||||||
$stmt->bindValue(":IMG", $destinationFilename);
|
$stmt->bindValue(":IMG", $destinationFilename);
|
||||||
@ -202,6 +205,11 @@ class User implements JsonSerializable
|
|||||||
return $this->isAdmin;
|
return $this->isAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMemberSince(): DateTime
|
||||||
|
{
|
||||||
|
return $this->memberSince;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* JSON
|
* JSON
|
||||||
*/
|
*/
|
||||||
@ -214,7 +222,8 @@ class User implements JsonSerializable
|
|||||||
'status' => $this->getStatus(),
|
'status' => $this->getStatus(),
|
||||||
'email' => $this->getEmail(),
|
'email' => $this->getEmail(),
|
||||||
'image' => $this->getImage(),
|
'image' => $this->getImage(),
|
||||||
'isAdmin' => $this->getIsAdmin()
|
'isAdmin' => $this->getIsAdmin(),
|
||||||
|
'memberSince' => $this->getMemberSince(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,11 @@ class Config
|
|||||||
return Config::getInstance()->app["baseFSPath"];
|
return Config::getInstance()->app["baseFSPath"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getStoragePath()
|
||||||
|
{
|
||||||
|
return Config::getInstance()->app["storagePath"];
|
||||||
|
}
|
||||||
|
|
||||||
public static function getDatabase()
|
public static function getDatabase()
|
||||||
{
|
{
|
||||||
return Config::getInstance()->database;
|
return Config::getInstance()->database;
|
||||||
|
|||||||
@ -2,5 +2,6 @@
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
"basePath" => "phpCourse/exam/",
|
"basePath" => "phpCourse/exam/",
|
||||||
"baseFSPath" => "/home/k/khofmann/public_html/phpCourse/exam/"
|
"baseFSPath" => "/home/k/khofmann/public_html/phpCourse/exam/",
|
||||||
|
"storagePath" => "/home/k/khofmann/public_html/phpCourse/exam/storage/"
|
||||||
];
|
];
|
||||||
|
|||||||
10
exam/package.json
Normal file
10
exam/package.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "php-course-exam",
|
||||||
|
"description": "End of Course Exam",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {},
|
||||||
|
"scripts": {
|
||||||
|
"generate-api-docs": "npx @redocly/cli build-docs --output api/docs/index.html api/docs/api.yaml"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,13 +11,27 @@ SimpleRouter::error(function (Request $request, Exception $exception) {
|
|||||||
SimpleRouter::all("/", function () {
|
SimpleRouter::all("/", function () {
|
||||||
redirect("docs", 301);
|
redirect("docs", 301);
|
||||||
});
|
});
|
||||||
// Login/Logout
|
|
||||||
|
/*
|
||||||
|
* Open routes
|
||||||
|
*/
|
||||||
|
// Login
|
||||||
SimpleRouter::post("/login", [Api\Login\Login::class, "post"]);
|
SimpleRouter::post("/login", [Api\Login\Login::class, "post"]);
|
||||||
|
/*
|
||||||
|
* Normal Auth routes
|
||||||
|
*/
|
||||||
SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
|
SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
|
||||||
|
// Login
|
||||||
SimpleRouter::post("/logout", [Api\Logout\Logout::class, "post"]);
|
SimpleRouter::post("/logout", [Api\Logout\Logout::class, "post"]);
|
||||||
|
// Get any user
|
||||||
|
SimpleRouter::get("/user/{id}", [Api\User\User::class, "get"]);
|
||||||
|
// Update self
|
||||||
|
SimpleRouter::post("/user/self", [Api\User\User::class, "postSelf"]);
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
* Admin Auth routes
|
||||||
|
*/
|
||||||
|
SimpleRouter::group(["middleware" => \Khofmann\Auth\AdminAuth::class], function () {
|
||||||
|
// Update any user
|
||||||
|
SimpleRouter::post("/user/{id}", [Api\User\User::class, "post"]);
|
||||||
});
|
});
|
||||||
// User
|
|
||||||
//SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
|
|
||||||
SimpleRouter::get("/user/{id}", [Api\User\User::class, "get"]);
|
|
||||||
SimpleRouter::post("/user/{id}", [Api\User\User::class, "post"]);
|
|
||||||
//});
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user