Admin login
Let's tackle the admin panel.
fn handle_admin(request: &Request, database: &Transaction,
sessions: &SessionsManager) -> Result<Response, RouteError>
{
...
}
The difference with the public part of the website is that only authorized users must have access to the admin panel.
We split the admin panel in three functions:
handle_admin_loggedin
that handles routes that are available if you are logged int.handle_admin_always_avail
that handles routes that are always available (like the login page).handle_admin
that handles authentication and dispatches to one of the other two functions.
struct SessionData {
user_id: i32
}
fn handle_admin(request: &Request, database: &Transaction,
sessions: &SessionsManager<SessionData>) -> Result<Response, RouteError>
{
if !request.url().starts_with("/admin") {
return Err(RouteError::NoRouteFound);
}
let session = sessions.start(request);
match handle_admin_always_avail(request, database, &session) {
Err(RouteError::NoRouteFound) => (),
resp => return resp
};
let auth_user_id = match session.get() {
Some(data) => data.user_id,
None => return Ok(Response::redirect("/admin/login")),
};
handle_admin_loggedin(request, database, auth_user_id)
.map(|response| session.apply(response))
}
fn handle_admin_always_avail(request: &Request, database: &Transaction,
session: &Session<SessionData>)
-> Result<Response, RouteError>
{
router!(request,
(GET) (/admin/login) => {
},
(POST) (/admin/login) => {
#[derive(RustcEncodable)]
struct FormData { login: String, password: String }
let data: FormData = match rouille::input::get_post_input() {
Ok(data) => data,
Err(_) => Ok(Response::redirect("/admin/login"))
};
let user_id = match authenticate(database, data.login, data.password) {
Ok(user_id) => user_id,
Err(_) => Ok(Response::redirect("/admin/login_failed"))
};
session.set(SessionData { user_id: user_id });
Ok(Response::redirect("/admin/login_success"));
},
_ => Err(RouteError::NoRouteFound)
)
}
fn handle_admin_loggedin(request: &Request, database: Transaction, auth_user_id: i32)
-> Result<Response, RouteError>
{
...
}