Image now a file
This commit is contained in:
parent
8d91e805dd
commit
b3c5841e36
@ -14,6 +14,11 @@ RewriteRule ^phpCourse/exam/vendor/.* index.php [L,NC]
|
||||
RewriteRule ^phpCourse/exam/routes/.* 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
|
||||
##
|
||||
|
||||
@ -9,8 +9,13 @@ class Login
|
||||
{
|
||||
public function post()
|
||||
{
|
||||
$email = Input::post("email");
|
||||
if (empty($email)) throw new Exception("Missing email", 400);
|
||||
$password = Input::post("password");
|
||||
if (empty($password)) throw new Exception("Missing Password", 400);
|
||||
|
||||
try {
|
||||
$response = \Khofmann\Models\User\User::logIn(Input::post("email"), Input::post("password"));
|
||||
$response = \Khofmann\Models\User\User::logIn($email, $password);
|
||||
return json_encode($response);
|
||||
} catch (Exception $err) {
|
||||
switch ($err->getMessage()) {
|
||||
@ -20,6 +25,8 @@ class Login
|
||||
throw new Exception("User not Found", 404);
|
||||
case "Invalid":
|
||||
throw new Exception("Invalid Username or Password", 401);
|
||||
default:
|
||||
throw $err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,6 @@ class Logout
|
||||
public function post()
|
||||
{
|
||||
$token = request()->getHeader("token");
|
||||
return json_decode(User::getByToken($token)->logOut($token));
|
||||
return json_decode(User::getByToken($token)->logOut());
|
||||
}
|
||||
}
|
||||
|
||||
48
exam/api/User/User.php
Normal file
48
exam/api/User/User.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Api\User;
|
||||
|
||||
use Exception;
|
||||
use Khofmann\Models\User\User as MUser;
|
||||
use Khofmann\Input\Input;
|
||||
|
||||
class User
|
||||
{
|
||||
public function get($id)
|
||||
{
|
||||
try {
|
||||
return json_encode(MUser::getByID($id));
|
||||
} catch (Exception $err) {
|
||||
switch ($err->getMessage()) {
|
||||
case "NotFound":
|
||||
throw new Exception("User not Found", 404);
|
||||
default:
|
||||
throw $err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function post($id)
|
||||
{
|
||||
$username = Input::post("username");
|
||||
$password = Input::post("password");
|
||||
$image = Input::file("image");
|
||||
|
||||
try {
|
||||
return json_encode(MUser::getByID($id)->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,6 +27,15 @@ paths:
|
||||
examples:
|
||||
Success:
|
||||
value: true
|
||||
400:
|
||||
description: Missing Fields
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
examples:
|
||||
Missing Fields:
|
||||
value: { "message": "Missing email" }
|
||||
401:
|
||||
description: Invalid credentials
|
||||
content:
|
||||
@ -74,6 +83,97 @@ paths:
|
||||
value: true
|
||||
tags:
|
||||
- Login/Logout
|
||||
/user{id}:
|
||||
get:
|
||||
summary: Get user
|
||||
description: Get user by ID
|
||||
security:
|
||||
- BasicAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: User ID
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int14
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UserResponse"
|
||||
examples:
|
||||
Success:
|
||||
value:
|
||||
{
|
||||
"id": 1,
|
||||
"username": "Admin",
|
||||
"status": 1,
|
||||
"email": "marvin@zedat.fu-berlin.de",
|
||||
"image": "profilbilder\\/admin.svg",
|
||||
"isAdmin": true,
|
||||
}
|
||||
404:
|
||||
description: User not Found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
examples:
|
||||
User not Found:
|
||||
value: { "message": "User not Found" }
|
||||
tags:
|
||||
- User
|
||||
post:
|
||||
summary: Update user
|
||||
description: Update user with ID. Fields are updated in order username,password,image. If one fails, subsequent are not updated
|
||||
security:
|
||||
- BasicAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: User ID
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
format: int14
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UserUpdateRequest"
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BooleanResponse"
|
||||
examples:
|
||||
Success:
|
||||
value: true
|
||||
404:
|
||||
description: User not Found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
examples:
|
||||
User not Found:
|
||||
value: { "message": "User not Found" }
|
||||
500:
|
||||
description: Update failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
examples:
|
||||
User not Found:
|
||||
value: { "message": "Failed to update username" }
|
||||
tags:
|
||||
- User
|
||||
|
||||
externalDocs:
|
||||
url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/
|
||||
@ -103,6 +203,31 @@ components:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
UserResponse:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: number
|
||||
username:
|
||||
type: string
|
||||
status:
|
||||
type: number
|
||||
email:
|
||||
type: string
|
||||
image:
|
||||
type: string
|
||||
nullable: true
|
||||
isAdmin:
|
||||
type: boolean
|
||||
UserUpdateRequest:
|
||||
type: object
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
image:
|
||||
type: string
|
||||
securitySchemes:
|
||||
BasicAuth:
|
||||
type: apiKey
|
||||
@ -110,5 +235,4 @@ components:
|
||||
in: header
|
||||
tags:
|
||||
- name: Login/Logout
|
||||
- name: Users
|
||||
- name: Posts
|
||||
- name: User
|
||||
|
||||
File diff suppressed because one or more lines are too long
30
exam/classes/.htaccess
Normal file
30
exam/classes/.htaccess
Normal file
@ -0,0 +1,30 @@
|
||||
RewriteEngine On
|
||||
|
||||
##
|
||||
## You may need to uncomment the following line for some hosting environments,
|
||||
## if you have installed to a subdirectory, enter the name here also.
|
||||
##
|
||||
RewriteBase /phpCourse/exam
|
||||
|
||||
##
|
||||
## Black listed folders
|
||||
##
|
||||
RewriteRule ^phpCourse/exam/config/.* index.php [L,NC]
|
||||
RewriteRule ^phpCourse/exam/vendor/.* index.php [L,NC]
|
||||
RewriteRule ^phpCourse/exam/routes/.* index.php [L,NC]
|
||||
RewriteRule ^phpCourse/exam/react/.* index.php [L,NC]
|
||||
|
||||
##
|
||||
## API routes
|
||||
##
|
||||
RewriteCond %{REQUEST_FILENAME} /api/.*
|
||||
RewriteCond %{REQUEST_FILENAME} !/api/docs
|
||||
RewriteRule ^ api/index.php [L,NC,QSA]
|
||||
|
||||
##
|
||||
## Standard routes
|
||||
##
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !/api/docs
|
||||
RewriteCond %{REQUEST_FILENAME} !/dist
|
||||
RewriteRule ^ dist [L,NC,QSA]
|
||||
31
exam/classes/Auth/AdminAuth.php
Normal file
31
exam/classes/Auth/AdminAuth.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Khofmann\Auth;
|
||||
|
||||
use Exception;
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
use Khofmann\Models\User\User;
|
||||
|
||||
class AdminAuth implements IMiddleware
|
||||
{
|
||||
public function handle(Request $request): void
|
||||
{
|
||||
$token = $request->getHeader("token");
|
||||
|
||||
// No token
|
||||
if ($token === null) {
|
||||
response()->httpCode(401)->json(["message" => "Not Authorized"]);
|
||||
}
|
||||
|
||||
try {
|
||||
$user = User::getByToken($token);
|
||||
if (!$user->getIsAdmin()) {
|
||||
response()->httpCode(401)->json(["message" => "Not Authorized"]);
|
||||
}
|
||||
} catch (Exception $err) {
|
||||
// No user with this token exists
|
||||
response()->httpCode(401)->json(["message" => "Not Authorized"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,17 +4,18 @@ namespace Khofmann\Input;
|
||||
|
||||
class Input
|
||||
{
|
||||
private static function input($index = null, $defaultValue = null, ...$methods)
|
||||
{
|
||||
if ($index !== null) {
|
||||
return request()->getInputHandler()->value($index, $defaultValue, ...$methods);
|
||||
}
|
||||
|
||||
return request()->getInputHandler();
|
||||
}
|
||||
|
||||
public static function post($index, $defaultValue = null)
|
||||
{
|
||||
return input()->post($index, $defaultValue);
|
||||
return request()->getInputHandler()->post($index, $defaultValue);
|
||||
}
|
||||
|
||||
public static function get($index, $defaultValue = null)
|
||||
{
|
||||
return request()->getInputHandler()->get($index, $defaultValue);
|
||||
}
|
||||
|
||||
public static function file($index, $defaultValue = null)
|
||||
{
|
||||
return request()->getInputHandler()->file($index, $defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ namespace Khofmann\Models\User;
|
||||
use Exception;
|
||||
use PDO;
|
||||
use Khofmann\Database\Database;
|
||||
use Config\Config;
|
||||
use JsonSerializable;
|
||||
|
||||
class User implements JsonSerializable
|
||||
@ -40,8 +41,7 @@ class User implements JsonSerializable
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetch();
|
||||
|
||||
if (!$data)
|
||||
throw new Exception("No user found");
|
||||
if (!$data) throw new Exception("NotFound");
|
||||
|
||||
return new User($id, $data["benutzer"], $data["status"], $data["email"], $data["image"], $data["isadmin"] === 1);
|
||||
}
|
||||
@ -56,8 +56,7 @@ class User implements JsonSerializable
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetch();
|
||||
|
||||
if (!$data)
|
||||
throw new Exception("No user found");
|
||||
if (!$data) throw new Exception("NotFound");
|
||||
|
||||
return new User($data["id"], $data["benutzer"], $data["status"], $email, $data["image"], $data["isadmin"] === 1);
|
||||
}
|
||||
@ -72,8 +71,7 @@ class User implements JsonSerializable
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetch();
|
||||
|
||||
if (!$data)
|
||||
throw new Exception("No user found");
|
||||
if (!$data) throw new Exception("NotFound");
|
||||
|
||||
return new User($data["id"], $data["benutzer"], $data["status"], $data["email"], $data["image"], $data["isadmin"] === 1);
|
||||
}
|
||||
@ -127,15 +125,49 @@ class User implements JsonSerializable
|
||||
* Members
|
||||
*/
|
||||
|
||||
public function logOut(string $token): bool
|
||||
public function logOut(): bool
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
// Get user data
|
||||
$stmt = $db->prepare("UPDATE egb_benutzer SET token = NULL WHERE id = :ID");
|
||||
$stmt->bindValue(":ID", $this->id);
|
||||
return $stmt->execute();
|
||||
}
|
||||
|
||||
public function update(?string $username, ?string $password, $image = null)
|
||||
{
|
||||
$db = Database::getInstance();
|
||||
|
||||
$error = false;
|
||||
if (!empty($username)) {
|
||||
$stmt = $db->prepare("UPDATE egb_benutzer SET benutzer = :USR WHERE id = :ID");
|
||||
$stmt->bindValue(":USR", $username);
|
||||
$stmt->bindValue(":ID", $this->id);
|
||||
$error = !$stmt->execute();
|
||||
}
|
||||
if ($error) throw new Exception("FailedUsername");
|
||||
|
||||
if (!empty($password)) {
|
||||
$stmt = $db->prepare("UPDATE egb_benutzer SET passwort = :PAS WHERE id = :ID");
|
||||
$stmt->bindValue(":PAS", password_hash($password, PASSWORD_DEFAULT));
|
||||
$stmt->bindValue(":ID", $this->id);
|
||||
$error = !$stmt->execute();
|
||||
}
|
||||
if ($error) throw new Exception("FailedPassword");
|
||||
|
||||
if (!empty($image)) {
|
||||
$destinationFilename = sprintf('%s.%s', uniqid(), $image->getExtension());
|
||||
$image->move(Config::getBaseFSPath() . "uploads/profilbilder/$destinationFilename");
|
||||
|
||||
$stmt = $db->prepare("UPDATE egb_benutzer SET image = :IMG WHERE id = :ID");
|
||||
$stmt->bindValue(":IMG", $destinationFilename);
|
||||
$stmt->bindValue(":ID", $this->id);
|
||||
$error = !$stmt->execute();
|
||||
}
|
||||
if ($error) throw new Exception("FailedImage");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Getters
|
||||
*/
|
||||
@ -160,7 +192,7 @@ class User implements JsonSerializable
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function getImage(): string
|
||||
public function getImage(): ?string
|
||||
{
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
@ -39,6 +39,11 @@ class Config
|
||||
return Config::getInstance()->app["basePath"];
|
||||
}
|
||||
|
||||
public static function getBaseFSPath()
|
||||
{
|
||||
return Config::getInstance()->app["baseFSPath"];
|
||||
}
|
||||
|
||||
public static function getDatabase()
|
||||
{
|
||||
return Config::getInstance()->database;
|
||||
|
||||
@ -2,4 +2,5 @@
|
||||
|
||||
return [
|
||||
"basePath" => "phpCourse/exam/",
|
||||
"baseFSPath" => "/home/k/khofmann/public_html/phpCourse/exam/"
|
||||
];
|
||||
|
||||
5
exam/dist/index.html
vendored
Normal file
5
exam/dist/index.html
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<h1>Redirect to React</h1>
|
||||
<form action="/phpCourse/exam/api/user/1" enctype="multipart/form-data" method="POST">
|
||||
<input type="file" name="image" />
|
||||
<input type="submit">Send</input>
|
||||
</form>
|
||||
1
exam/dist/index.php
vendored
1
exam/dist/index.php
vendored
@ -1 +0,0 @@
|
||||
<h1>Redirect to React</h1>
|
||||
@ -3,7 +3,7 @@
|
||||
use Pecee\SimpleRouter\SimpleRouter;
|
||||
use Pecee\Http\Request;
|
||||
// Error handling
|
||||
SimpleRouter::error(function (Request $request, \Exception $exception) {
|
||||
SimpleRouter::error(function (Request $request, Exception $exception) {
|
||||
$code = $exception->getCode();
|
||||
response()->httpCode(is_int($code) ? $code : 500)->json(["message" => $exception->getMessage()]);
|
||||
});
|
||||
@ -17,8 +17,7 @@ SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
|
||||
SimpleRouter::post("/logout", [Api\Logout\Logout::class, "post"]);
|
||||
});
|
||||
// User
|
||||
SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
|
||||
SimpleRouter::get("/user/{id}", function ($userID) {
|
||||
echo "USER ENDP $userID";
|
||||
});
|
||||
});
|
||||
//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"]);
|
||||
//});
|
||||
|
||||
2
exam/uploads/profilbilder/.gitignore
vendored
Normal file
2
exam/uploads/profilbilder/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@ -69,4 +69,4 @@ function csrf_token(): ?string
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user