diff --git a/exam/api/Login/Login.php b/exam/api/Login/Login.php
index 70e979b..fdcd279 100644
--- a/exam/api/Login/Login.php
+++ b/exam/api/Login/Login.php
@@ -4,6 +4,7 @@ namespace Api\Login;
use Exception;
use Khofmann\Api\Api;
+use Khofmann\ApiError\ApiError;
use Khofmann\Input\Input;
use Khofmann\Response\Response;
use Khofmann\Models\User\User;
@@ -12,21 +13,27 @@ class Login extends Api
{
public function post(): void
{
+ // Fetch all required inputs.
+ // Throw 400 error if a required one is missing.
+ $missing = [];
$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);
+ if (empty($email)) array_push($missing, "email");
+ if (empty($password)) array_push($missing, "password");
+ if (count($missing) > 0) throw ApiError::missingField($missing);
+ // Try and log in user.
+ // Throw errors according to situation.
try {
Response::json(User::logIn($email, $password));
} catch (Exception $err) {
switch ($err->getMessage()) {
case "Failed":
- throw new Exception("Login failed", 500);
+ throw ApiError::failed("Login failed");
case "NotFound":
- throw new Exception("User not found", 404);
+ throw ApiError::notFound("user");
case "Invalid":
- throw new Exception("Invalid username or password", 401);
+ throw ApiError::unauthorized("Invalid username or password");
default:
throw $err;
}
diff --git a/exam/api/Logout/Logout.php b/exam/api/Logout/Logout.php
index 8d087f2..6b0c459 100644
--- a/exam/api/Logout/Logout.php
+++ b/exam/api/Logout/Logout.php
@@ -11,8 +11,10 @@ class Logout extends Api
{
public function post(): void
{
+ // Get user auth token.
$token = Request::token();
+ // Log out.
Response::json(User::getByToken($token)->logOut());
}
}
diff --git a/exam/api/Post/Post.php b/exam/api/Post/Post.php
index dc12819..c24d23a 100644
--- a/exam/api/Post/Post.php
+++ b/exam/api/Post/Post.php
@@ -4,6 +4,7 @@ namespace Api\Post;
use Exception;
use Khofmann\Api\Api;
+use Khofmann\ApiError\ApiError;
use Khofmann\Input\Input;
use Khofmann\Models\Post\Post as MPost;
use Khofmann\Models\User\User;
@@ -12,40 +13,29 @@ use Khofmann\Response\Response;
class Post extends Api
{
- public function post(): void
- {
- $content = Input::patch("content");
-
- $self = User::getByToken(Request::token());
-
- try {
- Response::json(MPost::create($self, $content));
- } catch (Exception $err) {
- switch ($err->getMessage()) {
- default:
- throw $err;
- }
- }
- }
-
public function patch($id): void
{
+ // Fetch all inputs.
$content = Input::patch("content");
+ // Fetch authed user.
$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));
+ // Try fetch the post in question, 404 if not found.
+ $post = MPost::getByID($id);
+
+ // Throw 400 if we aren't admin but trying to edit another users post.
+ if (!$self->getIsAdmin() && $post->getUser()->getID() !== $self->getID()) throw ApiError::unauthorized("Not allowed");
+
+ // Try update.
+ Response::json($post->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);
+ throw ApiError::notFound("post");
default:
+ // Due to how the failed field is handled, it's ApiError is inside the models update
throw $err;
}
}
@@ -53,12 +43,13 @@ class Post extends Api
public function delete($id): void
{
+ // Try delete, 404 if post was not found.
try {
Response::json(MPost::getByID($id)->delete());
} catch (Exception $err) {
switch ($err->getMessage()) {
case "NotFound":
- throw new Exception("Post not found", 404);
+ throw ApiError::notFound("post");
default:
throw $err;
}
diff --git a/exam/api/Posts/Posts.php b/exam/api/Posts/Posts.php
index d9a701e..b853e2b 100644
--- a/exam/api/Posts/Posts.php
+++ b/exam/api/Posts/Posts.php
@@ -2,9 +2,12 @@
namespace Api\Posts;
+use Exception;
use Khofmann\Api\Api;
+use Khofmann\ApiError\ApiError;
use Khofmann\Input\Input;
use Khofmann\Models\Post\Post;
+use Khofmann\Models\User\User;
use Khofmann\Request\Request;
use Khofmann\Response\Response;
@@ -12,10 +15,33 @@ class Posts extends Api
{
public function get()
{
+ // Fetch and constrain all parameters.
$page = max(0, intval(Input::get("p", 0)));
$limit = constrain(0, 30, intval(Input::get("l", 10)));
$authed = Request::token() !== null;
+ // Return list of posts.
Response::json(Post::list($page, $limit, $authed));
}
+
+ public function post(): void
+ {
+ // Fetch all required inputs.
+ // Throw 400 error if a required one is missing.
+ $content = Input::post("content");
+ if (empty($content)) throw ApiError::missingField(["content"]);
+
+ // Get logged in user
+ $self = User::getByToken(Request::token());
+
+ // Try to create a new post for logged in user.
+ try {
+ Response::json(Post::create($self, $content));
+ } catch (Exception $err) {
+ switch ($err->getMessage()) {
+ default:
+ throw $err;
+ }
+ }
+ }
}
diff --git a/exam/api/Register/Register.php b/exam/api/Register/Register.php
index 78242cf..b57e544 100644
--- a/exam/api/Register/Register.php
+++ b/exam/api/Register/Register.php
@@ -4,6 +4,7 @@ namespace Api\Register;
use Exception;
use Khofmann\Api\Api;
+use Khofmann\ApiError\ApiError;
use Khofmann\Input\Input;
use Khofmann\Response\Response;
use Khofmann\Models\User\User;
@@ -12,19 +13,26 @@ class Register extends Api
{
public function post(): void
{
+ // Fetch all required inputs.
+ // Throw 400 error if a required one is missing.
+ $missing = [];
$username = Input::post("username");
- if (empty($username)) throw new Exception("Missing username", 400);
$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);
+ if (empty($username)) array_push($missing, "username");
+ if (empty($email)) array_push($missing, "email");
+ if (empty($password)) array_push($missing, "password");
+ if (count($missing) > 0) throw ApiError::missingField($missing);
+ // Try and create a new user, 400 if duplicate.
try {
Response::json(User::create($username, $email, $password));
} catch (Exception $err) {
switch ($err->getMessage()) {
+ case "NotFound":
+ throw ApiError::failed("Failed to create user");
case "Duplicate":
- throw new Exception("A user with this username or email already exists", 400);
+ throw ApiError::duplicate("user");
default:
throw $err;
}
@@ -33,15 +41,18 @@ class Register extends Api
public function patch(): void
{
+ // Fetch all required inputs.
+ // Throw 400 error if a required one is missing.
$code = Input::post("code");
- if (empty($code)) throw new Exception("Missing code", 400);
+ if (empty($code)) throw ApiError::missingField(["code"]);
+ // Try and confirm user, 404 if user not found.
try {
Response::json(User::confirm($code));
} catch (Exception $err) {
switch ($err->getMessage()) {
case "NotFound":
- throw new Exception("User not found", 404);
+ throw ApiError::notFound("user");
default:
throw $err;
}
diff --git a/exam/api/User/User.php b/exam/api/User/User.php
index cd274b9..ea46085 100644
--- a/exam/api/User/User.php
+++ b/exam/api/User/User.php
@@ -7,18 +7,20 @@ use Khofmann\Models\User\User as MUser;
use Khofmann\Input\Input;
use Khofmann\Response\Response;
use Khofmann\Api\Api;
+use Khofmann\ApiError\ApiError;
use Khofmann\Request\Request;
class User extends Api
{
public function get($id): void
{
+ // Try and get a user, 404 if not found.
try {
Response::json(MUser::getByID($id));
} catch (Exception $err) {
switch ($err->getMessage()) {
case "NotFound":
- throw new Exception("User not found", 404);
+ throw ApiError::notFound("user");
default:
throw $err;
}
@@ -27,23 +29,21 @@ class User extends Api
public function patch($id): void
{
+ // Fetch all inputs.
$username = Input::patch("username");
$password = Input::patch("password");
$image = Input::file("image");
+ // Try and update user.
+ // Throw errors according to situation.
try {
Response::json(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);
+ throw ApiError::notFound("user");
default:
+ // Due to how the failed field is handled, it's ApiError is inside the models update
throw $err;
}
}
@@ -51,24 +51,22 @@ class User extends Api
public function patchSelf(): void
{
+ // Fetch all inputs.
$token = Request::token();
$username = Input::patch("username");
$password = Input::patch("password");
$image = Input::file("image");
+ // Try and update user.
+ // Throw errors according to situation.
try {
Response::json(MUser::getByToken($token)->update($username, $password, $image));
} catch (Exception $err) {
switch ($err->getMessage()) {
case "NotFound":
- throw new Exception("User not found", 404);
- case "FailedUsername":
- throw new Exception("Failed to update username", 500);
- case "FailedPassword":
- throw new Exception("Failed to update password", 500);
- case "FailedImage":
- throw new Exception("Failed to update image", 500);
+ throw ApiError::notFound("user");
default:
+ // Due to how the failed field is handled, it's ApiError is inside the models update
throw $err;
}
}
@@ -76,12 +74,13 @@ class User extends Api
public function delete($id): void
{
+ // Try to delete user, 404 if not found.
try {
Response::json(MUser::getByID($id)->delete());
} catch (Exception $err) {
switch ($err->getMessage()) {
case "NotFound":
- throw new Exception("User not found", 404);
+ throw ApiError::notFound("user");
default:
throw $err;
}
diff --git a/exam/api/Users/Users.php b/exam/api/Users/Users.php
index 7f49e1c..1020cb2 100644
--- a/exam/api/Users/Users.php
+++ b/exam/api/Users/Users.php
@@ -11,8 +11,11 @@ class Users extends Api
{
public function get()
{
+ // Fetch and constrain all parameters.
$page = max(0, intval(Input::get("p", 0)));
$limit = constrain(0, 30, intval(Input::get("l", 10)));
+
+ // Return list of users.
Response::json(User::list($page, $limit));
}
}
diff --git a/exam/api/docs/api.yaml b/exam/api/docs/api.yaml
index 0098514..78069fc 100644
--- a/exam/api/docs/api.yaml
+++ b/exam/api/docs/api.yaml
@@ -29,37 +29,42 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/MissingFieldResponse"
examples:
Missing fields:
- value: { "message": "Missing email" }
+ value:
+ { "code": "MissingField", "fields": ["email", "password"] }
401:
description: Invalid credentials.
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/UnauthorizedResponse"
examples:
Invalid username or password:
- value: { "message": "Invalid username or password" }
+ value:
+ {
+ "code": "Unauthorized",
+ "message": "Invalid username or password",
+ }
404:
description: User not found.
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/NotFoundResponse"
examples:
User not found:
- value: { "message": "User not found" }
+ value: { "code": "NotFound", "entity": "user" }
500:
description: Failed.
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/FailedResponse"
examples:
Failed:
- value: { "message": "Login failed" }
+ value: { "code": "Failed", "message": "Login failed" }
tags:
- Login/Logout
/logout:
@@ -80,221 +85,6 @@ paths:
value: true
tags:
- Login/Logout
- /register:
- post:
- summary: Register
- description: Register a new user
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/RegisterRequest"
- responses:
- 200:
- description: Success
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/UserResponse"
- 400:
- description: Missing fields or duplicate
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ErrorResponse"
- examples:
- Missing fields:
- value: { "message": "Missing email" }
- Duplicate:
- value:
- {
- "message": "A user with this username or email already exists",
- }
- tags:
- - Register
- patch:
- summary: Confirm register
- description: Confirm a registration
- requestBody:
- required: true
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ConfirmRequest"
- 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 code" }
- 404:
- description: User not found
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ErrorResponse"
- examples:
- User not found:
- value: { "message": "User not found" }
- tags:
- - Register
- /users:
- get:
- summary: List users
- description: List all users.
- security:
- - BasicAuth: []
- parameters:
- - in: query
- name: p
- schema:
- type: integer
- minimum: 0
- default: 0
- description: Current page.
- - in: query
- name: l
- schema:
- type: integer
- minimum: 0
- maximum: 30
- default: 10
- description: The number of items to return.
- responses:
- 200:
- description: Success
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/UserListResponse"
- tags:
- - User
- /user/{id}:
- get:
- summary: Get user
- description: Get user by ID.
- security:
- - BasicAuth: [isAdmin]
- 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"
- 404:
- description: User not found.
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ErrorResponse"
- examples:
- User not found:
- value: { "message": "User not found" }
- tags:
- - User
- patch:
- summary: Update user
- description:
- Update user with ID. Fields are updated in order username, password, image. If one fails, subsequent are not updated.
- 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
- 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/UserResponse"
- 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:
- Failed username:
- value: { "message": "Failed to update username" }
- tags:
- - User
- delete:
- summary: Delete user
- description: Delete user with ID.
- security:
- - BasicAuth: [isAdmin]
- 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"
- 404:
- description: User not found.
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/ErrorResponse"
- examples:
- User not found:
- value: { "message": "User not found" }
- tags:
- - User
/posts:
get:
summary: List posts
@@ -404,16 +194,16 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/MissingFieldResponse"
examples:
Missing fields:
- value: { "message": "Missing content" }
+ value: { "code": "MissingField", "fields": ["content"] }
tags:
- Post
/post/{id}:
patch:
summary: Update post
- description: Update post with ID.
+ description: Update post with ID.
Requires logged in user to have admin permissions for posts not made by them.
security:
- BasicAuth: []
@@ -438,24 +228,33 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/PostResponse"
+ 401:
+ description: Not allowed.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UnauthorizedResponse"
+ examples:
+ Not allowed:
+ value: { "code": "Unauthorized", "message": "Not allowed" }
404:
description: Post not found.
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/NotFoundResponse"
examples:
- User not found:
- value: { "message": "Post not found" }
+ Post not found:
+ value: { "code": "NotFound", "entity": "post" }
500:
description: Update failed.
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/FailedUpdateResponse"
examples:
Failed:
- value: { "message": "Failed to update post" }
+ value: { "code": "FailedUpdate", "fields": ["content"] }
tags:
- Post
delete:
@@ -483,12 +282,242 @@ paths:
content:
application/json:
schema:
- $ref: "#/components/schemas/ErrorResponse"
+ $ref: "#/components/schemas/NotFoundResponse"
examples:
Post not found:
- value: { "message": "Post not found" }
+ value: { "code": "NotFound", "entity": "post" }
tags:
- Post
+ /register:
+ post:
+ summary: Register
+ description: Register a new user.
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/RegisterRequest"
+ responses:
+ 200:
+ description: Success.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UserResponse"
+ 400:
+ description: Missing fields or duplicate.
+ content:
+ application/json:
+ schema:
+ oneOf:
+ - $ref: "#/components/schemas/MissingFieldResponse"
+ - $ref: "#/components/schemas/DuplicateResponse"
+ examples:
+ Missing fields:
+ value:
+ {
+ "code": "MissingField",
+ "fields": ["username", "email", "password"],
+ }
+ Duplicate:
+ value: { "code": "Duplicate", "entity": "user" }
+ 404:
+ description: Failed to create
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/FailedResponse"
+ examples:
+ Failed to create:
+ value:
+ { "code": "Failed", "message": "Failed to create user" }
+ tags:
+ - Register
+ patch:
+ summary: Confirm register
+ description: Confirm a registration.
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ConfirmRequest"
+ responses:
+ 200:
+ description: Success.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UserResponse"
+ 400:
+ description: Missing fields.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/MissingFieldResponse"
+ examples:
+ Missing fields:
+ value: { "code": "MissingField", "fields": ["code"] }
+ 404:
+ description: User not found.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/NotFoundResponse"
+ examples:
+ User not found:
+ value: { "code": "NotFound", "entity": "user" }
+ tags:
+ - Register
+ /users:
+ get:
+ summary: List users
+ description: List all users.
+ security:
+ - BasicAuth: []
+ parameters:
+ - in: query
+ name: p
+ schema:
+ type: integer
+ minimum: 0
+ default: 0
+ description: Current page.
+ - in: query
+ name: l
+ schema:
+ type: integer
+ minimum: 0
+ maximum: 30
+ default: 10
+ description: The number of items to return.
+ responses:
+ 200:
+ description: Success
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/UserListResponse"
+ tags:
+ - User
+
+ /user/{id}:
+ get:
+ summary: Get user
+ description: Get user by ID.
+ security:
+ - BasicAuth: [isAdmin]
+ 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"
+ 404:
+ description: User not found.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/NotFoundResponse"
+ examples:
+ User not found:
+ value: { "code": "NotFound", "entity": "user" }
+ tags:
+ - User
+ patch:
+ summary: Update user
+ description: Update user with ID.
+ 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
+ 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/UserResponse"
+ 404:
+ description: User not found.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/NotFoundResponse"
+ examples:
+ User not found:
+ value: { "code": "NotFound", "entity": "username" }
+ 500:
+ description: Update failed.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/FailedUpdateResponse"
+ examples:
+ Failed username:
+ value:
+ {
+ "code": "FailedUpdate",
+ "fields": ["username", "email", "password"],
+ }
+ tags:
+ - User
+ delete:
+ summary: Delete user
+ description: Delete user with ID.
+ security:
+ - BasicAuth: [isAdmin]
+ 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"
+ 404:
+ description: User not found.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/NotFoundResponse"
+ examples:
+ User not found:
+ value: { "code": "NotFound", "entity": "user" }
+ tags:
+ - User
+
externalDocs:
url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/
security: []
@@ -498,6 +527,52 @@ components:
schemas:
BooleanResponse:
type: boolean
+ MissingFieldResponse:
+ type: object
+ properties:
+ code:
+ type: MissingField
+ fields:
+ type: array
+ items:
+ type: string
+ NotFoundResponse:
+ type: object
+ properties:
+ code:
+ type: NotFound
+ entity:
+ type: string
+ UnauthorizedResponse:
+ type: object
+ properties:
+ code:
+ type: Unauthorized
+ message:
+ type: string
+ FailedResponse:
+ type: object
+ properties:
+ code:
+ type: Failed
+ message:
+ type: string
+ DuplicateResponse:
+ type: object
+ properties:
+ code:
+ type: Duplicate
+ entity:
+ type: string
+ FailedUpdateResponse:
+ type: object
+ properties:
+ code:
+ type: FailedUpdate
+ fields:
+ type: array
+ items:
+ type: string
ErrorResponse:
type: object
properties:
@@ -635,6 +710,6 @@ components:
in: header
tags:
- name: Login/Logout
+ - name: Post
- name: Register
- name: User
- - name: Post
diff --git a/exam/api/docs/index.html b/exam/api/docs/index.html
index 87ee3ad..87d2bc1 100644
--- a/exam/api/docs/index.html
+++ b/exam/api/docs/index.html
@@ -327,10 +327,10 @@ 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*/
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*/
-.eUIOSr{font-size:0.929em;line-height:20px;background-color:#bf581d;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!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*/
+.eUIOSr{font-size:0.929em;line-height:20px;background-color:#bf581d;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
.ByFMv{font-size:0.929em;line-height:20px;background-color:#cc3333;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
-data-styled.g113[id="sc-oeqTF"]{content:"kpMtuJ,eUIOSr,ffmPnn,ByFMv,"}/*!sc*/
+data-styled.g113[id="sc-oeqTF"]{content:"kpMtuJ,ffmPnn,eUIOSr,ByFMv,"}/*!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*/
.hdRKqQ{padding:10px;}/*!sc*/
@@ -384,7 +384,7 @@ data-styled.g137[id="sc-kvXgyf"]{content:"fBvPoH,"}/*!sc*/
Register a new user
-| username required | string |
| email required | string |
| password required | 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
}List all posts, return full user data if authenticated.
+| p | integer >= 0 Default: 0 Current page. + |
| l | integer [ 0 .. 30 ] Default: 10 The number of items to return. + |
{- "pages": 0,
- "data": [
- {
- "id": 0,
- "user": {
- "username": "string"
}, - "content": "string",
- "postedAt": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}
}
]
}Create a new post.
+| content required | string |
{- "content": "string"
}{- "id": 0,
- "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
}, - "content": "string",
- "postedAt": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}
}Update post with ID.
Requires logged in user to have admin permissions for posts not made by them.
| id required | integer <int14> Post ID + |
| content | string |
{- "content": "string"
}{- "id": 0,
- "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
}, - "content": "string",
- "postedAt": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}
}Delete post with ID.
+| id required | integer <int14> Post ID + |
{- "id": 0,
- "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
}, - "content": "string",
- "postedAt": {
- "date": "2019-08-24T14:15:22Z",
- "timezone_type": 0,
- "timezone": "string"
}
}Register a new user.
+| username required | string |
| email required | string |
| password required | 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> |
{- "code": "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
}List all users.
| p | integer >= 0 Default: 0 Current page. @@ -442,7 +478,7 @@ data-styled.g137[id="sc-kvXgyf"]{content:"fBvPoH,"}/*!sc*/ " class="sc-euGpHm sc-exayXG fwfkcU jYGAQp">The number of items to return. |
{- "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
}
]
}{- "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.