3

I have the following login POST endpoint handler in my Rocket API:

#[post("/login", data = "<login_form>")]
pub fn login_validate(login_form: Form<LoginForm>) -> Result<Redirect, Template> {
    let user = get_user(&login_form.username).unwrap();
    match user {
        Some(existing_user) => if verify(&login_form.password, &existing_user.password_hash).unwrap() {
            return Ok(Redirect::to(uri!(home)))
        },
        // we now hash (without verifying) just to ensure that the timing is the same
        None => {
            hash(&login_form.password, DEFAULT_COST);
        },
    };
    let mut response = Template::render("login", &LoginContext {
        error: Some(String::from("Invalid username or password!")),
    });
    // TODO: <<<<<<<<<< HOW CAN I SET AN HTTP STATUS CODE TO THE RESPONSE?
    Err(response)
}

I am trying to set the HTTP status response code, but I can't find the correct method to do it? It would be good to notify the browser that the login was not successful with something other than a 200.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
Daniel Gray
  • 1,697
  • 1
  • 21
  • 41

1 Answers1

5

From the Template docs (specifically the Responder trait):

Returns a response with the Content-Type derived from the template's extension and a fixed-size body containing the rendered template. If rendering fails, an Err of Status::InternalServerError is returned.

Try making a new Error enum that derives the Responder trait. Instead of returning Result<Redirect, Template>, return Result<Redirect, Error> where Error looks like this:

#[derive(Debug, Responder)]
enum Error {
    #[response(status = 400)]
    BadRequest(Template),
    #[response(status = 404)]
    NotFound(Template),
}
vallentin
  • 23,478
  • 6
  • 59
  • 81
Joey Kilpatrick
  • 1,394
  • 8
  • 20