mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	app: improve error message for wrong/expired reset token
This commit is contained in:
		
							parent
							
								
									a41d7a3bce
								
							
						
					
					
						commit
						837b574060
					
				@ -32,7 +32,7 @@ pub struct App {
 | 
				
			|||||||
    user_info: Option<(String, bool)>,
 | 
					    user_info: Option<(String, bool)>,
 | 
				
			||||||
    redirect_to: Option<AppRoute>,
 | 
					    redirect_to: Option<AppRoute>,
 | 
				
			||||||
    route_dispatcher: RouteAgentDispatcher,
 | 
					    route_dispatcher: RouteAgentDispatcher,
 | 
				
			||||||
    password_reset_enabled: bool,
 | 
					    password_reset_enabled: Option<bool>,
 | 
				
			||||||
    task: Option<FetchTask>,
 | 
					    task: Option<FetchTask>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,7 +64,7 @@ impl Component for App {
 | 
				
			|||||||
                }),
 | 
					                }),
 | 
				
			||||||
            redirect_to: Self::get_redirect_route(),
 | 
					            redirect_to: Self::get_redirect_route(),
 | 
				
			||||||
            route_dispatcher: RouteAgentDispatcher::new(),
 | 
					            route_dispatcher: RouteAgentDispatcher::new(),
 | 
				
			||||||
            password_reset_enabled: false,
 | 
					            password_reset_enabled: None,
 | 
				
			||||||
            task: None,
 | 
					            task: None,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        app.task = Some(
 | 
					        app.task = Some(
 | 
				
			||||||
@ -95,22 +95,21 @@ impl Component for App {
 | 
				
			|||||||
            Msg::Logout => {
 | 
					            Msg::Logout => {
 | 
				
			||||||
                self.user_info = None;
 | 
					                self.user_info = None;
 | 
				
			||||||
                self.redirect_to = None;
 | 
					                self.redirect_to = None;
 | 
				
			||||||
 | 
					                self.route_dispatcher
 | 
				
			||||||
 | 
					                    .send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Msg::PasswordResetProbeFinished(Ok(enabled)) => {
 | 
					            Msg::PasswordResetProbeFinished(Ok(enabled)) => {
 | 
				
			||||||
                self.task = None;
 | 
					                self.task = None;
 | 
				
			||||||
                self.password_reset_enabled = enabled;
 | 
					                self.password_reset_enabled = Some(enabled);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Msg::PasswordResetProbeFinished(Err(err)) => {
 | 
					            Msg::PasswordResetProbeFinished(Err(err)) => {
 | 
				
			||||||
                self.task = None;
 | 
					                self.task = None;
 | 
				
			||||||
 | 
					                self.password_reset_enabled = Some(false);
 | 
				
			||||||
                ConsoleService::error(&format!(
 | 
					                ConsoleService::error(&format!(
 | 
				
			||||||
                    "Could not probe for password reset support: {err:#}"
 | 
					                    "Could not probe for password reset support: {err:#}"
 | 
				
			||||||
                ));
 | 
					                ));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if self.user_info.is_none() {
 | 
					 | 
				
			||||||
            self.route_dispatcher
 | 
					 | 
				
			||||||
                .send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        true
 | 
					        true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -160,7 +159,7 @@ impl App {
 | 
				
			|||||||
        let route_service = RouteService::<()>::new();
 | 
					        let route_service = RouteService::<()>::new();
 | 
				
			||||||
        let current_route = route_service.get_path();
 | 
					        let current_route = route_service.get_path();
 | 
				
			||||||
        if current_route.contains("reset-password") {
 | 
					        if current_route.contains("reset-password") {
 | 
				
			||||||
            if !self.password_reset_enabled {
 | 
					            if self.password_reset_enabled == Some(false) {
 | 
				
			||||||
                self.route_dispatcher
 | 
					                self.route_dispatcher
 | 
				
			||||||
                    .send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
 | 
					                    .send(RouteRequest::ReplaceRoute(Route::from(AppRoute::Login)));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -195,11 +194,11 @@ impl App {
 | 
				
			|||||||
        switch: AppRoute,
 | 
					        switch: AppRoute,
 | 
				
			||||||
        link: &ComponentLink<Self>,
 | 
					        link: &ComponentLink<Self>,
 | 
				
			||||||
        is_admin: bool,
 | 
					        is_admin: bool,
 | 
				
			||||||
        password_reset_enabled: bool,
 | 
					        password_reset_enabled: Option<bool>,
 | 
				
			||||||
    ) -> Html {
 | 
					    ) -> Html {
 | 
				
			||||||
        match switch {
 | 
					        match switch {
 | 
				
			||||||
            AppRoute::Login => html! {
 | 
					            AppRoute::Login => html! {
 | 
				
			||||||
                <LoginForm on_logged_in=link.callback(Msg::Login) password_reset_enabled=password_reset_enabled/>
 | 
					                <LoginForm on_logged_in=link.callback(Msg::Login) password_reset_enabled=password_reset_enabled.unwrap_or(false)/>
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            AppRoute::CreateUser => html! {
 | 
					            AppRoute::CreateUser => html! {
 | 
				
			||||||
                <CreateUserForm/>
 | 
					                <CreateUserForm/>
 | 
				
			||||||
@ -234,23 +233,20 @@ impl App {
 | 
				
			|||||||
            AppRoute::ChangePassword(username) => html! {
 | 
					            AppRoute::ChangePassword(username) => html! {
 | 
				
			||||||
                <ChangePasswordForm username=username is_admin=is_admin />
 | 
					                <ChangePasswordForm username=username is_admin=is_admin />
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            AppRoute::StartResetPassword => {
 | 
					            AppRoute::StartResetPassword => match password_reset_enabled {
 | 
				
			||||||
                if password_reset_enabled {
 | 
					                Some(true) => html! { <ResetPasswordStep1Form /> },
 | 
				
			||||||
                    html! {
 | 
					                Some(false) => {
 | 
				
			||||||
                      <ResetPasswordStep1Form />
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
 | 
					                    App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					
 | 
				
			||||||
            AppRoute::FinishResetPassword(token) => html! {
 | 
					                None => html! {},
 | 
				
			||||||
                if password_reset_enabled {
 | 
					            },
 | 
				
			||||||
                    html! {
 | 
					            AppRoute::FinishResetPassword(token) => match password_reset_enabled {
 | 
				
			||||||
                      <ResetPasswordStep2Form token=token />
 | 
					                Some(true) => html! { <ResetPasswordStep2Form token=token /> },
 | 
				
			||||||
                    }
 | 
					                Some(false) => {
 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
 | 
					                    App::dispatch_route(AppRoute::Login, link, is_admin, password_reset_enabled)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                None => html! {},
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -287,6 +283,9 @@ impl App {
 | 
				
			|||||||
                  } } else { html!{} } }
 | 
					                  } } else { html!{} } }
 | 
				
			||||||
                </ul>
 | 
					                </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  if let Some((user_id, _)) = &self.user_info {
 | 
				
			||||||
 | 
					                    html! {
 | 
				
			||||||
                      <div class="dropdown text-end">
 | 
					                      <div class="dropdown text-end">
 | 
				
			||||||
                        <a href="#"
 | 
					                        <a href="#"
 | 
				
			||||||
                          class="d-block link-dark text-decoration-none dropdown-toggle"
 | 
					                          class="d-block link-dark text-decoration-none dropdown-toggle"
 | 
				
			||||||
@ -302,17 +301,10 @@ impl App {
 | 
				
			|||||||
                            <path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
 | 
					                            <path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
 | 
				
			||||||
                            <path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
 | 
					                            <path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
 | 
				
			||||||
                          </svg>
 | 
					                          </svg>
 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                      if let Some((user_id, _)) = &self.user_info {
 | 
					 | 
				
			||||||
                        html! {
 | 
					 | 
				
			||||||
                          <span class="ms-2">
 | 
					                          <span class="ms-2">
 | 
				
			||||||
                            {user_id}
 | 
					                            {user_id}
 | 
				
			||||||
                          </span>
 | 
					                          </span>
 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                      } else { html!{} }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                        </a>
 | 
					                        </a>
 | 
				
			||||||
                  {if let Some((user_id, _)) = &self.user_info { html! {
 | 
					 | 
				
			||||||
                        <ul
 | 
					                        <ul
 | 
				
			||||||
                          class="dropdown-menu text-small dropdown-menu-lg-end"
 | 
					                          class="dropdown-menu text-small dropdown-menu-lg-end"
 | 
				
			||||||
                          aria-labelledby="dropdownUser1"
 | 
					                          aria-labelledby="dropdownUser1"
 | 
				
			||||||
@ -329,8 +321,10 @@ impl App {
 | 
				
			|||||||
                            <LogoutButton on_logged_out=self.link.callback(|_| Msg::Logout) />
 | 
					                            <LogoutButton on_logged_out=self.link.callback(|_| Msg::Logout) />
 | 
				
			||||||
                          </li>
 | 
					                          </li>
 | 
				
			||||||
                        </ul>
 | 
					                        </ul>
 | 
				
			||||||
                  } } else { html!{} } }
 | 
					 | 
				
			||||||
                      </div>
 | 
					                      </div>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  } else { html!{} }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </header>
 | 
					          </header>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    components::router::AppRoute,
 | 
					    components::router::{AppRoute, NavButton},
 | 
				
			||||||
    infra::{
 | 
					    infra::{
 | 
				
			||||||
        api::HostService,
 | 
					        api::HostService,
 | 
				
			||||||
        common_component::{CommonComponent, CommonComponentParts},
 | 
					        common_component::{CommonComponent, CommonComponentParts},
 | 
				
			||||||
@ -158,9 +158,17 @@ impl Component for ResetPasswordStep2Form {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            (None, Some(e)) => {
 | 
					            (None, Some(e)) => {
 | 
				
			||||||
                return html! {
 | 
					                return html! {
 | 
				
			||||||
 | 
					                  <>
 | 
				
			||||||
                    <div class="alert alert-danger">
 | 
					                    <div class="alert alert-danger">
 | 
				
			||||||
                      {e.to_string() }
 | 
					                      {e.to_string() }
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <NavButton
 | 
				
			||||||
 | 
					                      classes="btn-link btn"
 | 
				
			||||||
 | 
					                      disabled=self.common.is_task_running()
 | 
				
			||||||
 | 
					                      route=AppRoute::Login>
 | 
				
			||||||
 | 
					                      {"Back"}
 | 
				
			||||||
 | 
					                    </NavButton>
 | 
				
			||||||
 | 
					                  </>
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            _ => (),
 | 
					            _ => (),
 | 
				
			||||||
 | 
				
			|||||||
@ -214,11 +214,15 @@ where
 | 
				
			|||||||
    let token = request
 | 
					    let token = request
 | 
				
			||||||
        .match_info()
 | 
					        .match_info()
 | 
				
			||||||
        .get("token")
 | 
					        .get("token")
 | 
				
			||||||
        .ok_or_else(|| TcpError::BadRequest("Missing reset token".to_string()))?;
 | 
					        .ok_or_else(|| TcpError::BadRequest("Missing reset token".to_owned()))?;
 | 
				
			||||||
    let user_id = data
 | 
					    let user_id = data
 | 
				
			||||||
        .backend_handler
 | 
					        .backend_handler
 | 
				
			||||||
        .get_user_id_for_password_reset_token(token)
 | 
					        .get_user_id_for_password_reset_token(token)
 | 
				
			||||||
        .await?;
 | 
					        .await
 | 
				
			||||||
 | 
					        .map_err(|e| {
 | 
				
			||||||
 | 
					            debug!("Reset token error: {e:#}");
 | 
				
			||||||
 | 
					            TcpError::NotFoundError("Wrong or expired reset token".to_owned())
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
    let _ = data
 | 
					    let _ = data
 | 
				
			||||||
        .backend_handler
 | 
					        .backend_handler
 | 
				
			||||||
        .delete_password_reset_token(token)
 | 
					        .delete_password_reset_token(token)
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,8 @@ pub enum TcpError {
 | 
				
			|||||||
    BadRequest(String),
 | 
					    BadRequest(String),
 | 
				
			||||||
    #[error("Internal server error: `{0}`")]
 | 
					    #[error("Internal server error: `{0}`")]
 | 
				
			||||||
    InternalServerError(String),
 | 
					    InternalServerError(String),
 | 
				
			||||||
 | 
					    #[error("Not found: `{0}`")]
 | 
				
			||||||
 | 
					    NotFoundError(String),
 | 
				
			||||||
    #[error("Unauthorized: `{0}`")]
 | 
					    #[error("Unauthorized: `{0}`")]
 | 
				
			||||||
    UnauthorizedError(String),
 | 
					    UnauthorizedError(String),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -57,6 +59,7 @@ pub(crate) fn error_to_http_response(error: TcpError) -> HttpResponse {
 | 
				
			|||||||
            | DomainError::EntityNotFound(_) => HttpResponse::BadRequest(),
 | 
					            | DomainError::EntityNotFound(_) => HttpResponse::BadRequest(),
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        TcpError::BadRequest(_) => HttpResponse::BadRequest(),
 | 
					        TcpError::BadRequest(_) => HttpResponse::BadRequest(),
 | 
				
			||||||
 | 
					        TcpError::NotFoundError(_) => HttpResponse::NotFound(),
 | 
				
			||||||
        TcpError::InternalServerError(_) => HttpResponse::InternalServerError(),
 | 
					        TcpError::InternalServerError(_) => HttpResponse::InternalServerError(),
 | 
				
			||||||
        TcpError::UnauthorizedError(_) => HttpResponse::Unauthorized(),
 | 
					        TcpError::UnauthorizedError(_) => HttpResponse::Unauthorized(),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user