summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/api')
-rw-r--r--src/api/admin.rs75
-rw-r--r--src/api/auth.rs57
-rw-r--r--src/api/mod.rs8
-rw-r--r--src/api/posts.rs97
-rw-r--r--src/api/users.rs82
5 files changed, 308 insertions, 11 deletions
diff --git a/src/api/admin.rs b/src/api/admin.rs
index a23d20f..8db3032 100644
--- a/src/api/admin.rs
+++ b/src/api/admin.rs
@@ -6,13 +6,29 @@ use tower_cookies::{Cookie, Cookies};
use crate::{
database,
- public::admin,
+ public::{admin, docs::{EndpointDocumentation, EndpointMethod}},
types::{
extract::{AdminUser, Check, CheckResult, Json},
http::ResponseCode,
},
};
+pub const ADMIN_AUTH: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/admin/auth",
+ method: EndpointMethod::Post,
+ description: "Authenticates on the admin panel",
+ body: Some(r#"
+ {
+ "secret" : "admin"
+ }
+ "#),
+ responses: &[
+ (200, "Successfully executed SQL query"),
+ (400, " Successfully authed, admin cookie returned")
+ ],
+ cookie: None,
+};
+
#[derive(Deserialize)]
struct AdminAuthRequest {
secret: String,
@@ -40,6 +56,24 @@ async fn auth(cookies: Cookies, Json(body): Json<AdminAuthRequest>) -> Response
ResponseCode::Success.text("Successfully logged in")
}
+pub const ADMIN_QUERY: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/admin/query",
+ method: EndpointMethod::Post,
+ description: "Run a SQL query on the database",
+ body: Some(r#"
+ {
+ "query" : "DROP TABLE users;"
+ }
+ "#),
+ responses: &[
+ (200, "Successfully executed SQL query"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "SQL query ran into an error")
+ ],
+ cookie: Some("admin"),
+};
+
#[derive(Deserialize)]
struct QueryRequest {
query: String,
@@ -60,14 +94,53 @@ async fn query(_: AdminUser, Json(body): Json<QueryRequest>) -> Response {
}
}
+pub const ADMIN_POSTS: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/admin/posts",
+ method: EndpointMethod::Post,
+ description: "Returns the entire posts table",
+ body: None,
+ responses: &[
+ (200, "Returns sql table in <span>text/html</span>"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch data")
+ ],
+ cookie: Some("admin"),
+};
+
async fn posts(_: AdminUser) -> Response {
admin::generate_posts()
}
+pub const ADMIN_USERS: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/admin/users",
+ method: EndpointMethod::Post,
+ description: "Returns the entire users table",
+ body: None,
+ responses: &[
+ (200, "Returns sql table in <span>text/html</span>"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch data")
+ ],
+ cookie: Some("admin"),
+};
+
async fn users(_: AdminUser) -> Response {
admin::generate_users()
}
+pub const ADMIN_SESSIONS: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/admin/sessions",
+ method: EndpointMethod::Post,
+ description: "Returns the entire sessions table",
+ body: None,
+ responses: &[
+ (200, "Returns sql table in <span>text/html</span>"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch data")
+ ],
+ cookie: Some("admin"),
+};
+
async fn sessions(_: AdminUser) -> Response {
admin::generate_sessions()
}
diff --git a/src/api/auth.rs b/src/api/auth.rs
index 7f7cf9e..0ff180e 100644
--- a/src/api/auth.rs
+++ b/src/api/auth.rs
@@ -3,11 +3,34 @@ use serde::Deserialize;
use time::{Duration, OffsetDateTime};
use tower_cookies::{Cookie, Cookies};
-use crate::types::{
+use crate::{types::{
extract::{AuthorizedUser, Check, CheckResult, Json, Log},
http::ResponseCode,
session::Session,
user::User,
+}, public::docs::{EndpointDocumentation, EndpointMethod}};
+
+pub const AUTH_REGISTER: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/auth/register",
+ method: EndpointMethod::Post,
+ description: "Registeres a new account",
+ body: Some(r#"
+ {
+ "firstname": "[Object]",
+ "lastname": "object]",
+ "email": "object@object.object",
+ "password": "i love js",
+ "gender": "object",
+ "day": 1,
+ "month": 1,
+ "year": 1970
+ }
+ "#),
+ responses: &[
+ (201, "Successfully registered new user"),
+ (400, "Body does not match parameters"),
+ ],
+ cookie: None,
};
#[derive(Deserialize, Debug)]
@@ -93,9 +116,26 @@ async fn register(cookies: Cookies, Json(body): Json<RegistrationRequet>) -> Res
cookies.add(cookie);
- ResponseCode::Created.text("Successfully created new user")
+ ResponseCode::Created.text("Successfully created new user, auth cookie is returned")
}
+pub const AUTH_LOGIN: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/auth/login",
+ method: EndpointMethod::Post,
+ description: "Logs into an existing account",
+ body: Some(r#"
+ {
+ "email": "object@object.object",
+ "password": "i love js"
+ }
+ "#),
+ responses: &[
+ (200, "Successfully logged in, auth cookie is returned"),
+ (400, "Body does not match parameters, or invalid email password combination"),
+ ],
+ cookie: None,
+};
+
#[derive(Deserialize)]
struct LoginRequest {
email: String,
@@ -136,6 +176,19 @@ async fn login(cookies: Cookies, Json(body): Json<LoginRequest>) -> Response {
ResponseCode::Success.text("Successfully logged in")
}
+pub const AUTH_LOGOUT: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/auth/logout",
+ method: EndpointMethod::Post,
+ description: "Logs out of a logged in account",
+ body: None,
+ responses: &[
+ (200, "Successfully logged out"),
+ (401, "Unauthorized"),
+ (500, "Failed to log out user")
+ ],
+ cookie: None,
+};
+
async fn logout(cookies: Cookies, AuthorizedUser(user): AuthorizedUser, _: Log) -> Response {
cookies.remove(Cookie::new("auth", ""));
diff --git a/src/api/mod.rs b/src/api/mod.rs
index 9efcefc..12563e3 100644
--- a/src/api/mod.rs
+++ b/src/api/mod.rs
@@ -6,10 +6,10 @@ use tower_governor::{
GovernorLayer,
};
-mod admin;
-mod auth;
-mod posts;
-mod users;
+pub mod admin;
+pub mod auth;
+pub mod posts;
+pub mod users;
pub use auth::RegistrationRequet;
diff --git a/src/api/posts.rs b/src/api/posts.rs
index 6aa074f..f1cdab3 100644
--- a/src/api/posts.rs
+++ b/src/api/posts.rs
@@ -5,10 +5,28 @@ use axum::{
};
use serde::Deserialize;
-use crate::types::{
+use crate::{types::{
extract::{AuthorizedUser, Check, CheckResult, Json},
http::ResponseCode,
post::Post,
+}, public::docs::{EndpointDocumentation, EndpointMethod}};
+
+pub const POSTS_CREATE: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/posts/create",
+ method: EndpointMethod::Post,
+ description: "Creates a new post",
+ body: Some(r#"
+ {
+ "content" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
+ }
+ "#),
+ responses: &[
+ (201, "Successfully created post"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to create post")
+ ],
+ cookie: Some("auth"),
};
#[derive(Deserialize)]
@@ -43,6 +61,24 @@ async fn create(
ResponseCode::Created.json(&json)
}
+pub const POSTS_PAGE: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/posts/page",
+ method: EndpointMethod::Post,
+ description: "Load a section of posts from newest to oldest",
+ body: Some(r#"
+ {
+ "page": 0
+ }
+ "#),
+ responses: &[
+ (200, "Returns posts in <span>application/json<span>"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch posts")
+ ],
+ cookie: Some("auth"),
+};
+
#[derive(Deserialize)]
struct PostPageRequest {
page: u64,
@@ -69,10 +105,29 @@ async fn page(
ResponseCode::Success.json(&json)
}
+pub const POSTS_USER: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/posts/user",
+ method: EndpointMethod::Post,
+ description: "Load a section of posts from newest to oldest from a specific user",
+ body: Some(r#"
+ {
+ "user_id": 3,
+ "page": 0
+ }
+ "#),
+ responses: &[
+ (200, "Returns posts in <span>application/json<span>"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch posts")
+ ],
+ cookie: Some("auth"),
+};
+
#[derive(Deserialize)]
struct UsersPostsRequest {
user_id: u64,
- page: u64
+ page: u64,
}
impl Check for UsersPostsRequest {
@@ -96,6 +151,25 @@ async fn user(
ResponseCode::Success.json(&json)
}
+pub const POSTS_COMMENT: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/posts/comment",
+ method: EndpointMethod::Patch,
+ description: "Add a comment to a post",
+ body: Some(r#"
+ {
+ "content": "This is a very cool comment",
+ "post_id": 0
+ }
+ "#),
+ responses: &[
+ (200, "Successfully added comment"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to add comment")
+ ],
+ cookie: Some("auth"),
+};
+
#[derive(Deserialize)]
struct PostCommentRequest {
content: String,
@@ -129,6 +203,25 @@ async fn comment(
ResponseCode::Success.text("Successfully commented on post")
}
+pub const POSTS_LIKE: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/posts/like",
+ method: EndpointMethod::Patch,
+ description: "Set like status on a post",
+ body: Some(r#"
+ {
+ "post_id" : 0,
+ "status" : true
+ }
+ "#),
+ responses: &[
+ (200, "Successfully set like status"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to set like status")
+ ],
+ cookie: Some("auth"),
+};
+
#[derive(Deserialize)]
struct PostLikeRequest {
state: bool,
diff --git a/src/api/users.rs b/src/api/users.rs
index e3c992b..7d1f006 100644
--- a/src/api/users.rs
+++ b/src/api/users.rs
@@ -1,8 +1,8 @@
-use crate::types::{
+use crate::{types::{
extract::{AuthorizedUser, Check, CheckResult, Json, Png},
http::ResponseCode,
user::User,
-};
+}, public::docs::{EndpointDocumentation, EndpointMethod}};
use axum::{
response::Response,
routing::{post, put},
@@ -10,6 +10,24 @@ use axum::{
};
use serde::Deserialize;
+pub const USERS_LOAD: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/users/load",
+ method: EndpointMethod::Post,
+ description: "Loads a requested set of users",
+ body: Some(r#"
+ {
+ "ids": [0, 3, 7]
+ }
+ "#),
+ responses: &[
+ (200, "Returns users in <span>application/json</span>"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch users")
+ ],
+ cookie: Some("auth"),
+};
+
#[derive(Deserialize)]
struct UserLoadRequest {
ids: Vec<u64>,
@@ -33,6 +51,25 @@ async fn load_batch(
ResponseCode::Success.json(&json)
}
+pub const USERS_PAGE: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/users/page",
+ method: EndpointMethod::Post,
+ description: "Load a section of users from newest to oldest",
+ body: Some(r#"
+ {
+ "user_id": 3,
+ "page": 0
+ }
+ "#),
+ responses: &[
+ (200, "Returns users in <span>application/json</span>"),
+ (400, "Body does not match parameters"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch users")
+ ],
+ cookie: Some("auth"),
+};
+
#[derive(Deserialize)]
struct UserPageReqiest {
page: u64,
@@ -59,6 +96,19 @@ async fn load_page(
ResponseCode::Success.json(&json)
}
+pub const USERS_SELF: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/users/self",
+ method: EndpointMethod::Post,
+ description: "Returns current authenticated user (whoami)",
+ body: None,
+ responses: &[
+ (200, "Successfully executed SQL query"),
+ (401, "Unauthorized"),
+ (500, "Failed to fetch user")
+ ],
+ cookie: Some("auth"),
+};
+
async fn load_self(AuthorizedUser(user): AuthorizedUser) -> Response {
let Ok(json) = serde_json::to_string(&user) else {
return ResponseCode::InternalServerError.text("Failed to fetch user")
@@ -67,6 +117,20 @@ async fn load_self(AuthorizedUser(user): AuthorizedUser) -> Response {
ResponseCode::Success.json(&json)
}
+pub const USERS_AVATAR: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/users/avatar",
+ method: EndpointMethod::Put,
+ description: "Set your current profile avatar",
+ body: Some("PNG sent as a binary blob"),
+ responses: &[
+ (200, "Successfully updated avatar"),
+ (400, "Invalid PNG or disallowed size"),
+ (401, "Unauthorized"),
+ (500, "Failed to update avatar")
+ ],
+ cookie: Some("auth"),
+};
+
async fn avatar(AuthorizedUser(user): AuthorizedUser, Png(img): Png) -> Response {
let path = format!("./public/image/custom/avatar/{}.png", user.user_id);
@@ -77,6 +141,20 @@ async fn avatar(AuthorizedUser(user): AuthorizedUser, Png(img): Png) -> Response
ResponseCode::Success.text("Successfully updated avatar")
}
+pub const USERS_BANNER: EndpointDocumentation = EndpointDocumentation {
+ uri: "/api/users/banner",
+ method: EndpointMethod::Put,
+ description: "Set your current profile banner",
+ body: Some("PNG sent as a binary blob"),
+ responses: &[
+ (200, "Successfully updated banner"),
+ (400, "Invalid PNG or disallowed size"),
+ (401, "Unauthorized"),
+ (500, "Failed to update banner")
+ ],
+ cookie: Some("auth"),
+};
+
async fn banner(AuthorizedUser(user): AuthorizedUser, Png(img): Png) -> Response {
let path = format!("./public/image/custom/banner/{}.png", user.user_id);