routes: pastes: Finish impl of paste creation
Signed-off-by: ATechnoHazard <amolele@gmail.com>
This commit is contained in:
		
							parent
							
								
									0e5abac774
								
							
						
					
					
						commit
						8e44b02235
					
				
							
								
								
									
										31
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										31
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -64,6 +64,12 @@ dependencies = [
 | 
				
			|||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "anyhow"
 | 
				
			||||||
 | 
					version = "1.0.31"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "arrayref"
 | 
					name = "arrayref"
 | 
				
			||||||
version = "0.3.6"
 | 
					version = "0.3.6"
 | 
				
			||||||
@ -124,6 +130,18 @@ version = "0.12.2"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67"
 | 
					checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "bcrypt"
 | 
				
			||||||
 | 
					version = "0.8.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "41b70db86f3c560199b0dada79a22b9a924622384abb2a756a9707ffcce077f2"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64 0.12.2",
 | 
				
			||||||
 | 
					 "blowfish",
 | 
				
			||||||
 | 
					 "byteorder",
 | 
				
			||||||
 | 
					 "getrandom",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bitflags"
 | 
					name = "bitflags"
 | 
				
			||||||
version = "1.2.1"
 | 
					version = "1.2.1"
 | 
				
			||||||
@ -171,6 +189,17 @@ dependencies = [
 | 
				
			|||||||
 "byte-tools",
 | 
					 "byte-tools",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "blowfish"
 | 
				
			||||||
 | 
					version = "0.4.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "6aeb80d00f2688459b8542068abd974cfb101e7a82182414a99b5026c0d85cc3"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "block-cipher-trait",
 | 
				
			||||||
 | 
					 "byteorder",
 | 
				
			||||||
 | 
					 "opaque-debug",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bumpalo"
 | 
					name = "bumpalo"
 | 
				
			||||||
version = "3.4.0"
 | 
					version = "3.4.0"
 | 
				
			||||||
@ -601,6 +630,8 @@ dependencies = [
 | 
				
			|||||||
name = "katbin"
 | 
					name = "katbin"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "anyhow",
 | 
				
			||||||
 | 
					 "bcrypt",
 | 
				
			||||||
 "chrono",
 | 
					 "chrono",
 | 
				
			||||||
 "diesel",
 | 
					 "diesel",
 | 
				
			||||||
 "diesel_migrations",
 | 
					 "diesel_migrations",
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,8 @@ dotenv = "0.15.0"
 | 
				
			|||||||
jsonwebtoken = "7.1.2"
 | 
					jsonwebtoken = "7.1.2"
 | 
				
			||||||
slog = "2.5.2"
 | 
					slog = "2.5.2"
 | 
				
			||||||
slog-term = "2.6.0"
 | 
					slog-term = "2.6.0"
 | 
				
			||||||
 | 
					anyhow = "1.0"
 | 
				
			||||||
slog-async = "2.5.0"
 | 
					slog-async = "2.5.0"
 | 
				
			||||||
 | 
					bcrypt = "0.8"
 | 
				
			||||||
chrono = "0.4.11"
 | 
					chrono = "0.4.11"
 | 
				
			||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
 | 
					uuid = { version = "0.8", features = ["serde", "v4"] }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
# For documentation on how to configure this file,
 | 
					# For documentation on how to configure this file,
 | 
				
			||||||
# see diesel.rs/guides/configuring-diesel-cli
 | 
					# see postgres/guides/configuring-diesel-cli
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[print_schema]
 | 
					[print_schema]
 | 
				
			||||||
file = "src/schema.rs"
 | 
					file = "src/schema.rs"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,17 +1,19 @@
 | 
				
			|||||||
use rocket::{Rocket, response::status, http::{Status, Cookies, Cookie}};
 | 
					use std::ops::DerefMut;
 | 
				
			||||||
use rocket_contrib::json::Json;
 | 
					 | 
				
			||||||
use crate::core::paste::{entity::Paste, diesel::create_paste};
 | 
					 | 
				
			||||||
use serde_json::Value;
 | 
					 | 
				
			||||||
use crate::utils::{db, phonetic_key};
 | 
					 | 
				
			||||||
use std::ops::{DerefMut};
 | 
					 | 
				
			||||||
use rocket::response::status::Custom;
 | 
					 | 
				
			||||||
use crate::utils::phonetic_key::get_random_id;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use rocket::{http::{Cookie, Cookies, Status}, response::status, Rocket};
 | 
				
			||||||
 | 
					use rocket::response::status::Custom;
 | 
				
			||||||
 | 
					use rocket_contrib::json::Json;
 | 
				
			||||||
 | 
					use serde_json::Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::core::paste::{entity::Paste, service::create_paste};
 | 
				
			||||||
 | 
					use crate::core::users::{service::create_or_fetch_user};
 | 
				
			||||||
 | 
					use crate::utils::{db, phonetic_key};
 | 
				
			||||||
 | 
					use crate::utils::phonetic_key::get_random_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[post("/", data = "<paste>")]
 | 
					#[post("/", data = "<paste>")]
 | 
				
			||||||
fn create(mut paste: Json<Paste>, conn: db::DbConn, mut ck: Cookies) -> Custom<Json<Value>> {
 | 
					fn create(mut paste: Json<Paste>, conn: db::DbConn, mut ck: Cookies) -> Custom<Json<Value>> {
 | 
				
			||||||
    // Check if frontend sent a session cookie
 | 
					    // Check if frontend sent a session cookie
 | 
				
			||||||
    let session = match ck.get_private("session") {
 | 
					    let user_id = match ck.get_private("session") {
 | 
				
			||||||
        Some(c) => c.value().to_string(),
 | 
					        Some(c) => c.value().to_string(),
 | 
				
			||||||
        None => {
 | 
					        None => {
 | 
				
			||||||
            let user_id = get_random_id();
 | 
					            let user_id = get_random_id();
 | 
				
			||||||
@ -20,11 +22,22 @@ fn create(mut paste: Json<Paste>, conn: db::DbConn, mut ck: Cookies) -> Custom<J
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create or fetch already existing user
 | 
				
			||||||
 | 
					    let user = match create_or_fetch_user(user_id, &conn) {
 | 
				
			||||||
 | 
					        Ok(user) => user,
 | 
				
			||||||
 | 
					        Err(e) => return status::Custom(Status::InternalServerError, Json(json!({
 | 
				
			||||||
 | 
					            "err": e.to_string(),
 | 
				
			||||||
 | 
					            "msg": "Failed to create or fetch user"
 | 
				
			||||||
 | 
					        })))
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let new_paste = paste.deref_mut();
 | 
					    let new_paste = paste.deref_mut();
 | 
				
			||||||
    if new_paste.id.is_none() {
 | 
					    if new_paste.id.is_none() {
 | 
				
			||||||
        new_paste.id = Some(phonetic_key::get_random_id());
 | 
					        new_paste.id = Some(phonetic_key::get_random_id());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    new_paste.belongs_to = Some(user.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    match create_paste(new_paste, &conn) {
 | 
					    match create_paste(new_paste, &conn) {
 | 
				
			||||||
        Ok(_) => {
 | 
					        Ok(_) => {
 | 
				
			||||||
            status::Custom(Status::Created, Json(json!({
 | 
					            status::Custom(Status::Created, Json(json!({
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ use crate::schema::pastes;
 | 
				
			|||||||
#[derive(AsChangeset, Serialize, Deserialize, Queryable, Insertable)]
 | 
					#[derive(AsChangeset, Serialize, Deserialize, Queryable, Insertable)]
 | 
				
			||||||
pub struct Paste {
 | 
					pub struct Paste {
 | 
				
			||||||
    pub id: Option<String>,
 | 
					    pub id: Option<String>,
 | 
				
			||||||
    pub belongs_to: String,
 | 
					    pub belongs_to: Option<String>,
 | 
				
			||||||
    pub is_url: bool,
 | 
					    pub is_url: bool,
 | 
				
			||||||
    pub content: String
 | 
					    pub content: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
pub mod entity;
 | 
					pub mod entity;
 | 
				
			||||||
pub mod repository;
 | 
					pub mod postgres;
 | 
				
			||||||
pub mod diesel;
 | 
					 | 
				
			||||||
pub mod service;
 | 
					pub mod service;
 | 
				
			||||||
@ -1,13 +1,14 @@
 | 
				
			|||||||
use diesel::{RunQueryDsl};
 | 
					use anyhow::Result;
 | 
				
			||||||
use diesel::pg::PgConnection;
 | 
					use diesel::pg::PgConnection;
 | 
				
			||||||
use diesel::result::Error;
 | 
					use diesel::RunQueryDsl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::schema::pastes;
 | 
					use crate::schema::pastes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::entity::Paste;
 | 
					use super::entity::Paste;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn create_paste(paste: &Paste, conn: &PgConnection) -> Result<usize, Error> {
 | 
					pub fn create_paste(paste: &Paste, conn: &PgConnection) -> Result<usize> {
 | 
				
			||||||
    diesel::insert_into(pastes::table)
 | 
					    let rows = diesel::insert_into(pastes::table)
 | 
				
			||||||
        .values(paste)
 | 
					        .values(paste)
 | 
				
			||||||
        .execute(conn)
 | 
					        .execute(conn)?;
 | 
				
			||||||
 | 
					    Ok(rows)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					use anyhow::Result;
 | 
				
			||||||
 | 
					use diesel::pg::PgConnection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::entity::Paste;
 | 
				
			||||||
 | 
					use super::postgres;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn create_paste(paste: &Paste, conn: &PgConnection) -> Result<usize> {
 | 
				
			||||||
 | 
					    postgres::create_paste(paste, conn)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					use crate::schema::users;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[table_name = "users"]
 | 
				
			||||||
 | 
					#[derive(AsChangeset, Serialize, Deserialize, Queryable, Insertable)]
 | 
				
			||||||
 | 
					pub struct User {
 | 
				
			||||||
 | 
					    pub id: String,
 | 
				
			||||||
 | 
					    pub username: Option<String>,
 | 
				
			||||||
 | 
					    pub password: Option<String>,
 | 
				
			||||||
 | 
					    pub activated: Option<bool>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
pub mod diesel;
 | 
					pub mod postgres;
 | 
				
			||||||
pub mod entity;
 | 
					pub mod entity;
 | 
				
			||||||
pub mod repository;
 | 
					 | 
				
			||||||
pub mod service;
 | 
					pub mod service;
 | 
				
			||||||
							
								
								
									
										19
									
								
								src/core/users/postgres.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/core/users/postgres.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					use diesel::prelude::*;
 | 
				
			||||||
 | 
					use diesel::pg::PgConnection;
 | 
				
			||||||
 | 
					use anyhow::Result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::core::users::entity::User;
 | 
				
			||||||
 | 
					use crate::schema::users;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn create_user(user: &User, conn: &PgConnection) -> Result<usize> {
 | 
				
			||||||
 | 
					    let records = diesel::insert_into(users::table)
 | 
				
			||||||
 | 
					        .values(user)
 | 
				
			||||||
 | 
					        .on_conflict_do_nothing()
 | 
				
			||||||
 | 
					        .execute(conn)?;
 | 
				
			||||||
 | 
					    Ok(records)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn find_user(id: String, conn: &PgConnection) -> Result<User> {
 | 
				
			||||||
 | 
					    let user = users::table.find(id).get_result::<User>(conn)?;
 | 
				
			||||||
 | 
					    Ok(user)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					use anyhow::Result;
 | 
				
			||||||
 | 
					use bcrypt::{DEFAULT_COST, hash};
 | 
				
			||||||
 | 
					use diesel::pg::PgConnection;
 | 
				
			||||||
 | 
					use diesel::result::Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::core::users::entity::User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::postgres;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn create_user(user: &mut User, conn: &PgConnection) -> Result<usize> {
 | 
				
			||||||
 | 
					    let hashed_pass = hash(user.password.as_ref().unwrap().as_bytes(), DEFAULT_COST)?;
 | 
				
			||||||
 | 
					    user.password = Some(hashed_pass);
 | 
				
			||||||
 | 
					    postgres::create_user(user, conn)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn create_or_fetch_user(id: String, conn: &PgConnection) -> Result<User> {
 | 
				
			||||||
 | 
					    let user = match postgres::find_user(id.clone(), conn) {
 | 
				
			||||||
 | 
					        Ok(user) => user,
 | 
				
			||||||
 | 
					        Err(err) => {
 | 
				
			||||||
 | 
					            match err.downcast_ref::<Error>() {
 | 
				
			||||||
 | 
					                Some(Error::NotFound) => {
 | 
				
			||||||
 | 
					                    let new_user = User {
 | 
				
			||||||
 | 
					                        id: id.clone(),
 | 
				
			||||||
 | 
					                        username: None,
 | 
				
			||||||
 | 
					                        password: None,
 | 
				
			||||||
 | 
					                        activated: Some(false),
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    postgres::create_user(&new_user, conn)?;
 | 
				
			||||||
 | 
					                    new_user
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                _ => return Err(err)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Ok(user)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user