From a778d590f872b6aac2166edfafaeece12454a5f8 Mon Sep 17 00:00:00 2001 From: Nettika Date: Sun, 25 Jan 2026 15:43:59 -0800 Subject: [PATCH] Implement login form --- TODO.md | 2 +- src/main.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/TODO.md b/TODO.md index f45599e..7bbbca4 100644 --- a/TODO.md +++ b/TODO.md @@ -11,7 +11,7 @@ [x] Create a `POST /projects` endpoint that accepts URL encoded data and creates a new project. [x] Create a `GET /new-project` endpoint that returns a HTML page with a project creation form. Keep it simple. [x] Add .env file support using the dotenv crate. Load environment variables on server startup. -[ ] Create a `GET /login` endpoint that returns a simple HTML login form (username and password fields). +[x] Create a `GET /login` endpoint that returns a simple HTML login form (username and password fields). [ ] Create a `POST /login` endpoint that validates credentials against USERNAME and PASSWORD environment variables. On success, set a session cookie. [ ] Implement session management. Create a simple in-memory session store that tracks authenticated sessions by cookie token. [ ] Add authentication middleware or helper function to check if a request has a valid session cookie. diff --git a/src/main.rs b/src/main.rs index f9ac956..1e2e044 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ fn main() { }, (GET) ["/projects"] => display_projects(), (GET) ["/new-project"] => new_project_form(), + (GET) ["/login"] => login_form(), (POST) ["/projects"] => create_project(request), _ => rouille::Response::empty_404() ) @@ -125,6 +126,33 @@ fn new_project_form() -> rouille::Response { rouille::Response::html(markup.into_string()) } +fn login_form() -> rouille::Response { + let markup = html! { + (DOCTYPE) + html { + head { + meta charset="utf-8"; + meta name="viewport" content="width=device-width, initial-scale=1"; + link rel="stylesheet" href="/main.css"; + } + body { + main { + h1 { "Login" } + form method="POST" action="/login" { + label for="username" { "Username:" } + input type="text" id="username" name="username" required; + label for="password" { "Password:" } + input type="password" id="password" name="password" required; + button type="submit" { "Login" } + } + } + } + } + }; + + rouille::Response::html(markup.into_string()) +} + fn create_project(request: &rouille::Request) -> rouille::Response { let input = try_or_400!(rouille::post_input!(request, { title: String,