+ pub async fn post_reset_game_pwd(
+ form: web::Form<FormData>,
+ data: web::Data<WebData<'_>>,
+ ) -> HttpResponse {
+ let cached_data = {
+ let mut cache = data.cache.lock().await;
+ cache.remove(&form.csrf)
+ };
+ let (cached_token, cached_login) = match cached_data {
+ Some(d) => d,
+ None => {
+ log::warn!("Unknown data for CSRF: {}", form.csrf);
+ return HttpResponse::BadRequest().body("Incorrect");
+ }
+ };
+ if form.token != cached_token {
+ log::warn!("Mismatch token for CSRF: {}", form.csrf);
+ return HttpResponse::BadRequest().body("Incorrect");
+ }
+
+ let dbclient = match data.pool_rw.get().await {
+ Ok(c) => c,
+ Err(e) => {
+ log::error!("Pool RW error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+
+ let pass_match = form.password == form.password_copy;
+ let login_match = form.login.to_ascii_lowercase() == cached_login.to_ascii_lowercase();
+ if pass_match && login_match {
+ let stmt = match dbclient
+ .prepare("delete from auth.reset_tokens where token = $1 and player_name = $2;")
+ .await
+ {
+ Ok(stmt) => stmt,
+ Err(e) => {
+ log::error!("Pool RW statement delete error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+ let deleted = match dbclient.execute(&stmt, &[&form.token, &form.login]).await {
+ Ok(c) => c,
+ Err(e) => {
+ log::error!("Pool RW execute delete error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+ if deleted == 0 {
+ log::error!("Not delete error: {}", cached_token);
+ return HttpResponse::BadRequest().body("Incorrect");
+ }
+ let stmt = match dbclient.prepare("update auth.users set game_password = crypt($1, gen_salt('bf', 8)) where player_name = $2;").await {
+ Ok(stmt) => stmt,
+ Err(e) => {
+ log::error!("Pool RW statement upd pwd error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+ let changed = match dbclient
+ .execute(&stmt, &[&form.password, &form.login])
+ .await
+ {
+ Ok(c) => c,
+ Err(e) => {
+ log::error!("Pool RW execute upd pwd error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+ if changed > 0 {
+ HttpResponse::Found()
+ .append_header((header::LOCATION, "index.html"))
+ .finish()
+ } else {
+ log::error!("Not update pwd error: {}", cached_token);
+ HttpResponse::BadRequest().body("Incorrect")
+ }
+ } else {
+ let stmt = match dbclient.prepare("update auth.reset_tokens set last_error = $1 where token = $2 and player_name = $3;").await {
+ Ok(stmt) => stmt,
+ Err(e) => {
+ log::error!("Pool RW statement error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+ let changed = match dbclient
+ .execute(
+ &stmt,
+ &[
+ &if login_match {
+ "Passwords mismatch"
+ } else {
+ "Login mismatch"
+ },
+ &cached_token,
+ &cached_login,
+ ],
+ )
+ .await
+ {
+ Ok(c) => c,
+ Err(e) => {
+ log::error!("Pool RW execute error {}", e);
+ return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
+ }
+ };
+ if changed > 0 {
+ HttpResponse::Found()
+ .append_header((
+ header::LOCATION,
+ format!("reset-game-pwd-{}.html", cached_token),
+ ))
+ .finish()
+ } else {
+ log::error!("Not set error: {}", cached_token);
+ HttpResponse::BadRequest().body("Incorrect")
+ }
+ }