mirror of
https://gitea.mizah.xyz/mizah/dergchat
synced 2024-11-26 23:22:16 -05:00
Refactoring the login-related code.
This commit is contained in:
parent
74e2cfd6b7
commit
f4e8d5fa3b
@ -14,11 +14,12 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::passwords::Password;
|
use crate::passwords::{Password, try_retrieve_password_from_keyring};
|
||||||
use jid::BareJid;
|
use jid::BareJid;
|
||||||
use keyring::Entry;
|
use keyring::Entry;
|
||||||
use log::error;
|
use log::{error, info};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use crate::types::LoginCredentials;
|
||||||
|
|
||||||
/// The configuration struct containing all the configuration options.
|
/// The configuration struct containing all the configuration options.
|
||||||
#[derive(Default, Debug, Serialize, Deserialize)]
|
#[derive(Default, Debug, Serialize, Deserialize)]
|
||||||
@ -70,3 +71,22 @@ pub fn load_config() -> Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve the full login credentials from the config and keyring, if they exist.
|
||||||
|
pub fn try_retrieve_credentials(config: &Configuration) -> Option<LoginCredentials> {
|
||||||
|
if let (Some(user), Some(nick)) = (&config.stored_username, &config.stored_default_nick) {
|
||||||
|
if let Some(password) = try_retrieve_password_from_keyring(&user) {
|
||||||
|
Some(LoginCredentials {
|
||||||
|
username: user.clone(),
|
||||||
|
default_nick: nick.clone(),
|
||||||
|
password,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
info!("No stored password found; will not try to log in.");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("No stored username or default nick found; will not try to log in.");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,11 @@ use dioxus::hooks::use_state;
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use jid::BareJid;
|
||||||
|
use log::error;
|
||||||
|
use crate::passwords::Password;
|
||||||
|
use crate::types::LoginCredentials;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum LoginStatus {
|
pub enum LoginStatus {
|
||||||
@ -49,6 +54,32 @@ impl Debug for LoginAttempt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate_login_attempt(x: LoginAttempt) -> Result<LoginCredentials, String> {
|
||||||
|
let LoginAttempt {
|
||||||
|
username,
|
||||||
|
default_nick,
|
||||||
|
password,
|
||||||
|
} = x;
|
||||||
|
|
||||||
|
// First, validate the username as a jid:
|
||||||
|
let jid = match BareJid::from_str(&username) {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Invalid JID: {}", e);
|
||||||
|
return Err(format!("Invalid JID: {}", e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wrap the password in a Password struct.
|
||||||
|
let password = Password(password);
|
||||||
|
|
||||||
|
Ok(LoginCredentials {
|
||||||
|
username: jid,
|
||||||
|
default_nick,
|
||||||
|
password,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// The props for the login screen widget, including:
|
/// The props for the login screen widget, including:
|
||||||
/// * The xmpp address to pre-fill in the username field.
|
/// * The xmpp address to pre-fill in the username field.
|
||||||
/// * The default nick to pre-fill in the default nick field.
|
/// * The default nick to pre-fill in the default nick field.
|
||||||
|
@ -23,6 +23,7 @@ use crate::widgets::room_view::RoomView;
|
|||||||
use crate::widgets::sidebar::SideBar;
|
use crate::widgets::sidebar::SideBar;
|
||||||
use crate::xmpp_interface::NetworkCommand;
|
use crate::xmpp_interface::NetworkCommand;
|
||||||
use dioxus::core::{Element, Scope};
|
use dioxus::core::{Element, Scope};
|
||||||
|
use crate::widgets::login_screen::validate_login_attempt;
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
@ -30,7 +31,7 @@ use jid::BareJid;
|
|||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::configuration::{load_config, Configuration};
|
use crate::configuration::{load_config, Configuration, try_retrieve_credentials};
|
||||||
use crate::xmpp_interface;
|
use crate::xmpp_interface;
|
||||||
|
|
||||||
use crate::configuration::store_login_details;
|
use crate::configuration::store_login_details;
|
||||||
@ -46,24 +47,6 @@ pub mod room_view;
|
|||||||
pub mod send_message;
|
pub mod send_message;
|
||||||
pub mod sidebar;
|
pub mod sidebar;
|
||||||
|
|
||||||
fn try_retrieve_credentials(config: &Configuration) -> Option<LoginCredentials> {
|
|
||||||
if let (Some(user), Some(nick)) = (&config.stored_username, &config.stored_default_nick) {
|
|
||||||
if let Some(password) = try_retrieve_password_from_keyring(&user) {
|
|
||||||
Some(LoginCredentials {
|
|
||||||
username: user.clone(),
|
|
||||||
default_nick: nick.clone(),
|
|
||||||
password,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
info!("No stored password found; will not try to log in.");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info!("No stored username or default nick found; will not try to log in.");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn App(cx: Scope) -> Element {
|
pub fn App(cx: Scope) -> Element {
|
||||||
let messages = use_ref(cx, || HashMap::new());
|
let messages = use_ref(cx, || HashMap::new());
|
||||||
let current_room = use_state(cx, || None::<BareJid>);
|
let current_room = use_state(cx, || None::<BareJid>);
|
||||||
@ -103,34 +86,18 @@ pub fn App(cx: Scope) -> Element {
|
|||||||
cached_nick: config.read().stored_default_nick.clone().unwrap_or("".to_string()),
|
cached_nick: config.read().stored_default_nick.clone().unwrap_or("".to_string()),
|
||||||
login_state: connection_status.current().as_ref().clone(),
|
login_state: connection_status.current().as_ref().clone(),
|
||||||
on_login_attempt: move |x: LoginAttempt| {
|
on_login_attempt: move |x: LoginAttempt| {
|
||||||
|
// Validate the login attempt.
|
||||||
let LoginAttempt { username, default_nick, password } = x;
|
match validate_login_attempt(x) {
|
||||||
|
Ok(x) => {
|
||||||
// First, validate the username as a jid:
|
config.with_mut(|c| {
|
||||||
let jid = match BareJid::from_str(&username) {
|
store_login_details(x.username.clone(), x.default_nick.clone(), &x.password, c);
|
||||||
Ok(x) => x,
|
});
|
||||||
Err(e) => {
|
coroutine.send(NetworkCommand::TryLogin { credentials: x });
|
||||||
error!("Invalid JID: {}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wrap the password in a Password struct.
|
|
||||||
let password = Password(password);
|
|
||||||
|
|
||||||
// Store the login details in the config and keyring for auto-login next time.
|
|
||||||
config.with_mut(|c| {
|
|
||||||
store_login_details(jid.clone(), default_nick.clone(), &password, c);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Finally, send the login command to the xmpp interface.
|
|
||||||
coroutine.send(NetworkCommand::TryLogin {
|
|
||||||
credentials: LoginCredentials {
|
|
||||||
username: jid,
|
|
||||||
default_nick,
|
|
||||||
password,
|
|
||||||
},
|
},
|
||||||
});
|
Err(e) => {
|
||||||
|
error!("Invalid login attempt: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,7 +105,6 @@ pub fn App(cx: Scope) -> Element {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
// We're logged in; show a sidebar and a room view.
|
// We're logged in; show a sidebar and a room view.
|
||||||
|
|
||||||
rsx!{
|
rsx!{
|
||||||
|
|
||||||
// Sidebar.
|
// Sidebar.
|
||||||
|
Loading…
Reference in New Issue
Block a user