summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorTyler Murphy <tylermurphy534@gmail.com>2023-01-26 17:29:16 -0500
committerTyler Murphy <tylermurphy534@gmail.com>2023-01-26 17:29:16 -0500
commit88209d88236c3d865a9f5174a0dced31920859bf (patch)
tree89a9985927393005cf632950b585a6a227b1c679 /src/api
downloadxssbook-88209d88236c3d865a9f5174a0dced31920859bf.tar.gz
xssbook-88209d88236c3d865a9f5174a0dced31920859bf.tar.bz2
xssbook-88209d88236c3d865a9f5174a0dced31920859bf.zip
i did things
Diffstat (limited to 'src/api')
-rw-r--r--src/api/auth.rs98
-rw-r--r--src/api/mod.rs4
-rw-r--r--src/api/pages.rs58
-rw-r--r--src/api/posts.rs102
-rw-r--r--src/api/users.rs52
5 files changed, 314 insertions, 0 deletions
diff --git a/src/api/auth.rs b/src/api/auth.rs
new file mode 100644
index 0000000..d60483f
--- /dev/null
+++ b/src/api/auth.rs
@@ -0,0 +1,98 @@
+use axum::{Router, routing::post, response::Response};
+use serde::Deserialize;
+use time::{OffsetDateTime, Duration};
+use tower_cookies::{Cookies, Cookie};
+
+use crate::types::{user::User, response::ResponseCode, session::Session, extract::{Json, AuthorizedUser}};
+
+#[derive(Deserialize)]
+struct RegistrationRequet {
+ firstname: String,
+ lastname: String,
+ email: String,
+ password: String,
+ gender: String,
+ day: u8,
+ month: u8,
+ year: u32
+}
+
+
+async fn register(cookies: Cookies, Json(body): Json<RegistrationRequet>) -> Response {
+
+ let user = match User::new(body.firstname, body.lastname, body.email, body.password, body.gender, body.day, body.month, body.year) {
+ Ok(user) => user,
+ Err(err) => return err
+ };
+
+ let session = match Session::new(user.user_id) {
+ Ok(session) => session,
+ Err(err) => return err
+ };
+
+ let mut now = OffsetDateTime::now_utc();
+ now += Duration::weeks(52);
+
+ let mut cookie = Cookie::new("auth", session.token);
+ cookie.set_secure(false);
+ cookie.set_http_only(false);
+ cookie.set_expires(now);
+ cookie.set_path("/");
+
+ cookies.add(cookie);
+
+ ResponseCode::Created.msg("Successfully created new user")
+}
+
+#[derive(Deserialize)]
+struct LoginRequest {
+ email: String,
+ password: String,
+}
+
+async fn login(cookies: Cookies, Json(body): Json<LoginRequest>) -> Response {
+
+ let Ok(user) = User::from_email(&body.email) else {
+ return ResponseCode::BadRequest.msg("Email is not registered")
+ };
+
+ if user.password != body.password {
+ return ResponseCode::BadRequest.msg("Password is not correct")
+ }
+
+ let session = match Session::new(user.user_id) {
+ Ok(session) => session,
+ Err(err) => return err
+ };
+
+ let mut now = OffsetDateTime::now_utc();
+ now += Duration::weeks(52);
+
+ let mut cookie = Cookie::new("auth", session.token);
+ cookie.set_secure(false);
+ cookie.set_http_only(false);
+ cookie.set_expires(now);
+ cookie.set_path("/");
+
+ cookies.add(cookie);
+
+ ResponseCode::Success.msg("Successfully logged in")
+}
+
+async fn logout(cookies: Cookies, AuthorizedUser(user): AuthorizedUser) -> Response {
+
+ cookies.remove(Cookie::new("auth", ""));
+
+ if let Err(err) = Session::delete(user.user_id) {
+ return err
+ }
+
+ ResponseCode::Success.msg("Successfully logged out")
+}
+
+pub fn router() -> Router {
+ Router::new()
+ .route("/register", post(register))
+ .route("/login", post(login))
+ .route("/logout", post(logout))
+} \ No newline at end of file
diff --git a/src/api/mod.rs b/src/api/mod.rs
new file mode 100644
index 0000000..ba38aeb
--- /dev/null
+++ b/src/api/mod.rs
@@ -0,0 +1,4 @@
+pub mod auth;
+pub mod pages;
+pub mod posts;
+pub mod users; \ No newline at end of file
diff --git a/src/api/pages.rs b/src/api/pages.rs
new file mode 100644
index 0000000..749a686
--- /dev/null
+++ b/src/api/pages.rs
@@ -0,0 +1,58 @@
+use axum::{Router, response::{Response, Redirect, IntoResponse}, routing::get};
+
+use crate::types::{extract::AuthorizedUser, response::ResponseCode};
+
+async fn root(user: Option<AuthorizedUser>) -> Response {
+ println!("{}", user.is_some());
+ if user.is_some() {
+ return Redirect::to("/home").into_response()
+ } else {
+ return Redirect::to("/login").into_response()
+ }
+}
+
+async fn login(user: Option<AuthorizedUser>) -> Response {
+ if user.is_some() {
+ return Redirect::to("/home").into_response()
+ } else {
+ return ResponseCode::Success.file("/login.html").await.unwrap()
+ }
+}
+
+async fn home(user: Option<AuthorizedUser>) -> Response {
+ if user.is_none() {
+ return Redirect::to("/login").into_response()
+ } else {
+ return ResponseCode::Success.file("/home.html").await.unwrap()
+ }
+}
+
+async fn people(user: Option<AuthorizedUser>) -> Response {
+ if user.is_none() {
+ return Redirect::to("/login").into_response()
+ } else {
+ return ResponseCode::Success.file("/people.html").await.unwrap()
+ }
+}
+
+async fn profile(user: Option<AuthorizedUser>) -> Response {
+ if user.is_none() {
+ return Redirect::to("/login").into_response()
+ } else {
+ return ResponseCode::Success.file("/profile.html").await.unwrap()
+ }
+}
+
+async fn wordpress() -> Response {
+ ResponseCode::ImATeapot.msg("Hello i am a teapot owo")
+}
+
+pub fn router() -> Router {
+ Router::new()
+ .route("/", get(root))
+ .route("/login", get(login))
+ .route("/home", get(home))
+ .route("/people", get(people))
+ .route("/profile", get(profile))
+ .route("/wp-admin", get(wordpress))
+} \ No newline at end of file
diff --git a/src/api/posts.rs b/src/api/posts.rs
new file mode 100644
index 0000000..405dfa6
--- /dev/null
+++ b/src/api/posts.rs
@@ -0,0 +1,102 @@
+use axum::{response::Response, Router, routing::{post, patch}};
+use serde::Deserialize;
+
+use crate::types::{extract::{AuthorizedUser, Json}, post::Post, response::ResponseCode};
+
+
+#[derive(Deserialize)]
+struct PostCreateRequest {
+ content: String
+}
+
+async fn create(AuthorizedUser(user): AuthorizedUser, Json(body): Json<PostCreateRequest>) -> Response {
+
+ let Ok(_post) = Post::new(user.user_id, body.content) else {
+ return ResponseCode::InternalServerError.msg("Failed to create post")
+ };
+
+ ResponseCode::Created.msg("Successfully created new post")
+}
+
+#[derive(Deserialize)]
+struct PostPageRequest {
+ page: u64
+}
+
+async fn page(AuthorizedUser(_user): AuthorizedUser, Json(body): Json<PostPageRequest>) -> Response {
+
+ let Ok(posts) = Post::from_post_page(body.page) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ };
+
+ let Ok(json) = serde_json::to_string(&posts) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ };
+
+ ResponseCode::Success.json(&json)
+}
+
+#[derive(Deserialize)]
+struct UsersPostsRequest {
+ user_id: u64
+}
+
+async fn user(AuthorizedUser(_user): AuthorizedUser, Json(body): Json<UsersPostsRequest>) -> Response {
+
+ let Ok(posts) = Post::from_user_id(body.user_id) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ };
+
+ let Ok(json) = serde_json::to_string(&posts) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ };
+
+ ResponseCode::Success.json(&json)
+}
+
+#[derive(Deserialize)]
+struct PostCommentRequest {
+ content: String,
+ post_id: u64
+}
+
+async fn comment(AuthorizedUser(user): AuthorizedUser, Json(body): Json<PostCommentRequest>) -> Response {
+
+ let Ok(mut post) = Post::from_post_id(body.post_id) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ };
+
+ if let Err(err) = post.comment(user.user_id, body.content) {
+ return err;
+ }
+
+ ResponseCode::Success.msg("Successfully commented on post")
+}
+
+#[derive(Deserialize)]
+struct PostLikeRequest {
+ state: bool,
+ post_id: u64
+}
+
+async fn like(AuthorizedUser(user): AuthorizedUser, Json(body): Json<PostLikeRequest>) -> Response {
+
+ let Ok(mut post) = Post::from_post_id(body.post_id) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch posts")
+ };
+
+ if let Err(err) = post.like(user.user_id, body.state) {
+ return err;
+ }
+
+ ResponseCode::Success.msg("Successfully changed like status on post")
+}
+
+pub fn router() -> Router {
+ Router::new()
+ .route("/create", post(create))
+ .route("/page", post(page))
+ .route("/user", post(user))
+ .route("/comment", patch(comment))
+ .route("/like", patch(like))
+} \ No newline at end of file
diff --git a/src/api/users.rs b/src/api/users.rs
new file mode 100644
index 0000000..283ec96
--- /dev/null
+++ b/src/api/users.rs
@@ -0,0 +1,52 @@
+use axum::{Router, response::Response, routing::post};
+use serde::Deserialize;
+use crate::types::{extract::{AuthorizedUser, Json}, response::ResponseCode, user::User};
+
+#[derive(Deserialize)]
+struct UserLoadRequest {
+ ids: Vec<u64>
+}
+
+async fn load_batch(AuthorizedUser(_user): AuthorizedUser, Json(body): Json<UserLoadRequest>) -> Response {
+
+ let users = User::from_user_ids(body.ids);
+ let Ok(json) = serde_json::to_string(&users) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch users")
+ };
+
+ ResponseCode::Success.json(&json)
+}
+
+#[derive(Deserialize)]
+struct UserPageReqiest {
+ page: u64
+}
+
+async fn load_page(AuthorizedUser(_user): AuthorizedUser, Json(body): Json<UserPageReqiest>) -> Response {
+
+ let Ok(users) = User::from_user_page(body.page) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch users")
+ };
+
+ let Ok(json) = serde_json::to_string(&users) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch users")
+ };
+
+ ResponseCode::Success.json(&json)
+}
+
+async fn load_self(AuthorizedUser(user): AuthorizedUser) -> Response {
+
+ let Ok(json) = serde_json::to_string(&user) else {
+ return ResponseCode::InternalServerError.msg("Failed to fetch user")
+ };
+
+ ResponseCode::Success.json(&json)
+}
+
+pub fn router() -> Router {
+ Router::new()
+ .route("/load", post(load_batch))
+ .route("/self", post(load_self))
+ .route("/page", post(load_page))
+} \ No newline at end of file