admin pages
Pages can now be locked behind admin privileges
This commit is contained in:
@@ -5,22 +5,27 @@ use yew_router::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct AuthState {
|
||||
pub is_authenticated: bool,
|
||||
pub is_authenticated: Option<bool>,
|
||||
pub is_admin: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct ProtectedRouteProps {
|
||||
pub children: Children,
|
||||
pub admin_page: bool,
|
||||
}
|
||||
|
||||
#[component(ProtectedRoute)]
|
||||
pub fn protected_route(props: &ProtectedRouteProps) -> Html {
|
||||
let is_authenticated = use_state(|| None::<bool>);
|
||||
let auth_state = use_state(|| AuthState {
|
||||
is_authenticated: None,
|
||||
is_admin: None,
|
||||
});
|
||||
|
||||
{
|
||||
let is_authenticated = is_authenticated.clone();
|
||||
let auth_state = auth_state.clone();
|
||||
use_effect_with((), move |_| {
|
||||
let is_authenticated = is_authenticated.clone();
|
||||
let auth_state = auth_state.clone();
|
||||
spawn_local(async move {
|
||||
match Request::get("/api/users/current")
|
||||
.credentials(web_sys::RequestCredentials::Include)
|
||||
@@ -31,14 +36,27 @@ pub fn protected_route(props: &ProtectedRouteProps) -> Html {
|
||||
let status = resp.status();
|
||||
web_sys::console::log_1(&format!("Auth check: status {}", status).into());
|
||||
if status == 200 {
|
||||
is_authenticated.set(Some(true));
|
||||
let user_data: serde_json::Value =
|
||||
resp.json().await.unwrap_or_default();
|
||||
let is_admin = user_data["data"]["is_admin"].as_bool();
|
||||
|
||||
auth_state.set(AuthState {
|
||||
is_authenticated: Some(true),
|
||||
is_admin,
|
||||
});
|
||||
} else {
|
||||
is_authenticated.set(Some(false));
|
||||
auth_state.set(AuthState {
|
||||
is_authenticated: Some(false),
|
||||
is_admin: Some(false),
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
web_sys::console::log_1(&format!("Auth check error: {:?}", err).into());
|
||||
is_authenticated.set(Some(false));
|
||||
auth_state.set(AuthState {
|
||||
is_authenticated: Some(false),
|
||||
is_admin: Some(false),
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -46,13 +64,33 @@ pub fn protected_route(props: &ProtectedRouteProps) -> Html {
|
||||
});
|
||||
}
|
||||
|
||||
match *is_authenticated {
|
||||
None => html! { <div>{"Loading..."}</div> },
|
||||
Some(true) => props.children.clone().into(),
|
||||
Some(false) => {
|
||||
html! {
|
||||
<Redirect<crate::Route> to={crate::Route::Login} />
|
||||
match (*auth_state) {
|
||||
AuthState {
|
||||
is_authenticated: None,
|
||||
..
|
||||
} => html! { <div>{ "Loading..." } </div> },
|
||||
AuthState {
|
||||
is_authenticated: Some(false),
|
||||
..
|
||||
} => html! {
|
||||
<Redirect<crate::Route> to={crate::Route::Login}/>
|
||||
},
|
||||
AuthState {
|
||||
is_authenticated: Some(true),
|
||||
is_admin: admin_flag,
|
||||
} => {
|
||||
if props.admin_page {
|
||||
match admin_flag {
|
||||
Some(true) => props.children.clone().into(),
|
||||
Some(false) => {
|
||||
html! { <Redirect<crate::Route> to={crate::Route::PermissionDenied}/> }
|
||||
}
|
||||
None => html! { <div>{ "Checking permissions..." }</div> },
|
||||
}
|
||||
} else {
|
||||
props.children.clone().into()
|
||||
}
|
||||
}
|
||||
_ => html! { <div>{ "Checking permissions..." }</div> },
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user