Image now a file

This commit is contained in:
Kilian committed 2024-07-21 18:28:19 +02:00
1 parent 8d91e805dd
commit b3c5841e36
16 files changed
+345 -35

No files matched your search

+5
View File
@@ -14,6 +14,11 @@ 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
## ##
+8 -1
View File
@@ -9,8 +9,13 @@ class Login
{ {
public function post() 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 { 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); return json_encode($response);
} catch (Exception $err) { } catch (Exception $err) {
switch ($err->getMessage()) { switch ($err->getMessage()) {
@@ -20,6 +25,8 @@ class Login
throw new Exception("User not Found", 404); throw new Exception("User not Found", 404);
case "Invalid": case "Invalid":
throw new Exception("Invalid Username or Password", 401); throw new Exception("Invalid Username or Password", 401);
default:
throw $err;
} }
} }
} }
+1 -1
View File
@@ -9,6 +9,6 @@ class Logout
public function post() public function post()
{ {
$token = request()->getHeader("token"); $token = request()->getHeader("token");
return json_decode(User::getByToken($token)->logOut($token)); return json_decode(User::getByToken($token)->logOut());
} }
} }
+48
View 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;
}
}
}
}
+126 -2
View File
@@ -27,6 +27,15 @@ paths:
examples: examples:
Success: Success:
value: true value: true
400:
description: Missing Fields
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
Missing Fields:
value: { "message": "Missing email" }
401: 401:
description: Invalid credentials description: Invalid credentials
content: content:
@@ -74,6 +83,97 @@ paths:
value: true value: true
tags: tags:
- Login/Logout - 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: externalDocs:
url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/ url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/
@@ -103,6 +203,31 @@ components:
type: string type: string
password: password:
type: string 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: securitySchemes:
BasicAuth: BasicAuth:
type: apiKey type: apiKey
@@ -110,5 +235,4 @@ components:
in: header in: header
tags: tags:
- name: Login/Logout - name: Login/Logout
- name: Users - name: User
- name: Posts
+26 -5
View File
@@ -309,7 +309,8 @@ data-styled.g111[id="sc-eowDPD"]{content:"jcAXWA,"}/*!sc*/
.gsBSOU:focus{box-shadow:inset 0 2px 2px rgba(0, 0, 0, 0.45),0 2px 0 rgba(128, 128, 128, 0.25);}/*!sc*/ .gsBSOU:focus{box-shadow:inset 0 2px 2px rgba(0, 0, 0, 0.45),0 2px 0 rgba(128, 128, 128, 0.25);}/*!sc*/
data-styled.g112[id="sc-iAlELC"]{content:"gsBSOU,"}/*!sc*/ data-styled.g112[id="sc-iAlELC"]{content:"gsBSOU,"}/*!sc*/
.kpMtuJ{font-size:0.929em;line-height:20px;background-color:#186FAF;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/ .kpMtuJ{font-size:0.929em;line-height:20px;background-color:#186FAF;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
data-styled.g113[id="sc-oeqTF"]{content:"kpMtuJ,"}/*!sc*/ .ffmPnn{font-size:0.929em;line-height:20px;background-color:#2F8132;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
data-styled.g113[id="sc-oeqTF"]{content:"kpMtuJ,ffmPnn,"}/*!sc*/
.bFiOkX{position:absolute;width:100%;z-index:100;background:#fafafa;color:#263238;box-sizing:border-box;box-shadow:0 0 6px rgba(0, 0, 0, 0.33);overflow:hidden;border-bottom-left-radius:4px;border-bottom-right-radius:4px;transition:all 0.25s ease;visibility:hidden;transform:translateY(-50%) scaleY(0);}/*!sc*/ .bFiOkX{position:absolute;width:100%;z-index:100;background:#fafafa;color:#263238;box-sizing:border-box;box-shadow:0 0 6px rgba(0, 0, 0, 0.33);overflow:hidden;border-bottom-left-radius:4px;border-bottom-right-radius:4px;transition:all 0.25s ease;visibility:hidden;transform:translateY(-50%) scaleY(0);}/*!sc*/
data-styled.g114[id="sc-ezTrPE"]{content:"bFiOkX,"}/*!sc*/ data-styled.g114[id="sc-ezTrPE"]{content:"bFiOkX,"}/*!sc*/
.hdRKqQ{padding:10px;}/*!sc*/ .hdRKqQ{padding:10px;}/*!sc*/
@@ -363,7 +364,7 @@ data-styled.g137[id="sc-kvXgyf"]{content:"fBvPoH,"}/*!sc*/
<body> <body>
<div id="redoc"><div class="sc-ixtKjU fabhKa redoc-wrap"><div class="sc-dUMaFF ktzGvn menu-content" style="top:0px;height:calc(100vh - 0px)"><div role="search" class="sc-dovzVR dcjLWY"><svg class="sc-kvXgyf fBvPoH search-icon" version="1.1" viewBox="0 0 1000 1000" x="0px" xmlns="http://www.w3.org/2000/svg" y="0px"><path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z"></path></svg><input placeholder="Search..." aria-label="Search" type="text" class="sc-hAkARQ dlxCDf search-input" value=""/></div><div class="sc-dJDBYC bWVgjU scrollbar-container undefined"><ul role="menu" class="sc-iMDhdf hYtPsf"><li tabindex="0" depth="1" data-item-id="tag/LoginLogout" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cwxKjr -depth1"><span width="calc(100% - 38px)" title="Login/Logout" class="sc-eteQWc glMKqQ">Login/Logout</span><svg class="sc-cBYhjr gUrACV" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></label><ul class="sc-iMDhdf fEjWGm"><li tabindex="0" depth="2" data-item-id="tag/LoginLogout/paths/~1login/post" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cmGsIR -depth2"><span type="post" class="sc-exkVDC QUyzu operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-eteQWc glMKqQ">Login</span></label></li><li tabindex="0" depth="2" data-item-id="tag/LoginLogout/paths/~1logout/post" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cmGsIR -depth2"><span type="post" class="sc-exkVDC QUyzu operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-eteQWc glMKqQ">Logout</span></label></li></ul></li><li tabindex="0" depth="1" data-item-id="tag/Users" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cwxKjr -depth1"><span width="calc(100% - 38px)" title="Users" class="sc-eteQWc glMKqQ">Users</span></label></li><li tabindex="0" depth="1" data-item-id="tag/Posts" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cwxKjr -depth1"><span width="calc(100% - 38px)" title="Posts" class="sc-eteQWc glMKqQ">Posts</span></label></li></ul><div class="sc-gkavYR iljewH"><a target="_blank" rel="noopener noreferrer" href="https://redocly.com/redoc/">API docs by Redocly</a></div></div></div><div class="sc-elEJnV kEKeWg"><div class="sc-bQEQyQ jQQbBk"><svg class="" style="transform:translate(2px, -4px) rotate(180deg);transition:transform 0.2s ease" viewBox="0 0 926.23699 573.74994" version="1.1" x="0px" y="0px" width="15" height="15"><g transform="translate(904.92214,-879.1482)"><path d=" <div id="redoc"><div class="sc-ixtKjU fabhKa redoc-wrap"><div class="sc-dUMaFF ktzGvn menu-content" style="top:0px;height:calc(100vh - 0px)"><div role="search" class="sc-dovzVR dcjLWY"><svg class="sc-kvXgyf fBvPoH search-icon" version="1.1" viewBox="0 0 1000 1000" x="0px" xmlns="http://www.w3.org/2000/svg" y="0px"><path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z"></path></svg><input placeholder="Search..." aria-label="Search" type="text" class="sc-hAkARQ dlxCDf search-input" value=""/></div><div class="sc-dJDBYC bWVgjU scrollbar-container undefined"><ul role="menu" class="sc-iMDhdf hYtPsf"><li tabindex="0" depth="1" data-item-id="tag/LoginLogout" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cwxKjr -depth1"><span width="calc(100% - 38px)" title="Login/Logout" class="sc-eteQWc glMKqQ">Login/Logout</span><svg class="sc-cBYhjr gUrACV" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></label><ul class="sc-iMDhdf fEjWGm"><li tabindex="0" depth="2" data-item-id="tag/LoginLogout/paths/~1login/post" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cmGsIR -depth2"><span type="post" class="sc-exkVDC QUyzu operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-eteQWc glMKqQ">Login</span></label></li><li tabindex="0" depth="2" data-item-id="tag/LoginLogout/paths/~1logout/post" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cmGsIR -depth2"><span type="post" class="sc-exkVDC QUyzu operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-eteQWc glMKqQ">Logout</span></label></li></ul></li><li tabindex="0" depth="1" data-item-id="tag/User" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cwxKjr -depth1"><span width="calc(100% - 38px)" title="User" class="sc-eteQWc glMKqQ">User</span><svg class="sc-cBYhjr gUrACV" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></label><ul class="sc-iMDhdf fEjWGm"><li tabindex="0" depth="2" data-item-id="tag/User/paths/~1user{id}/get" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cmGsIR -depth2"><span type="get" class="sc-exkVDC QUyzu operation-type get">get</span><span tabindex="0" width="calc(100% - 38px)" class="sc-eteQWc glMKqQ">Get user</span></label></li><li tabindex="0" depth="2" data-item-id="tag/User/paths/~1user{id}/post" role="menuitem" class="sc-loAbOW btrDvq"><label class="sc-bPZXsP cmGsIR -depth2"><span type="post" class="sc-exkVDC QUyzu operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-eteQWc glMKqQ">Update user</span></label></li></ul></li></ul><div class="sc-gkavYR iljewH"><a target="_blank" rel="noopener noreferrer" href="https://redocly.com/redoc/">API docs by Redocly</a></div></div></div><div class="sc-elEJnV kEKeWg"><div class="sc-bQEQyQ jQQbBk"><svg class="" style="transform:translate(2px, -4px) rotate(180deg);transition:transform 0.2s ease" viewBox="0 0 926.23699 573.74994" version="1.1" x="0px" y="0px" width="15" height="15"><g transform="translate(904.92214,-879.1482)"><path d="
m -673.67664,1221.6502 -231.2455,-231.24803 55.6165, m -673.67664,1221.6502 -231.2455,-231.24803 55.6165,
-55.627 c 30.5891,-30.59485 56.1806,-55.627 56.8701,-55.627 0.6894, -55.627 c 30.5891,-30.59485 56.1806,-55.627 56.8701,-55.627 0.6894,
0 79.8637,78.60862 175.9427,174.68583 l 174.6892,174.6858 174.6892, 0 79.8637,78.60862 175.9427,174.68583 l 174.6892,174.6858 174.6892,
@@ -387,19 +388,39 @@ data-styled.g137[id="sc-kvXgyf"]{content:"fBvPoH,"}/*!sc*/
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"><p>Log in user</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"><p>Log in user</p>
</div></div><h5 class="sc-dkjaqt gwrByh">Request Body schema: <span class="sc-dwYcXH fafqZb">application/json</span><div class="sc-xuUkR sc-hrDJJk sc-kGqRax bJcEcT gLEAmN HCLfY">required</div></h5><div html="" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"></div><table class="sc-dENhDJ ceVHDP"><tbody><tr class=""><td kind="field" title="username" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">username</span><div class="sc-xuUkR sc-hrDJJk bJcEcT gLEAmN">required</div></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr><tr class="last "><td kind="field" title="password" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">password</span><div class="sc-xuUkR sc-hrDJJk bJcEcT gLEAmN">required</div></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr></tbody></table><div><h3 class="sc-eiLgtK dbBFCU">Responses</h3><div><button class="sc-giOWAb gcYfHW"><svg class="sc-cBYhjr fqtTpb" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">200<!-- --> </strong><div html="&lt;p&gt;Success&lt;/p&gt; </div></div><h5 class="sc-dkjaqt gwrByh">Request Body schema: <span class="sc-dwYcXH fafqZb">application/json</span><div class="sc-xuUkR sc-hrDJJk sc-kGqRax bJcEcT gLEAmN HCLfY">required</div></h5><div html="" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"></div><table class="sc-dENhDJ ceVHDP"><tbody><tr class=""><td kind="field" title="username" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">username</span><div class="sc-xuUkR sc-hrDJJk bJcEcT gLEAmN">required</div></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr><tr class="last "><td kind="field" title="password" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">password</span><div class="sc-xuUkR sc-hrDJJk bJcEcT gLEAmN">required</div></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr></tbody></table><div><h3 class="sc-eiLgtK dbBFCU">Responses</h3><div><button class="sc-giOWAb gcYfHW"><svg class="sc-cBYhjr fqtTpb" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">200<!-- --> </strong><div html="&lt;p&gt;Success&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Success</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Success</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">400<!-- --> </strong><div html="&lt;p&gt;Missing Fields&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Missing Fields</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">401<!-- --> </strong><div html="&lt;p&gt;Invalid credentials&lt;/p&gt; </div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">401<!-- --> </strong><div html="&lt;p&gt;Invalid credentials&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Invalid credentials</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Invalid credentials</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">404<!-- --> </strong><div html="&lt;p&gt;User not Found&lt;/p&gt; </div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">404<!-- --> </strong><div html="&lt;p&gt;User not Found&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>User not Found</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>User not Found</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">500<!-- --> </strong><div html="&lt;p&gt;Failed&lt;/p&gt; </div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">500<!-- --> </strong><div html="&lt;p&gt;Failed&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Failed</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Failed</p>
</div></button></div></div></div><div class="sc-iKTcqh sc-gnpbhQ fTxZsC drGLlX"><div class="sc-dKsqdn dCbPd"><button class="sc-iAlELC gsBSOU"><span type="post" class="sc-oeqTF kpMtuJ http-verb post">post</span><span class="sc-eowDPD jcAXWA">/login</span><svg class="sc-cBYhjr iMxoRf" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-ezTrPE bFiOkX"><div class="sc-drnuxz hdRKqQ"><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div><div tabindex="0" role="button"><div class="sc-hDcvty jpmGrk"><span>https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api</span>/login</div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Request samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="react-tabs__tab react-tabs__tab--selected" role="tab" id="tab:R99cq:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R99cq:0" tabindex="0" data-rttab="true">Payload</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R99cq:0" aria-labelledby="tab:R99cq:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"username"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"password"</span>: <span class="token string">&quot;string&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Response samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab:R9pcq:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R9pcq:0" tabindex="0" data-rttab="true">200</li><li class="tab-error" role="tab" id="tab:R9pcq:1" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:1" data-rttab="true">401</li><li class="tab-error" role="tab" id="tab:R9pcq:2" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:2" data-rttab="true">404</li><li class="tab-error" role="tab" id="tab:R9pcq:3" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:3" data-rttab="true">500</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R9pcq:0" aria-labelledby="tab:R9pcq:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><span class="token boolean">true</span></code></div></div></div></div></div></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:1" aria-labelledby="tab:R9pcq:1"></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:2" aria-labelledby="tab:R9pcq:2"></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:3" aria-labelledby="tab:R9pcq:3"></div></div></div></div></div></div><div id="tag/LoginLogout/paths/~1logout/post" data-section-id="tag/LoginLogout/paths/~1logout/post" class="sc-dsLQwm kcRA-dj"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/LoginLogout/paths/~1logout/post" aria-label="tag/LoginLogout/paths/~1logout/post"></a>Logout<!-- --> </h2><div class="sc-fpJhiv cQxXyG"><div html="&lt;p&gt;Log out User&lt;/p&gt; </div></button></div></div></div><div class="sc-iKTcqh sc-gnpbhQ fTxZsC drGLlX"><div class="sc-dKsqdn dCbPd"><button class="sc-iAlELC gsBSOU"><span type="post" class="sc-oeqTF kpMtuJ http-verb post">post</span><span class="sc-eowDPD jcAXWA">/login</span><svg class="sc-cBYhjr iMxoRf" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-ezTrPE bFiOkX"><div class="sc-drnuxz hdRKqQ"><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div><div tabindex="0" role="button"><div class="sc-hDcvty jpmGrk"><span>https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api</span>/login</div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Request samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="react-tabs__tab react-tabs__tab--selected" role="tab" id="tab:R99cq:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R99cq:0" tabindex="0" data-rttab="true">Payload</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R99cq:0" aria-labelledby="tab:R99cq:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"username"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"password"</span>: <span class="token string">&quot;string&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Response samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab:R9pcq:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R9pcq:0" tabindex="0" data-rttab="true">200</li><li class="tab-error" role="tab" id="tab:R9pcq:1" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:1" data-rttab="true">400</li><li class="tab-error" role="tab" id="tab:R9pcq:2" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:2" data-rttab="true">401</li><li class="tab-error" role="tab" id="tab:R9pcq:3" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:3" data-rttab="true">404</li><li class="tab-error" role="tab" id="tab:R9pcq:4" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pcq:4" data-rttab="true">500</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R9pcq:0" aria-labelledby="tab:R9pcq:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><span class="token boolean">true</span></code></div></div></div></div></div></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:1" aria-labelledby="tab:R9pcq:1"></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:2" aria-labelledby="tab:R9pcq:2"></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:3" aria-labelledby="tab:R9pcq:3"></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pcq:4" aria-labelledby="tab:R9pcq:4"></div></div></div></div></div></div><div id="tag/LoginLogout/paths/~1logout/post" data-section-id="tag/LoginLogout/paths/~1logout/post" class="sc-dsLQwm kcRA-dj"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/LoginLogout/paths/~1logout/post" aria-label="tag/LoginLogout/paths/~1logout/post"></a>Logout<!-- --> </h2><div class="sc-fpJhiv cQxXyG"><div html="&lt;p&gt;Log out User&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"><p>Log out User</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"><p>Log out User</p>
</div></div><div class="sc-hWiVxH cCfxdS"><div class="sc-jHofgq febKCY"><h5 class="sc-dkjaqt sc-jRHPII gwrByh eGMvsx">Authorizations:</h5><svg class="sc-cBYhjr dJanPw" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></div><div class="sc-iRFtIJ juVMxG"><span class="sc-iHlJgr lkBZak"><span class="sc-blcnQh fyveIh"><i>BasicAuth</i></span></span></div></div><div><h3 class="sc-eiLgtK dbBFCU">Responses</h3><div><button class="sc-giOWAb gcYfHW"><svg class="sc-cBYhjr fqtTpb" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">200<!-- --> </strong><div html="&lt;p&gt;Success&lt;/p&gt; </div></div><div class="sc-hWiVxH cCfxdS"><div class="sc-jHofgq febKCY"><h5 class="sc-dkjaqt sc-jRHPII gwrByh eGMvsx">Authorizations:</h5><svg class="sc-cBYhjr dJanPw" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></div><div class="sc-iRFtIJ juVMxG"><span class="sc-iHlJgr lkBZak"><span class="sc-blcnQh fyveIh"><i>BasicAuth</i></span></span></div></div><div><h3 class="sc-eiLgtK dbBFCU">Responses</h3><div><button class="sc-giOWAb gcYfHW"><svg class="sc-cBYhjr fqtTpb" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">200<!-- --> </strong><div html="&lt;p&gt;Success&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Success</p> " class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Success</p>
</div></button></div></div></div><div class="sc-iKTcqh sc-gnpbhQ fTxZsC drGLlX"><div class="sc-dKsqdn dCbPd"><button class="sc-iAlELC gsBSOU"><span type="post" class="sc-oeqTF kpMtuJ http-verb post">post</span><span class="sc-eowDPD jcAXWA">/logout</span><svg class="sc-cBYhjr iMxoRf" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-ezTrPE bFiOkX"><div class="sc-drnuxz hdRKqQ"><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div><div tabindex="0" role="button"><div class="sc-hDcvty jpmGrk"><span>https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api</span>/logout</div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Response samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab:R9pkq:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R9pkq:0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R9pkq:0" aria-labelledby="tab:R9pkq:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><span class="token boolean">true</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="tag/Users" data-section-id="tag/Users" class="sc-dsLQwm diwyyM"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/Users" aria-label="tag/Users"></a>Users</h2></div></div></div><div id="tag/Posts" data-section-id="tag/Posts" class="sc-dsLQwm diwyyM"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/Posts" aria-label="tag/Posts"></a>Posts</h2></div></div></div></div><div class="sc-epzHnm bWkBKa"></div></div></div> </div></button></div></div></div><div class="sc-iKTcqh sc-gnpbhQ fTxZsC drGLlX"><div class="sc-dKsqdn dCbPd"><button class="sc-iAlELC gsBSOU"><span type="post" class="sc-oeqTF kpMtuJ http-verb post">post</span><span class="sc-eowDPD jcAXWA">/logout</span><svg class="sc-cBYhjr iMxoRf" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-ezTrPE bFiOkX"><div class="sc-drnuxz hdRKqQ"><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div><div tabindex="0" role="button"><div class="sc-hDcvty jpmGrk"><span>https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api</span>/logout</div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Response samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab:R9pkq:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R9pkq:0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R9pkq:0" aria-labelledby="tab:R9pkq:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><span class="token boolean">true</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="tag/User" data-section-id="tag/User" class="sc-dsLQwm diwyyM"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/User" aria-label="tag/User"></a>User</h2></div></div></div><div id="tag/User/paths/~1user{id}/get" data-section-id="tag/User/paths/~1user{id}/get" class="sc-dsLQwm kcRA-dj"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/User/paths/~1user{id}/get" aria-label="tag/User/paths/~1user{id}/get"></a>Get user<!-- --> </h2><div class="sc-fpJhiv cQxXyG"><div html="&lt;p&gt;Get user by ID&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"><p>Get user by ID</p>
</div></div><div class="sc-hWiVxH cCfxdS"><div class="sc-jHofgq febKCY"><h5 class="sc-dkjaqt sc-jRHPII gwrByh eGMvsx">Authorizations:</h5><svg class="sc-cBYhjr dJanPw" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></div><div class="sc-iRFtIJ juVMxG"><span class="sc-iHlJgr lkBZak"><span class="sc-blcnQh fyveIh"><i>BasicAuth</i></span></span></div></div><div><h5 class="sc-dkjaqt gwrByh">path<!-- --> Parameters</h5><table class="sc-dENhDJ ceVHDP"><tbody><tr class="last "><td kind="field" title="id" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">id</span><div class="sc-xuUkR sc-hrDJJk bJcEcT gLEAmN">required</div></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">integer</span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc"> <!-- -->&lt;<!-- -->int14<!-- -->&gt;<!-- --> </span></div> <div><div html="&lt;p&gt;User ID&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"><p>User ID</p>
</div></div></div></td></tr></tbody></table></div><div><h3 class="sc-eiLgtK dbBFCU">Responses</h3><div><button class="sc-giOWAb gcYfHW"><svg class="sc-cBYhjr fqtTpb" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">200<!-- --> </strong><div html="&lt;p&gt;Success&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Success</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">404<!-- --> </strong><div html="&lt;p&gt;User not Found&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>User not Found</p>
</div></button></div></div></div><div class="sc-iKTcqh sc-gnpbhQ fTxZsC drGLlX"><div class="sc-dKsqdn dCbPd"><button class="sc-iAlELC gsBSOU"><span type="get" class="sc-oeqTF ffmPnn http-verb get">get</span><span class="sc-eowDPD jcAXWA">/user{id}</span><svg class="sc-cBYhjr iMxoRf" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-ezTrPE bFiOkX"><div class="sc-drnuxz hdRKqQ"><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div><div tabindex="0" role="button"><div class="sc-hDcvty jpmGrk"><span>https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api</span>/user{id}</div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Response samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab:R9pda:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R9pda:0" tabindex="0" data-rttab="true">200</li><li class="tab-error" role="tab" id="tab:R9pda:1" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pda:1" data-rttab="true">404</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R9pda:0" aria-labelledby="tab:R9pda:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"id"</span>: <span class="token number">1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"username"</span>: <span class="token string">&quot;Admin&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"status"</span>: <span class="token number">1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"email"</span>: <span class="token string">&quot;marvin@zedat.fu-berlin.de&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"image"</span>: <span class="token string">&quot;profilbilder\\/admin.svg&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"isAdmin"</span>: <span class="token boolean">true</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pda:1" aria-labelledby="tab:R9pda:1"></div></div></div></div></div></div><div id="tag/User/paths/~1user{id}/post" data-section-id="tag/User/paths/~1user{id}/post" class="sc-dsLQwm kcRA-dj"><div class="sc-la-DxNn dSIRVR"><div class="sc-fQpRED htdgPt"><h2 class="sc-knesRu cbpGTP"><a class="sc-jCbFiK hSvuOo" href="#tag/User/paths/~1user{id}/post" aria-label="tag/User/paths/~1user{id}/post"></a>Update user<!-- --> </h2><div class="sc-fpJhiv cQxXyG"><div html="&lt;p&gt;Update user with ID. Fields are updated in order username,password,image. If one fails, subsequent are not updated&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"><p>Update user with ID. Fields are updated in order username,password,image. If one fails, subsequent are not updated</p>
</div></div><div class="sc-hWiVxH cCfxdS"><div class="sc-jHofgq febKCY"><h5 class="sc-dkjaqt sc-jRHPII gwrByh eGMvsx">Authorizations:</h5><svg class="sc-cBYhjr dJanPw" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></div><div class="sc-iRFtIJ juVMxG"><span class="sc-iHlJgr lkBZak"><span class="sc-blcnQh fyveIh"><i>BasicAuth</i></span></span></div></div><div><h5 class="sc-dkjaqt gwrByh">path<!-- --> Parameters</h5><table class="sc-dENhDJ ceVHDP"><tbody><tr class="last "><td kind="field" title="id" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">id</span><div class="sc-xuUkR sc-hrDJJk bJcEcT gLEAmN">required</div></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">integer</span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc"> <!-- -->&lt;<!-- -->int14<!-- -->&gt;<!-- --> </span></div> <div><div html="&lt;p&gt;User ID&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"><p>User ID</p>
</div></div></div></td></tr></tbody></table></div><h5 class="sc-dkjaqt gwrByh">Request Body schema: <span class="sc-dwYcXH fafqZb">application/json</span></h5><div html="" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD"></div><table class="sc-dENhDJ ceVHDP"><tbody><tr class=""><td kind="field" title="username" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">username</span></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr><tr class=""><td kind="field" title="password" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">password</span></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr><tr class="last "><td kind="field" title="image" class="sc-tOkKi sc-epPVmt gbdrVc bUksBx"><span class="sc-hfvVTD hTjFRU"></span><span class="property-name">image</span></td><td class="sc-fpSrms exGrJC"><div><div><span class="sc-xuUkR sc-cvzDha bJcEcT kDPMlG"></span><span class="sc-xuUkR sc-gKROGD bJcEcT etUsjc">string</span></div> <div><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div></div></div></td></tr></tbody></table><div><h3 class="sc-eiLgtK dbBFCU">Responses</h3><div><button class="sc-giOWAb gcYfHW"><svg class="sc-cBYhjr fqtTpb" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">200<!-- --> </strong><div html="&lt;p&gt;Success&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Success</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">404<!-- --> </strong><div html="&lt;p&gt;User not Found&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>User not Found</p>
</div></button></div><div><button class="sc-giOWAb gbPhWg"><svg class="sc-cBYhjr ezFOZv" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-catHVh gXPvFO">500<!-- --> </strong><div html="&lt;p&gt;Update failed&lt;/p&gt;
" class="sc-euGpHm sc-exayXG fwfkcU kqJXdD sc-dHrNzZ dRdjww"><p>Update failed</p>
</div></button></div></div></div><div class="sc-iKTcqh sc-gnpbhQ fTxZsC drGLlX"><div class="sc-dKsqdn dCbPd"><button class="sc-iAlELC gsBSOU"><span type="post" class="sc-oeqTF kpMtuJ http-verb post">post</span><span class="sc-eowDPD jcAXWA">/user{id}</span><svg class="sc-cBYhjr iMxoRf" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-ezTrPE bFiOkX"><div class="sc-drnuxz hdRKqQ"><div html="" class="sc-euGpHm sc-exayXG fwfkcU jYGAQp"></div><div tabindex="0" role="button"><div class="sc-hDcvty jpmGrk"><span>https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api</span>/user{id}</div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Request samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="react-tabs__tab react-tabs__tab--selected" role="tab" id="tab:R99la:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R99la:0" tabindex="0" data-rttab="true">Payload</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R99la:0" aria-labelledby="tab:R99la:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"username"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"password"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"image"</span>: <span class="token string">&quot;string&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div><div><h3 class="sc-kkmypM jKNCPF"> <!-- -->Response samples<!-- --> </h3><div class="sc-bSlUec jxQggo" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab:R9pla:0" aria-selected="true" aria-disabled="false" aria-controls="panel:R9pla:0" tabindex="0" data-rttab="true">200</li><li class="tab-error" role="tab" id="tab:R9pla:1" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pla:1" data-rttab="true">404</li><li class="tab-error" role="tab" id="tab:R9pla:2" aria-selected="false" aria-disabled="false" aria-controls="panel:R9pla:2" data-rttab="true">500</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel:R9pla:0" aria-labelledby="tab:R9pla:0"><div><div class="sc-WChnI iLXIA-d"><span class="sc-foMnoT dmNpjh">Content type</span><div class="sc-ZubPq KmnOC">application/json</div></div><div class="sc-AmOMz gDrQpr"><div class="sc-eTdEpr dgzSkD"><div class="sc-pFPEP bMXXJy"><button><div class="sc-eHujzY ecCAmX">Copy</div></button></div><div class="sc-euGpHm fwfkcU sc-fTgapq bDqsIm"><div class="redoc-json"><code><span class="token boolean">true</span></code></div></div></div></div></div></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pla:1" aria-labelledby="tab:R9pla:1"></div><div class="react-tabs__tab-panel" role="tabpanel" id="panel:R9pla:2" aria-labelledby="tab:R9pla:2"></div></div></div></div></div></div></div><div class="sc-epzHnm bWkBKa"></div></div></div>
<script> <script>
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.0","info":{"title":"PHP Course Exam","version":"1.0.0","contact":{"name":"Kilian Kurt Hofmann","email":"khofmann@zedat.fu-berlin.de"},"description":"PHP Course (ABV FU Berlin) 2024 Exam"},"paths":{"/login":{"post":{"summary":"Login","description":"Log in user","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BooleanResponse"},"examples":{"Success":{"value":true}}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"Invalid Username or Password":{"value":{"message":"Invalid Username or Password"}}}}}},"404":{"description":"User not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"User not Found":{"value":{"message":"User not Found"}}}}}},"500":{"description":"Failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"Failed":{"value":{"message":"Login failed"}}}}}}},"tags":["Login/Logout"]}},"/logout":{"post":{"summary":"Logout","description":"Log out User","security":[{"BasicAuth":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BooleanResponse"},"examples":{"Success":{"value":true}}}}}},"tags":["Login/Logout"]}}},"externalDocs":{"url":"https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/"},"security":[],"servers":[{"url":"https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/","description":"","variables":{}}],"components":{"links":{},"callbacks":{},"schemas":{"BooleanResponse":{"type":"boolean"},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"}}},"LoginRequest":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string"},"password":{"type":"string"}}}},"securitySchemes":{"BasicAuth":{"type":"apiKey","name":"token","in":"header"}}},"tags":[{"name":"Login/Logout"},{"name":"Users"},{"name":"Posts"}]}},"searchIndex":{"store":["tag/LoginLogout","tag/LoginLogout/paths/~1login/post","tag/LoginLogout/paths/~1logout/post","tag/Users","tag/Posts"],"index":{"version":"2.3.9","fields":["title","description"],"fieldVectors":[["title/0",[0,1.386]],["description/0",[]],["title/1",[1,0.875]],["description/1",[1,0.597,2,0.597,3,0.367]],["title/2",[4,0.875]],["description/2",[2,0.497,3,0.306,4,0.497,5,0.788]],["title/3",[3,0.539]],["description/3",[]],["title/4",[6,1.386]],["description/4",[]]],"invertedIndex":[["log",{"_index":2,"title":{},"description":{"1":{},"2":{}}}],["login",{"_index":1,"title":{"1":{}},"description":{"1":{}}}],["login/logout",{"_index":0,"title":{"0":{}},"description":{}}],["logout",{"_index":4,"title":{"2":{}},"description":{"2":{}}}],["out",{"_index":5,"title":{},"description":{"2":{}}}],["post",{"_index":6,"title":{"4":{}},"description":{}}],["user",{"_index":3,"title":{"3":{}},"description":{"1":{},"2":{}}}]],"pipeline":[]}},"options":{}}; const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.0","info":{"title":"PHP Course Exam","version":"1.0.0","contact":{"name":"Kilian Kurt Hofmann","email":"khofmann@zedat.fu-berlin.de"},"description":"PHP Course (ABV FU Berlin) 2024 Exam"},"paths":{"/login":{"post":{"summary":"Login","description":"Log in user","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BooleanResponse"},"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":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"Invalid Username or Password":{"value":{"message":"Invalid Username or Password"}}}}}},"404":{"description":"User not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"User not Found":{"value":{"message":"User not Found"}}}}}},"500":{"description":"Failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"Failed":{"value":{"message":"Login failed"}}}}}}},"tags":["Login/Logout"]}},"/logout":{"post":{"summary":"Logout","description":"Log out User","security":[{"BasicAuth":[]}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BooleanResponse"},"examples":{"Success":{"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/"},"security":[],"servers":[{"url":"https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/","description":"","variables":{}}],"components":{"links":{},"callbacks":{},"schemas":{"BooleanResponse":{"type":"boolean"},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"}}},"LoginRequest":{"type":"object","required":["username","password"],"properties":{"username":{"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","name":"token","in":"header"}}},"tags":[{"name":"Login/Logout"},{"name":"User"}]}},"searchIndex":{"store":["tag/LoginLogout","tag/LoginLogout/paths/~1login/post","tag/LoginLogout/paths/~1logout/post","tag/User","tag/User/paths/~1user{id}/get","tag/User/paths/~1user{id}/post"],"index":{"version":"2.3.9","fields":["title","description"],"fieldVectors":[["title/0",[0,1.636]],["description/0",[]],["title/1",[1,1.094]],["description/1",[1,1.112,2,1.112,3,0.07]],["title/2",[4,1.094]],["description/2",[2,0.993,3,0.062,4,0.993,5,1.485]],["title/3",[3,0Line truncated
var container = document.getElementById('redoc'); var container = document.getElementById('redoc');
Redoc.hydrate(__redoc_state, container); Redoc.hydrate(__redoc_state, container);
+30
View 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
View 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"]);
}
}
}
+11 -10
View File
@@ -4,17 +4,18 @@ namespace Khofmann\Input;
class 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) 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);
} }
} }
+41 -9
View File
@@ -5,6 +5,7 @@ namespace Khofmann\Models\User;
use Exception; use Exception;
use PDO; use PDO;
use Khofmann\Database\Database; use Khofmann\Database\Database;
use Config\Config;
use JsonSerializable; use JsonSerializable;
class User implements JsonSerializable class User implements JsonSerializable
@@ -40,8 +41,7 @@ class User implements JsonSerializable
$stmt->execute(); $stmt->execute();
$data = $stmt->fetch(); $data = $stmt->fetch();
if (!$data) if (!$data) throw new Exception("NotFound");
throw new Exception("No user found");
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["image"], $data["isadmin"] === 1);
} }
@@ -56,8 +56,7 @@ class User implements JsonSerializable
$stmt->execute(); $stmt->execute();
$data = $stmt->fetch(); $data = $stmt->fetch();
if (!$data) if (!$data) throw new Exception("NotFound");
throw new Exception("No user found");
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["image"], $data["isadmin"] === 1);
} }
@@ -72,8 +71,7 @@ class User implements JsonSerializable
$stmt->execute(); $stmt->execute();
$data = $stmt->fetch(); $data = $stmt->fetch();
if (!$data) if (!$data) throw new Exception("NotFound");
throw new Exception("No user found");
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["image"], $data["isadmin"] === 1);
} }
@@ -127,15 +125,49 @@ class User implements JsonSerializable
* Members * Members
*/ */
public function logOut(string $token): bool public function logOut(): bool
{ {
$db = Database::getInstance(); $db = Database::getInstance();
// Get user data
$stmt = $db->prepare("UPDATE egb_benutzer SET token = NULL WHERE id = :ID"); $stmt = $db->prepare("UPDATE egb_benutzer SET token = NULL WHERE id = :ID");
$stmt->bindValue(":ID", $this->id); $stmt->bindValue(":ID", $this->id);
return $stmt->execute(); 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 * Getters
*/ */
@@ -160,7 +192,7 @@ class User implements JsonSerializable
return $this->email; return $this->email;
} }
public function getImage(): string public function getImage(): ?string
{ {
return $this->image; return $this->image;
} }
+5
View File
@@ -39,6 +39,11 @@ class Config
return Config::getInstance()->app["basePath"]; return Config::getInstance()->app["basePath"];
} }
public static function getBaseFSPath()
{
return Config::getInstance()->app["baseFSPath"];
}
public static function getDatabase() public static function getDatabase()
{ {
return Config::getInstance()->database; return Config::getInstance()->database;
+1
View File
@@ -2,4 +2,5 @@
return [ return [
"basePath" => "phpCourse/exam/", "basePath" => "phpCourse/exam/",
"baseFSPath" => "/home/k/khofmann/public_html/phpCourse/exam/"
]; ];
+5
View 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
View File
@@ -1 +0,0 @@
<h1>Redirect to React</h1>
+5 -6
View File
@@ -3,7 +3,7 @@
use Pecee\SimpleRouter\SimpleRouter; use Pecee\SimpleRouter\SimpleRouter;
use Pecee\Http\Request; use Pecee\Http\Request;
// Error handling // Error handling
SimpleRouter::error(function (Request $request, \Exception $exception) { SimpleRouter::error(function (Request $request, Exception $exception) {
$code = $exception->getCode(); $code = $exception->getCode();
response()->httpCode(is_int($code) ? $code : 500)->json(["message" => $exception->getMessage()]); 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"]); SimpleRouter::post("/logout", [Api\Logout\Logout::class, "post"]);
}); });
// User // User
SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () { //SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
SimpleRouter::get("/user/{id}", function ($userID) { SimpleRouter::get("/user/{id}", [Api\User\User::class, "get"]);
echo "USER ENDP $userID"; SimpleRouter::post("/user/{id}", [Api\User\User::class, "post"]);
}); //});
});
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore