Skip to content

Commit

Permalink
add account related functions
Browse files Browse the repository at this point in the history
  • Loading branch information
weigo0510 committed Apr 17, 2024
1 parent 7440358 commit ccf4c70
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 0 deletions.
42 changes: 42 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ sqlx = { version = "0.7.4", features = [
tracing = { version = "0.1", features = ["log"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
reqwest = "0.12.3"
rand = "0.8"
rust-argon2 = "2.1"
2 changes: 2 additions & 0 deletions migrations/20240417084119_create_accounts_table.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- Add down migration script here
DROP TABLE IF EXISTS accounts;
6 changes: 6 additions & 0 deletions migrations/20240417084119_create_accounts_table.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- Add up migration script here
CREATE TABLE IF NOT EXISTS accounts (
id serial NOT NULL,
email VARCHAR(255) NOT NULL PRIMARY KEY,
password VARCHAR(255) NOT NULL
);
33 changes: 33 additions & 0 deletions src/handlers/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use argon2::Config;
use axum::{extract::State, Json};
use rand::Rng;
use tracing::{event, Level};

use crate::{common::error::Error, models::account::Account, repositories::store::Store};

pub async fn register(
State(store): State<Store>,
Json(account): Json<Account>,
) -> Result<String, Error> {
event!(target:"axum-web-dev", Level::INFO, "register new user");
let hashed_pwd = hash_passowrd(account.password.as_bytes());

let account = Account {
id: account.id,
email: account.email,
password: hashed_pwd,
};

let _res: Result<bool, Error> = match store.add_account(account).await {
Err(e) => return Err(e),
Ok(res) => Ok(res),
};

Ok(String::from("Success"))
}

pub fn hash_passowrd(password: &[u8]) -> String {
let salt = rand::thread_rng().gen::<[u8; 32]>();
let config = Config::default();
argon2::hash_encoded(password, &salt, &config).unwrap()
}
1 change: 1 addition & 0 deletions src/handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use axum::{response::IntoResponse, Json};

pub mod account;
pub mod answer;
pub mod question;

Expand Down
11 changes: 11 additions & 0 deletions src/models/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Account {
pub id: Option<AccountId>,
pub email: String,
pub password: String,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
pub struct AccountId(pub i32);
1 change: 1 addition & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::Deserialize;

pub mod account;
pub mod answer;
pub mod question;

Expand Down
30 changes: 30 additions & 0 deletions src/repositories/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use tracing::event;
use crate::{
common::error::Error,
models::{
account::Account,
answer::{Answer, AnswerId, NewAnswer},
question::{NewQuestion, Question, QuestionId},
},
Expand Down Expand Up @@ -167,4 +168,33 @@ impl Store {
}
}
}

pub async fn add_account(self, account: Account) -> Result<bool, Error> {
match sqlx::query("INSERT INTO accounts (email, password) VALUES($1, $2)")
.bind(account.email)
.bind(account.password)
.execute(&self.connection)
.await
{
Ok(_) => Ok(true),
Err(error) => {
let err_code = error
.as_database_error()
.unwrap()
.code()
.unwrap()
.parse::<i32>()
.unwrap();
let err_message = error.as_database_error().unwrap().message();
let err_constraint = error.as_database_error().unwrap().constraint().unwrap();
event!(
tracing::Level::ERROR,
code = err_code,
message = err_message,
constraint = err_constraint
);
Err(Error::DatabaseQueryError)
}
}
}
}
9 changes: 9 additions & 0 deletions src/routers/account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use axum::{routing::post, Router};

use crate::{handlers::account::register, repositories::store::Store};

pub fn create_router(store: Store) -> Router {
Router::new()
.route("/api/registration", post(register))
.with_state(store)
}
2 changes: 2 additions & 0 deletions src/routers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use tower_http::trace::TraceLayer;

use crate::{handlers::health_check_handler, repositories::store::Store};

pub mod account;
pub mod answer;
pub mod question;

Expand All @@ -14,5 +15,6 @@ pub fn create_router(store: Store) -> Router {
.route("/api/healthcheck", get(health_check_handler))
.merge(question::create_router(store.clone()))
.merge(answer::create_router(store.clone()))
.merge(account::create_router(store.clone()))
.layer(TraceLayer::new_for_http())
}

0 comments on commit ccf4c70

Please sign in to comment.