Skip to content

Commit

Permalink
Merge pull request #42 from traP-jp/feat/#16-post-login
Browse files Browse the repository at this point in the history
POST /loginを実装
  • Loading branch information
kenken714 authored Oct 29, 2024
2 parents a2870a8 + bbd9476 commit c88dd90
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ mod users;
pub fn make_router(app_state: Repository) -> Router {
let authentication_router = Router::new()
.route("/signup/request", post(authentication::sign_up_request))
.route("/signup", post(authentication::sign_up));
.route("/signup", post(authentication::sign_up))
.route("/login", post(authentication::login));

let users_router = Router::new()
.route("/me", get(users::get_me).put(users::put_me))
Expand Down
53 changes: 51 additions & 2 deletions src/handler/authentication.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use axum::{extract::State, Json};
use axum::{extract::State, http::HeaderMap, response::IntoResponse, Json};
use lettre::Address;
use reqwest::StatusCode;
use reqwest::{header::SET_COOKIE, StatusCode};
use serde::Deserialize;

use crate::{
Expand Down Expand Up @@ -91,3 +91,52 @@ pub async fn sign_up(
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(StatusCode::CREATED)
}

#[derive(Deserialize)]
pub struct LogIn {
email: String,
password: String,
}

impl Validator for LogIn {
fn validate(&self) -> anyhow::Result<()> {
RuleType::Password.validate(&self.password)?;
Ok(())
}
}

pub async fn login(
State(state): State<Repository>,
Json(body): Json<LogIn>,
) -> Result<impl IntoResponse, StatusCode> {
body.validate().map_err(|_| StatusCode::BAD_REQUEST)?;
let user = state
.get_user_by_email(&body.email)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
.ok_or(StatusCode::UNAUTHORIZED)?;

let verification = state
.verify_user_password(user.id, &body.password)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

if !verification {
return Err(StatusCode::UNAUTHORIZED);
}

let session_id = state
.create_session(user)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

let mut headers = HeaderMap::new();
headers.insert(
SET_COOKIE,
format!("session_id={}; HttpOnly; SameSite=Lax", session_id)
.parse()
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?,
);

Ok((StatusCode::OK, headers))
}
9 changes: 9 additions & 0 deletions src/repository/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ impl Repository {
Ok(user)
}

pub async fn get_user_by_email(&self, email: &str) -> anyhow::Result<Option<User>> {
let user = sqlx::query_as::<_, User>("SELECT * FROM users WHERE email = ?")
.bind(email)
.fetch_optional(&self.pool)
.await?;

Ok(user)
}

pub async fn create_user_by_email(&self, name: &str, email: &str) -> anyhow::Result<UserId> {
let id = UserId::new(Uuid::now_v7());

Expand Down

0 comments on commit c88dd90

Please sign in to comment.