Create UserDao and unit tests for login
This commit is contained in:
78
src/auth.rs
78
src/auth.rs
@@ -1,19 +1,23 @@
|
||||
use actix_web::web::{HttpResponse, Json};
|
||||
use actix_web::web::{self, HttpResponse, Json};
|
||||
use actix_web::{post, Responder};
|
||||
use chrono::{Duration, Utc};
|
||||
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||
use log::{debug, error};
|
||||
|
||||
use crate::data::LoginRequest;
|
||||
use crate::data::{secret_key, Claims, CreateAccountRequest, Token};
|
||||
use crate::database::{create_user, get_user, user_exists};
|
||||
use crate::{
|
||||
data::{secret_key, Claims, CreateAccountRequest, LoginRequest, Token},
|
||||
database::UserDao,
|
||||
};
|
||||
|
||||
#[post("/register")]
|
||||
async fn register(user: Json<CreateAccountRequest>) -> impl Responder {
|
||||
async fn register(
|
||||
user: Json<CreateAccountRequest>,
|
||||
user_dao: web::Data<Box<dyn UserDao>>,
|
||||
) -> impl Responder {
|
||||
if !user.username.is_empty() && user.password.len() > 5 && user.password == user.confirmation {
|
||||
if user_exists(&user.username) {
|
||||
if user_dao.user_exists(&user.username) {
|
||||
HttpResponse::BadRequest()
|
||||
} else if let Some(_user) = create_user(&user.username, &user.password) {
|
||||
} else if let Some(_user) = user_dao.create_user(&user.username, &user.password) {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::InternalServerError()
|
||||
@@ -23,10 +27,12 @@ async fn register(user: Json<CreateAccountRequest>) -> impl Responder {
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/login")]
|
||||
async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
||||
pub async fn login(
|
||||
creds: Json<LoginRequest>,
|
||||
user_dao: web::Data<Box<dyn UserDao>>,
|
||||
) -> HttpResponse {
|
||||
debug!("Logging in: {}", creds.username);
|
||||
if let Some(user) = get_user(&creds.username, &creds.password) {
|
||||
if let Some(user) = user_dao.get_user(&creds.username, &creds.password) {
|
||||
let claims = Claims {
|
||||
sub: user.id.to_string(),
|
||||
exp: (Utc::now() + Duration::days(5)).timestamp(),
|
||||
@@ -43,3 +49,55 @@ async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::database::testhelpers::{BodyReader, TestUserDao};
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_login_reports_200_when_user_exists() {
|
||||
let dao = TestUserDao::new();
|
||||
dao.create_user("user", "pass");
|
||||
|
||||
let j = Json(LoginRequest {
|
||||
username: "user".to_string(),
|
||||
password: "pass".to_string(),
|
||||
});
|
||||
|
||||
let response = login(j, web::Data::new(Box::new(dao))).await;
|
||||
|
||||
assert_eq!(response.status(), 200);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_login_returns_token_on_success() {
|
||||
let dao = TestUserDao::new();
|
||||
dao.create_user("user", "password");
|
||||
|
||||
let j = Json(LoginRequest {
|
||||
username: "user".to_string(),
|
||||
password: "password".to_string(),
|
||||
});
|
||||
|
||||
let response = login(j, web::Data::new(Box::new(dao))).await;
|
||||
|
||||
assert_eq!(response.status(), 200);
|
||||
assert!(response.body().read_to_str().contains("\"token\""));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_login_reports_400_when_user_does_not_exist() {
|
||||
let dao = TestUserDao::new();
|
||||
dao.create_user("user", "password");
|
||||
|
||||
let j = Json(LoginRequest {
|
||||
username: "doesnotexist".to_string(),
|
||||
password: "password".to_string(),
|
||||
});
|
||||
|
||||
let response = login(j, web::Data::new(Box::new(dao))).await;
|
||||
|
||||
assert_eq!(response.status(), 404);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user