mirror of
https://github.com/nitnelave/lldap.git
synced 2023-04-12 14:25:13 +00:00
app: Implement login refresh
This commit is contained in:
parent
ebffc1c086
commit
b54fe9128d
@ -85,7 +85,7 @@ impl Component for App {
|
|||||||
}
|
}
|
||||||
if self.user_info.is_none() {
|
if self.user_info.is_none() {
|
||||||
self.route_dispatcher
|
self.route_dispatcher
|
||||||
.send(RouteRequest::ReplaceRoute(Route::new_no_state("/login")));
|
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ impl App {
|
|||||||
match &self.user_info {
|
match &self.user_info {
|
||||||
None => {
|
None => {
|
||||||
self.route_dispatcher
|
self.route_dispatcher
|
||||||
.send(RouteRequest::ReplaceRoute(Route::new_no_state("/login")));
|
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
|
||||||
}
|
}
|
||||||
Some((user_name, is_admin)) => match &self.redirect_to {
|
Some((user_name, is_admin)) => match &self.redirect_to {
|
||||||
Some(url) => {
|
Some(url) => {
|
||||||
@ -148,7 +148,7 @@ impl App {
|
|||||||
None => {
|
None => {
|
||||||
if *is_admin {
|
if *is_admin {
|
||||||
self.route_dispatcher
|
self.route_dispatcher
|
||||||
.send(RouteRequest::ReplaceRoute(Route::new_no_state("/users")));
|
.send(RouteRequest::ReplaceRoute(Route::from(AppRoute::ListUsers)));
|
||||||
} else {
|
} else {
|
||||||
self.route_dispatcher
|
self.route_dispatcher
|
||||||
.send(RouteRequest::ReplaceRoute(Route::from(
|
.send(RouteRequest::ReplaceRoute(Route::from(
|
||||||
|
@ -15,6 +15,7 @@ use yew_form_derive::Model;
|
|||||||
pub struct LoginForm {
|
pub struct LoginForm {
|
||||||
common: CommonComponentParts<Self>,
|
common: CommonComponentParts<Self>,
|
||||||
form: Form<FormModel>,
|
form: Form<FormModel>,
|
||||||
|
refreshing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The fields of the form, with the constraints.
|
/// The fields of the form, with the constraints.
|
||||||
@ -34,6 +35,7 @@ pub struct Props {
|
|||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
Update,
|
Update,
|
||||||
Submit,
|
Submit,
|
||||||
|
AuthenticationRefreshResponse(Result<(String, bool)>),
|
||||||
AuthenticationStartResponse(
|
AuthenticationStartResponse(
|
||||||
(
|
(
|
||||||
opaque::client::login::ClientLogin,
|
opaque::client::login::ClientLogin,
|
||||||
@ -99,6 +101,14 @@ impl CommonComponent<LoginForm> for LoginForm {
|
|||||||
.emit(user_info.context("Could not log in")?);
|
.emit(user_info.context("Could not log in")?);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
Msg::AuthenticationRefreshResponse(user_info) => {
|
||||||
|
self.refreshing = false;
|
||||||
|
self.common.cancel_task();
|
||||||
|
if let Ok(user_info) = user_info {
|
||||||
|
self.common.on_logged_in.emit(user_info);
|
||||||
|
}
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,10 +122,19 @@ impl Component for LoginForm {
|
|||||||
type Properties = Props;
|
type Properties = Props;
|
||||||
|
|
||||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||||
LoginForm {
|
let mut app = LoginForm {
|
||||||
common: CommonComponentParts::<Self>::create(props, link),
|
common: CommonComponentParts::<Self>::create(props, link),
|
||||||
form: Form::<FormModel>::new(FormModel::default()),
|
form: Form::<FormModel>::new(FormModel::default()),
|
||||||
|
refreshing: true,
|
||||||
|
};
|
||||||
|
if let Err(e) =
|
||||||
|
app.common
|
||||||
|
.call_backend(HostService::refresh, (), Msg::AuthenticationRefreshResponse)
|
||||||
|
{
|
||||||
|
ConsoleService::debug(&format!("Could not refresh auth: {}", e));
|
||||||
|
app.refreshing = false;
|
||||||
}
|
}
|
||||||
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
fn update(&mut self, msg: Self::Message) -> ShouldRender {
|
||||||
@ -128,6 +147,13 @@ impl Component for LoginForm {
|
|||||||
|
|
||||||
fn view(&self) -> Html {
|
fn view(&self) -> Html {
|
||||||
type Field = yew_form::Field<FormModel>;
|
type Field = yew_form::Field<FormModel>;
|
||||||
|
if self.refreshing {
|
||||||
|
html! {
|
||||||
|
<div>
|
||||||
|
<img src={"spinner.gif"} alt={"Loading"} />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
html! {
|
html! {
|
||||||
<form
|
<form
|
||||||
class="form center-block col-sm-4 col-offset-4">
|
class="form center-block col-sm-4 col-offset-4">
|
||||||
@ -187,4 +213,5 @@ impl Component for LoginForm {
|
|||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,32 @@ impl HostService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh(_request: (), callback: Callback<Result<(String, bool)>>) -> Result<FetchTask> {
|
||||||
|
let set_cookies = |jwt_claims: JWTClaims| {
|
||||||
|
let is_admin = jwt_claims.groups.contains("lldap_admin");
|
||||||
|
set_cookie("user_id", &jwt_claims.user, &jwt_claims.exp)
|
||||||
|
.map(|_| set_cookie("is_admin", &is_admin.to_string(), &jwt_claims.exp))
|
||||||
|
.map(|_| (jwt_claims.user.clone(), is_admin))
|
||||||
|
.context("Error clearing cookie")
|
||||||
|
};
|
||||||
|
let parse_token = move |data: String| {
|
||||||
|
serde_json::from_str::<login::ServerLoginResponse>(&data)
|
||||||
|
.context("Could not parse response")
|
||||||
|
.and_then(|r| {
|
||||||
|
get_claims_from_jwt(r.token.as_str())
|
||||||
|
.context("Could not parse response")
|
||||||
|
.and_then(set_cookies)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
call_server(
|
||||||
|
"/auth/refresh",
|
||||||
|
yew::format::Nothing,
|
||||||
|
callback,
|
||||||
|
"Could not start authentication: ",
|
||||||
|
parse_token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// The `_request` parameter is to make it the same shape as the other functions.
|
// The `_request` parameter is to make it the same shape as the other functions.
|
||||||
pub fn logout(_request: (), callback: Callback<Result<()>>) -> Result<FetchTask> {
|
pub fn logout(_request: (), callback: Callback<Result<()>>) -> Result<FetchTask> {
|
||||||
call_server_empty_response_with_error_message(
|
call_server_empty_response_with_error_message(
|
||||||
|
BIN
app/static/spinner.gif
Normal file
BIN
app/static/spinner.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
Loading…
Reference in New Issue
Block a user