From 1d51343bc819ec19a593e224f61245b3b0f639b1 Mon Sep 17 00:00:00 2001 From: mrw1593 Date: Sun, 18 Jun 2023 18:56:38 -0400 Subject: error page --- src/api/oauth.rs | 79 +++++++++++++++++++++++++++++++++++++++------- src/resources/templates.rs | 32 +++++++++++++++++++ 2 files changed, 100 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/api/oauth.rs b/src/api/oauth.rs index de98e80..353f287 100644 --- a/src/api/oauth.rs +++ b/src/api/oauth.rs @@ -131,12 +131,18 @@ async fn authorize( db: web::Data, req: web::Query, credentials: web::Json, + tera: web::Data, + translations: web::Data, ) -> HttpResponse { // TODO use sessions to verify that the request was previously validated // TODO handle internal server error let db = db.get_ref(); let Some(client_id) = db::get_client_id_by_alias(db, &req.client_id).await.unwrap() else { - todo!("client not found") + // TODO find a better way of doing languages + let language = Language::from_str("en").unwrap(); + let translations = translations.get_ref().clone(); + let page = templates::error_page(&tera, language, translations, templates::ErrorPage::ClientNotFound).unwrap(); + return HttpResponse::NotFound().content_type("text/html").body(page); }; let self_id = Url::parse("www.google.com").unwrap(); // TODO find the actual value let state = req.state.clone(); @@ -147,7 +153,18 @@ async fn authorize( } else { let redirect_uris = db::get_client_redirect_uris(db, client_id).await.unwrap(); if redirect_uris.len() != 1 { - todo!("no redirect uri"); + let language = Language::from_str("en").unwrap(); + let translations = translations.get_ref().clone(); + let page = templates::error_page( + &tera, + language, + translations, + templates::ErrorPage::MissingRedirectUri, + ) + .unwrap(); + return HttpResponse::NotFound() + .content_type("text/html") + .body(page); } redirect_uris[0].clone() @@ -230,21 +247,44 @@ async fn authorize_page( translations: web::Data, request: HttpRequest, ) -> HttpResponse { + // TODO handle internal server error + let language = Language::from_str("en").unwrap(); + let translations = translations.get_ref().clone(); + let params = request.query_string(); let params = serde_urlencoded::from_str::(params); let Ok(params) = params else { - todo!("invalid request") + let page = templates::error_page( + &tera, + language, + translations, + templates::ErrorPage::InvalidRequest, + ) + .unwrap(); + return HttpResponse::BadRequest() + .content_type("text/html") + .body(page); }; let db = db.get_ref(); let Some(client_id) = db::get_client_id_by_alias(db, ¶ms.client_id).await.unwrap() else { - todo!("client not found") + let page = templates::error_page( + &tera, + language, + translations, + templates::ErrorPage::ClientNotFound, + ) + .unwrap(); + return HttpResponse::NotFound() + .content_type("text/html") + .body(page); }; // verify scope - let Some(allowed_scopes) = db::get_client_allowed_scopes(db, client_id).await.unwrap() else { - todo!("client not found") - }; + let allowed_scopes = db::get_client_allowed_scopes(db, client_id) + .await + .unwrap() + .unwrap(); // verify redirect uri let redirect_uri: Url; @@ -254,12 +294,30 @@ async fn authorize_page( .await .unwrap() { - todo!("access denied") + let page = templates::error_page( + &tera, + language, + translations, + templates::ErrorPage::InvalidRedirectUri, + ) + .unwrap(); + return HttpResponse::BadRequest() + .content_type("text/html") + .body(page); } } else { let redirect_uris = db::get_client_redirect_uris(db, client_id).await.unwrap(); if redirect_uris.len() != 1 { - todo!("must have redirect uri") + let page = templates::error_page( + &tera, + language, + translations, + templates::ErrorPage::MissingRedirectUri, + ) + .unwrap(); + return HttpResponse::NotFound() + .content_type("text/html") + .body(page); } redirect_uri = redirect_uris.get(0).unwrap().clone(); @@ -290,8 +348,7 @@ async fn authorize_page( // TODO find a better way of doing languages let language = Language::from_str("en").unwrap(); - let page = - templates::login_page(&tera, ¶ms, language, translations.get_ref().clone()).unwrap(); + let page = templates::login_page(&tera, ¶ms, language, translations).unwrap(); HttpResponse::Ok().content_type("text/html").body(page) } diff --git a/src/resources/templates.rs b/src/resources/templates.rs index 7578256..88c1fad 100644 --- a/src/resources/templates.rs +++ b/src/resources/templates.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use exun::{RawUnexpected, ResultErrorExt}; use raise::yeet; +use serde::Serialize; use tera::{Function, Tera, Value}; use unic_langid::subtags::Language; @@ -36,6 +37,37 @@ pub fn initialize() -> tera::Result { Ok(tera) } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum ErrorPage { + InvalidRequest, + ClientNotFound, + MissingRedirectUri, + InvalidRedirectUri, +} + +pub fn error_page( + tera: &Tera, + language: Language, + mut translations: languages::Translations, + error: ErrorPage, +) -> Result { + translations.refresh()?; + let mut tera = extend_tera(tera, language, translations)?; + tera.full_reload()?; + + let error = serde_variant::to_variant_name(&error)?; + let header = format!("errorHeader_{error}"); + let message = format!("errorMessage_{error}"); + + let mut context = tera::Context::new(); + context.insert("lang", language.as_str()); + context.insert("errorHeader", &header); + context.insert("errormessage", &message); + + tera.render("error.html", &context).unexpect() +} + pub fn login_page( tera: &Tera, params: &AuthorizationParameters, -- cgit v1.2.3