diff --git a/exam/api/Logout/Logout.php b/exam/api/Logout/Logout.php
index 0a483ef..8d087f2 100644
--- a/exam/api/Logout/Logout.php
+++ b/exam/api/Logout/Logout.php
@@ -11,7 +11,7 @@ class Logout extends Api
{
public function post(): void
{
- $token = Request::header("token");
+ $token = Request::token();
Response::json(User::getByToken($token)->logOut());
}
diff --git a/exam/api/Post/Post.php b/exam/api/Post/Post.php
new file mode 100644
index 0000000..dc12819
--- /dev/null
+++ b/exam/api/Post/Post.php
@@ -0,0 +1,67 @@
+getMessage()) {
+ default:
+ throw $err;
+ }
+ }
+ }
+
+ public function patch($id): void
+ {
+ $content = Input::patch("content");
+
+ $self = User::getByToken(Request::token());
+ $post = MPost::getByID($id);
+
+ if (!$self->getIsAdmin() && $post->getUser()->getID() !== $self->getID()) throw new Exception("Not Authorized", 401);
+
+ try {
+ Response::json(MPost::getByID($id)->update($content));
+ } catch (Exception $err) {
+ switch ($err->getMessage()) {
+ case "NotFound":
+ throw new Exception("Post not found", 404);
+ case "FailedContent":
+ throw new Exception("Failed to update content", 500);
+ default:
+ throw $err;
+ }
+ }
+ }
+
+ public function delete($id): void
+ {
+ try {
+ Response::json(MPost::getByID($id)->delete());
+ } catch (Exception $err) {
+ switch ($err->getMessage()) {
+ case "NotFound":
+ throw new Exception("Post not found", 404);
+ default:
+ throw $err;
+ }
+ }
+ }
+}
diff --git a/exam/api/Posts/Posts.php b/exam/api/Posts/Posts.php
index 1513594..d9a701e 100644
--- a/exam/api/Posts/Posts.php
+++ b/exam/api/Posts/Posts.php
@@ -14,7 +14,8 @@ class Posts extends Api
{
$page = max(0, intval(Input::get("p", 0)));
$limit = constrain(0, 30, intval(Input::get("l", 10)));
- $authed = Request::header("token") !== null;
+ $authed = Request::token() !== null;
+
Response::json(Post::list($page, $limit, $authed));
}
}
diff --git a/exam/api/User/User.php b/exam/api/User/User.php
index 88c5b61..cd274b9 100644
--- a/exam/api/User/User.php
+++ b/exam/api/User/User.php
@@ -51,7 +51,7 @@ class User extends Api
public function patchSelf(): void
{
- $token = Request::header("token");
+ $token = Request::token();
$username = Input::patch("username");
$password = Input::patch("password");
$image = Input::file("image");
diff --git a/exam/api/docs/api.yaml b/exam/api/docs/api.yaml
index 005fb49..0098514 100644
--- a/exam/api/docs/api.yaml
+++ b/exam/api/docs/api.yaml
@@ -23,10 +23,7 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/BooleanResponse"
- examples:
- Success:
- value: true
+ $ref: "#/components/schemas/LoginResponse"
400:
description: Missing fields.
content:
@@ -99,10 +96,7 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/BooleanResponse"
- examples:
- Success:
- value: true
+ $ref: "#/components/schemas/UserResponse"
400:
description: Missing fields or duplicate
content:
@@ -187,48 +181,9 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/UserListResponse"
- examples:
- Success:
- value:
- {
- "pages": 1,
- "data":
- [
- {
- "id": 1,
- "username": "Admin",
- "status": 1,
- "email": "marvin@zedat.fu-berlin.de",
- "image": "669d41fbdb56b.png",
- "isAdmin": true,
- "memberSince":
- {
- "date": "2024-07-22 14:02:49.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
- },
- "postCount": 3,
- },
- {
- "id": 2,
- "username": "Max",
- "status": 1,
- "email": "max@moritz.net",
- "image": "profilbilder/max.svg",
- "isAdmin": false,
- "memberSince":
- {
- "date": "2024-07-22 03:07:41.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
- },
- "postCount": 2,
- },
- ],
- }
tags:
- User
- /user{id}:
+ /user/{id}:
get:
summary: Get user
description: Get user by ID.
@@ -249,24 +204,6 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/UserResponse"
- examples:
- Success:
- value:
- {
- "id": 1,
- "username": "Admin",
- "status": 1,
- "email": "marvin@zedat.fu-berlin.de",
- "image": "669d41fbdb56b.png",
- "isAdmin": true,
- "memberSince":
- {
- "date": "2024-07-22 14:02:49.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
- },
- "postCount": 3,
- }
404:
description: User not found.
content:
@@ -285,6 +222,7 @@ paths:
Use special ID self to update logged in user.
Requires logged in user to have admin permissions for any ID other than self.
security:
+ - BasicAuth: []
- BasicAuth: [isAdmin]
parameters:
- name: id
@@ -305,10 +243,7 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/BooleanResponse"
- examples:
- Success:
- value: true
+ $ref: "#/components/schemas/UserResponse"
404:
description: User not found.
content:
@@ -325,7 +260,7 @@ paths:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
- User not found:
+ Failed username:
value: { "message": "Failed to update username" }
tags:
- User
@@ -348,10 +283,7 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/BooleanResponse"
- examples:
- Success:
- value: true
+ $ref: "#/components/schemas/UserResponse"
404:
description: User not found.
content:
@@ -397,29 +329,18 @@ paths:
Not authenticated:
value:
{
- "pages": 1,
+ "pages": 0,
"data":
[
{
- "id": 1,
- "user": { "username": "Admin" },
- "content": "Hey,\r\nGästebucher sind cool…\r\nDas Gästebuch ist freigegeben.\r\nIch hoffe auf viele Beiträge!",
+ "id": 0,
+ "user": { "username": "string" },
+ "content": "string",
"postedAt":
{
- "date": "2020-03-03 09:03:00.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
- },
- },
- {
- "id": 2,
- "user": { "username": "Max" },
- "content": "Bin über Google auf deine Seite gestoßen, danke für das geniale Gästebuch. Werde in Zukunft des Öftern vorbeischaun…\r\n\r\nLiebe Grüsse, Max",
- "postedAt":
- {
- "date": "2020-03-04 12:26:40.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
+ "date": "2019-08-24T14:15:22Z",
+ "timezone_type": 0,
+ "timezone": "string",
},
},
],
@@ -434,58 +355,140 @@ paths:
"id": 1,
"user":
{
- "id": 1,
- "username": "Admin",
- "status": 1,
- "email": "marvin@zedat.fu-berlin.de",
- "image": "669d41fbdb56b.png",
+ "id": 0,
+ "username": "string",
+ "status": 0,
+ "email": "string",
+ "image": "string",
"isAdmin": true,
"memberSince":
{
- "date": "2024-07-22 14:02:49.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
+ "date": "2019-08-24T14:15:22Z",
+ "timezone_type": 0,
+ "timezone": "string",
},
- "postCount": 3,
+ "postCount": 0,
},
- "content": "Hey,\r\nGästebucher sind cool…\r\nDas Gästebuch ist freigegeben.\r\nIch hoffe auf viele Beiträge!",
+ "content": "string",
"postedAt":
{
- "date": "2020-03-03 09:03:00.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
- },
- },
- {
- "id": 2,
- "user":
- {
- "id": 2,
- "username": "Max",
- "status": 1,
- "email": "max@moritz.net",
- "image": "profilbilder/max.svg",
- "isAdmin": false,
- "memberSince":
- {
- "date": "2024-07-22 03:07:41.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
- },
- "postCount": 2,
- },
- "content": "Bin über Google auf deine Seite gestoßen, danke für das geniale Gästebuch. Werde in Zukunft des Öftern vorbeischaun…\r\n\r\nLiebe Grüsse, Max",
- "postedAt":
- {
- "date": "2020-03-04 12:26:40.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin",
+ "date": "2019-08-24T14:15:22Z",
+ "timezone_type": 0,
+ "timezone": "string",
},
},
],
}
tags:
- Post
+ post:
+ summary: New post
+ description: Create a new post.
+ security:
+ - BasicAuth: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/PostCreateRequest"
+ responses:
+ 200:
+ description: Success.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/PostResponse"
+ 400:
+ description: Missing fields.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ Missing fields:
+ value: { "message": "Missing content" }
+ tags:
+ - Post
+ /post/{id}:
+ patch:
+ summary: Update post
+ description: Update post with ID.
+ Requires logged in user to have admin permissions for posts not made by them.
+ security:
+ - BasicAuth: []
+ - BasicAuth: [isAdmin]
+ parameters:
+ - name: id
+ in: path
+ description: Post ID
+ required: true
+ schema:
+ type: integer
+ format: int14
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/PostUpdateRequest"
+ responses:
+ 200:
+ description: Success.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/PostResponse"
+ 404:
+ description: Post not found.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ User not found:
+ value: { "message": "Post not found" }
+ 500:
+ description: Update failed.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ Failed:
+ value: { "message": "Failed to update post" }
+ tags:
+ - Post
+ delete:
+ summary: Delete post
+ description: Delete post with ID.
+ security:
+ - BasicAuth: [isAdmin]
+ parameters:
+ - name: id
+ in: path
+ description: Post ID
+ required: true
+ schema:
+ type: integer
+ format: int14
+ responses:
+ 200:
+ description: Success.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/PostResponse"
+ 404:
+ description: Post not found.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ Post not found:
+ value: { "message": "Post not found" }
+ tags:
+ - Post
externalDocs:
url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/
security: []
@@ -510,6 +513,13 @@ components:
type: string
password:
type: string
+ LoginResponse:
+ type: object
+ properties:
+ user:
+ $ref: "#/components/schemas/UserResponse"
+ token:
+ type: string
UserResponse:
type: object
properties:
@@ -585,6 +595,8 @@ components:
type: number
user:
$ref: "#/components/schemas/UserResponse"
+ content:
+ type: string
postedAt:
type: object
properties:
@@ -604,6 +616,18 @@ components:
type: array
items:
$ref: "#/components/schemas/PostResponse"
+ PostUpdateRequest:
+ type: object
+ properties:
+ content:
+ type: string
+ PostCreateRequest:
+ type: object
+ required:
+ - content
+ properties:
+ content:
+ type: string
securitySchemes:
BasicAuth:
type: apiKey
diff --git a/exam/api/docs/index.html b/exam/api/docs/index.html
index d74706a..87ee3ad 100644
--- a/exam/api/docs/index.html
+++ b/exam/api/docs/index.html
@@ -384,7 +384,7 @@ data-styled.g137[id="sc-kvXgyf"]{content:"fBvPoH,"}/*!sc*/
{- "username": "string",
- "password": "string"
}true{- "username": "string",
- "password": "string"
}{- "user": {
- "id": 0,
- "username": "string",
- "status": 0,
- "email": "string",
- "image": "string",
- "isAdmin": true,
- "memberSince": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}, - "postCount": 0
}, - "token": "string"
}{- "username": "string",
- "email": "string",
- "password": "string"
}{- "id": 0,
- "username": "string",
- "status": 0,
- "email": "string",
- "image": "string",
- "isAdmin": true,
- "memberSince": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}, - "postCount": 0
}Confirm a registration
| code required | string <uuid4> |
{- "pages": 1,
- "data": [
- {
- "id": 1,
- "username": "Admin",
- "status": 1,
- "email": "marvin@zedat.fu-berlin.de",
- "image": "669d41fbdb56b.png",
- "isAdmin": true,
- "memberSince": {
- "date": "2024-07-22 14:02:49.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin"
}, - "postCount": 3
}, - {
- "id": 2,
- "username": "Max",
- "status": 1,
- "email": "max@moritz.net",
- "image": "profilbilder/max.svg",
- "isAdmin": false,
- "memberSince": {
- "date": "2024-07-22 03:07:41.000000",
- "timezone_type": 3,
- "timezone": "Europe/Berlin"
}, - "postCount": 2
}
]
}{- "pages": 0,
- "data": [
- {
- "id": 0,
- "username": "string",
- "status": 0,
- "email": "string",
- "image": "string",
- "isAdmin": true,
- "memberSince": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}, - "postCount": 0
}
]
}Get user by ID.