1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2024-11-22 18:51:08 +00:00

Use auth header

This commit is contained in:
Felix Ableitner 2024-11-14 11:27:55 +01:00
parent d9020a15d4
commit 66f89d3bfd
22 changed files with 61 additions and 77 deletions

View file

@ -12,20 +12,12 @@ use crate::{
search_article, search_article,
}, },
instance::{follow_instance, get_instance, resolve_instance}, instance::{follow_instance, get_instance, resolve_instance},
user::{ user::{get_user, login_user, logout_user, my_profile, register_user, validate},
get_user,
login_user,
logout_user,
my_profile,
register_user,
validate,
AUTH_COOKIE,
},
}, },
database::IbisData, database::IbisData,
error::MyResult, error::MyResult,
}, },
common::LocalUserView, common::{LocalUserView, AUTH_COOKIE},
}; };
use activitypub_federation::config::Data; use activitypub_federation::config::Data;
use anyhow::anyhow; use anyhow::anyhow;
@ -78,8 +70,15 @@ async fn auth(
mut request: Request<Body>, mut request: Request<Body>,
next: Next, next: Next,
) -> Result<Response, StatusCode> { ) -> Result<Response, StatusCode> {
if let Some(auth) = jar.get(AUTH_COOKIE) { let auth = request
if let Ok(user) = validate(auth.value(), &data).await { .headers()
.get(AUTH_COOKIE)
.map(|h| h.to_str().ok())
.flatten()
.or(jar.get(AUTH_COOKIE).map(|c| c.value()));
if let Some(auth) = auth {
if let Ok(user) = validate(auth, &data).await {
request.extensions_mut().insert(user); request.extensions_mut().insert(user);
} }
} }

View file

@ -12,6 +12,7 @@ use crate::{
LoginUserForm, LoginUserForm,
Notification, Notification,
RegisterUserForm, RegisterUserForm,
AUTH_COOKIE,
}, },
}; };
use activitypub_federation::config::Data; use activitypub_federation::config::Data;
@ -34,8 +35,6 @@ use jsonwebtoken::{
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use time::{Duration, OffsetDateTime}; use time::{Duration, OffsetDateTime};
pub static AUTH_COOKIE: &str = "auth";
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Claims { struct Claims {
/// person.username /// person.username

View file

@ -13,6 +13,7 @@ use crate::{
DbInstance, DbInstance,
DbPerson, DbPerson,
EditVersion, EditVersion,
AUTH_COOKIE,
MAIN_PAGE_NAME, MAIN_PAGE_NAME,
}, },
frontend::app::App, frontend::app::App,
@ -22,7 +23,7 @@ use activitypub_federation::{
fetch::object_id::ObjectId, fetch::object_id::ObjectId,
http_signatures::generate_actor_keypair, http_signatures::generate_actor_keypair,
}; };
use api::{api_routes, user::AUTH_COOKIE}; use api::api_routes;
use assets::file_and_error_handler; use assets::file_and_error_handler;
use axum::{ use axum::{
body::Body, body::Body,

View file

@ -21,6 +21,8 @@ use {
pub const MAIN_PAGE_NAME: &str = "Main_Page"; pub const MAIN_PAGE_NAME: &str = "Main_Page";
pub static AUTH_COOKIE: &str = "auth";
#[derive(Clone)] #[derive(Clone)]
pub struct Auth(pub Option<String>); pub struct Auth(pub Option<String>);

View file

@ -1,5 +1,3 @@
use std::sync::LazyLock;
use crate::{ use crate::{
common::{ common::{
newtypes::ArticleId, newtypes::ArticleId,
@ -32,11 +30,10 @@ use crate::{
use anyhow::anyhow; use anyhow::anyhow;
use reqwest::{Client, RequestBuilder, StatusCode}; use reqwest::{Client, RequestBuilder, StatusCode};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::LazyLock;
use url::Url; use url::Url;
pub static CLIENT: LazyLock<ApiClient> = LazyLock::new(|| { pub static CLIENT: LazyLock<ApiClient> = LazyLock::new(|| ApiClient::new(Client::new(), None));
ApiClient::new(Client::new(), None)
});
#[derive(Clone)] #[derive(Clone)]
pub struct ApiClient { pub struct ApiClient {
@ -276,13 +273,13 @@ where
#[cfg(feature = "ssr")] #[cfg(feature = "ssr")]
{ {
use crate::common::Auth; use crate::common::{Auth, AUTH_COOKIE};
use leptos::use_context; use leptos::use_context;
use reqwest::header::HeaderName; use reqwest::header::HeaderName;
let auth = use_context::<Auth>(); let auth = use_context::<Auth>();
if let Some(Auth(Some(auth))) = auth { if let Some(Auth(Some(auth))) = auth {
req = req.header(HeaderName::from_static("auth"), auth); req = req.header(HeaderName::from_static(AUTH_COOKIE), auth);
} }
} }
let res = req.send().await?; let res = req.send().await?;

View file

@ -1,6 +1,7 @@
use crate::{ use crate::{
common::LocalUserView, common::LocalUserView,
frontend::{ frontend::{
api::CLIENT,
components::nav::Nav, components::nav::Nav,
dark_mode::DarkMode, dark_mode::DarkMode,
pages::{ pages::{
@ -38,7 +39,6 @@ use leptos::{
}; };
use leptos_meta::{provide_meta_context, *}; use leptos_meta::{provide_meta_context, *};
use leptos_router::{Route, Router, Routes}; use leptos_router::{Route, Router, Routes};
use crate::frontend::api::CLIENT;
// https://book.leptos.dev/15_global_state.html // https://book.leptos.dev/15_global_state.html
#[derive(Clone)] #[derive(Clone)]
@ -47,7 +47,6 @@ pub struct GlobalState {
} }
impl GlobalState { impl GlobalState {
pub fn update_my_profile() { pub fn update_my_profile() {
create_local_resource( create_local_resource(
move || (), move || (),
@ -74,9 +73,7 @@ impl GlobalState {
#[component] #[component]
pub fn App() -> impl IntoView { pub fn App() -> impl IntoView {
provide_meta_context(); provide_meta_context();
let global_state = GlobalState { let global_state = GlobalState { my_profile: None };
my_profile: None,
};
// Load user profile in case we are already logged in // Load user profile in case we are already logged in
GlobalState::update_my_profile(); GlobalState::update_my_profile();
provide_context(create_rw_signal(global_state)); provide_context(create_rw_signal(global_state));

View file

@ -1,12 +1,13 @@
use crate::{ use crate::{
common::{validation::can_edit_article, ArticleView, GetInstance}, common::{validation::can_edit_article, ArticleView, GetInstance},
frontend::{ frontend::{
api::CLIENT,
app::GlobalState, app::GlobalState,
article_link, article_link,
article_title, article_title,
components::instance_follow_button::InstanceFollowButton, components::instance_follow_button::InstanceFollowButton,
}, },
};use crate::frontend::api::CLIENT; };
use leptos::*; use leptos::*;
use leptos_router::*; use leptos_router::*;

View file

@ -1,5 +1,6 @@
use crate::frontend::api::CLIENT;
use leptos::{component, *}; use leptos::{component, *};
use url::Url;use crate::frontend::api::CLIENT; use url::Url;
#[component] #[component]
pub fn ConnectView<T: Clone + 'static, R: 'static>(res: Resource<T, R>) -> impl IntoView { pub fn ConnectView<T: Clone + 'static, R: 'static>(res: Resource<T, R>) -> impl IntoView {

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
common::{newtypes::InstanceId, DbInstance, FollowInstance}, common::{newtypes::InstanceId, DbInstance, FollowInstance},
frontend::app::GlobalState, frontend::{api::CLIENT, app::GlobalState},
};use crate::frontend::api::CLIENT; };
use leptos::{component, *}; use leptos::{component, *};
#[component] #[component]
@ -11,10 +11,7 @@ pub fn InstanceFollowButton(instance: DbInstance) -> impl IntoView {
let instance_id = *instance_id; let instance_id = *instance_id;
async move { async move {
let form = FollowInstance { id: instance_id }; let form = FollowInstance { id: instance_id };
CLIENT CLIENT.follow_instance(form).await.unwrap();
.follow_instance(form)
.await
.unwrap();
GlobalState::update_my_profile(); GlobalState::update_my_profile();
} }
}); });

View file

@ -1,6 +1,6 @@
use crate::frontend::{app::GlobalState, dark_mode::DarkMode}; use crate::frontend::{api::CLIENT, app::GlobalState, dark_mode::DarkMode};
use leptos::{component, use_context, view, IntoView, RwSignal, SignalWith, *}; use leptos::{component, use_context, view, IntoView, RwSignal, SignalWith, *};
use leptos_router::*;use crate::frontend::api::CLIENT; use leptos_router::*;
#[component] #[component]
pub fn Nav() -> impl IntoView { pub fn Nav() -> impl IntoView {
@ -21,12 +21,7 @@ pub fn Nav() -> impl IntoView {
); );
let notification_count = create_resource( let notification_count = create_resource(
|| (), || (),
move |_| async move { move |_| async move { CLIENT.notifications_count().await.unwrap_or_default() },
CLIENT
.notifications_count()
.await
.unwrap_or_default()
},
); );
let (search_query, set_search_query) = create_signal(String::new()); let (search_query, set_search_query) = create_signal(String::new());

View file

@ -1,13 +1,14 @@
use crate::{ use crate::{
common::{newtypes::ArticleId, ForkArticleForm, ProtectArticleForm}, common::{newtypes::ArticleId, ForkArticleForm, ProtectArticleForm},
frontend::{ frontend::{
api::CLIENT,
app::GlobalState, app::GlobalState,
article_link, article_link,
components::article_nav::{ActiveTab, ArticleNav}, components::article_nav::{ActiveTab, ArticleNav},
pages::article_resource, pages::article_resource,
DbArticle, DbArticle,
}, },
};use crate::frontend::api::CLIENT; };
use leptos::*; use leptos::*;
use leptos_router::Redirect; use leptos_router::Redirect;

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
common::CreateArticleForm, common::CreateArticleForm,
frontend::components::editor::EditorView, frontend::{api::CLIENT, components::editor::EditorView},
};use crate::frontend::api::CLIENT; };
use html::Textarea; use html::Textarea;
use leptos::*; use leptos::*;
use leptos_router::Redirect; use leptos_router::Redirect;

View file

@ -1,13 +1,14 @@
use crate::{ use crate::{
common::{newtypes::ConflictId, ApiConflict, ArticleView, EditArticleForm, Notification}, common::{newtypes::ConflictId, ApiConflict, ArticleView, EditArticleForm, Notification},
frontend::{ frontend::{
api::CLIENT,
components::{ components::{
article_nav::{ActiveTab, ArticleNav}, article_nav::{ActiveTab, ArticleNav},
editor::EditorView, editor::EditorView,
}, },
pages::article_resource, pages::article_resource,
}, },
};use crate::frontend::api::CLIENT; };
use html::Textarea; use html::Textarea;
use leptos::*; use leptos::*;
use leptos_router::use_params_map; use leptos_router::use_params_map;
@ -89,9 +90,7 @@ pub fn EditArticle() -> impl IntoView {
resolve_conflict_id, resolve_conflict_id,
}; };
set_wait_for_response.update(|w| *w = true); set_wait_for_response.update(|w| *w = true);
let res = CLIENT let res = CLIENT.edit_article_with_conflict(&form).await;
.edit_article_with_conflict(&form)
.await;
set_wait_for_response.update(|w| *w = false); set_wait_for_response.update(|w| *w = false);
match res { match res {
Ok(Some(conflict)) => { Ok(Some(conflict)) => {

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
common::ListArticlesForm, common::ListArticlesForm,
frontend::{article_link, article_title, components::connect::ConnectView}, frontend::{api::CLIENT, article_link, article_title, components::connect::ConnectView},
};use crate::frontend::api::CLIENT; };
use html::Input; use html::Input;
use leptos::*; use leptos::*;

View file

@ -1,11 +1,12 @@
use crate::{ use crate::{
common::{utils::http_protocol_str, DbInstance, ListArticlesForm}, common::{utils::http_protocol_str, DbInstance, ListArticlesForm},
frontend::{ frontend::{
api::CLIENT,
article_link, article_link,
article_title, article_title,
components::instance_follow_button::InstanceFollowButton, components::instance_follow_button::InstanceFollowButton,
}, },
};use crate::frontend::api::CLIENT; };
use leptos::*; use leptos::*;
use leptos_router::use_params_map; use leptos_router::use_params_map;
use url::Url; use url::Url;
@ -16,10 +17,7 @@ pub fn InstanceDetails() -> impl IntoView {
let hostname = move || params.get().get("hostname").cloned().unwrap(); let hostname = move || params.get().get("hostname").cloned().unwrap();
let instance_profile = create_resource(hostname, move |hostname| async move { let instance_profile = create_resource(hostname, move |hostname| async move {
let url = Url::parse(&format!("{}://{hostname}", http_protocol_str())).unwrap(); let url = Url::parse(&format!("{}://{hostname}", http_protocol_str())).unwrap();
CLIENT CLIENT.resolve_instance(url).await.unwrap()
.resolve_instance(url)
.await
.unwrap()
}); });
view! { view! {

View file

@ -1,5 +1,5 @@
use crate::frontend::components::connect::ConnectView; use crate::frontend::{api::CLIENT, components::connect::ConnectView};
use leptos::*;use crate::frontend::api::CLIENT; use leptos::*;
#[component] #[component]
pub fn ListInstances() -> impl IntoView { pub fn ListInstances() -> impl IntoView {

View file

@ -1,8 +1,8 @@
use crate::{ use crate::{
common::LoginUserForm, common::LoginUserForm,
frontend::{app::GlobalState, components::credentials::*}, frontend::{api::CLIENT, app::GlobalState, components::credentials::*},
}; };
use leptos::*;use crate::frontend::api::CLIENT; use leptos::*;
use leptos_router::Redirect; use leptos_router::Redirect;
#[component] #[component]

View file

@ -1,6 +1,9 @@
use crate::common::{ArticleView, GetArticleForm, MAIN_PAGE_NAME}; use crate::{
common::{ArticleView, GetArticleForm, MAIN_PAGE_NAME},
frontend::api::CLIENT,
};
use leptos::{create_resource, Resource, SignalGet}; use leptos::{create_resource, Resource, SignalGet};
use leptos_router::use_params_map;use crate::frontend::api::CLIENT; use leptos_router::use_params_map;
pub(crate) mod article; pub(crate) mod article;
pub(crate) mod diff; pub(crate) mod diff;

View file

@ -8,12 +8,7 @@ use leptos::*;
pub fn Notifications() -> impl IntoView { pub fn Notifications() -> impl IntoView {
let notifications = create_local_resource( let notifications = create_local_resource(
move || {}, move || {},
|_| async move { |_| async move { CLIENT.notifications_list().await.unwrap() },
CLIENT
.notifications_list()
.await
.unwrap()
},
); );
view! { view! {

View file

@ -1,8 +1,8 @@
use crate::{ use crate::{
common::{LocalUserView, RegisterUserForm}, common::{LocalUserView, RegisterUserForm},
frontend::{app::GlobalState, components::credentials::*, error::MyResult}, frontend::{api::CLIENT, app::GlobalState, components::credentials::*, error::MyResult},
}; };
use leptos::{logging::log, *};use crate::frontend::api::CLIENT; use leptos::{logging::log, *};
#[component] #[component]
pub fn Register() -> impl IntoView { pub fn Register() -> impl IntoView {
@ -17,8 +17,7 @@ pub fn Register() -> impl IntoView {
log!("Try to register new account for {}", credentials.username); log!("Try to register new account for {}", credentials.username);
async move { async move {
set_wait_for_response.update(|w| *w = true); set_wait_for_response.update(|w| *w = true);
let result: MyResult<LocalUserView> = let result: MyResult<LocalUserView> = CLIENT.register(credentials).await;
CLIENT.register(credentials).await;
set_wait_for_response.update(|w| *w = false); set_wait_for_response.update(|w| *w = false);
match result { match result {
Ok(res) => { Ok(res) => {

View file

@ -1,11 +1,11 @@
use crate::{ use crate::{
common::{DbArticle, DbInstance, SearchArticleForm}, common::{DbArticle, DbInstance, SearchArticleForm},
frontend::{article_link, article_title}, frontend::{api::CLIENT, article_link, article_title},
}; };
use leptos::*; use leptos::*;
use leptos_router::use_query_map; use leptos_router::use_query_map;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use url::Url;use crate::frontend::api::CLIENT; use url::Url;
#[derive(Default, Clone, Deserialize, Serialize, Debug)] #[derive(Default, Clone, Deserialize, Serialize, Debug)]
struct SearchResults { struct SearchResults {

View file

@ -1,9 +1,9 @@
use crate::{ use crate::{
common::{DbPerson, GetUserForm}, common::{DbPerson, GetUserForm},
frontend::user_title, frontend::{api::CLIENT, user_title},
}; };
use leptos::*; use leptos::*;
use leptos_router::use_params_map;use crate::frontend::api::CLIENT; use leptos_router::use_params_map;
#[component] #[component]
pub fn UserProfile() -> impl IntoView { pub fn UserProfile() -> impl IntoView {