restructured auto-credentials (#74)
* restructured auto-credentials * fix clone --------- Co-authored-by: Jai A <jaiagr+gpg@pm.me> Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
parent
34005dd2e2
commit
764d75181f
@ -57,6 +57,7 @@ pub async fn authenticate(
|
|||||||
Ok(credentials)
|
Ok(credentials)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Refresh some credentials using Hydra, if needed
|
/// Refresh some credentials using Hydra, if needed
|
||||||
/// This is the primary desired way to get credentials, as it will also refresh them.
|
/// This is the primary desired way to get credentials, as it will also refresh them.
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
//! Theseus profile management interface
|
//! Theseus profile management interface
|
||||||
use crate::{launcher::download, state::MinecraftChild};
|
use crate::{
|
||||||
|
auth::{self, refresh},
|
||||||
|
launcher::download,
|
||||||
|
state::MinecraftChild,
|
||||||
|
};
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
state::{JavaSettings, Profile},
|
state::{JavaSettings, Profile},
|
||||||
State,
|
State,
|
||||||
@ -91,10 +95,33 @@ pub async fn sync(path: &Path) -> crate::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run Minecraft using a profile
|
/// Run Minecraft using a profile and the default credentials, logged in credentials,
|
||||||
|
/// failing with an error if no credentials are available
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
|
pub async fn run(path: &Path) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
|
||||||
|
let state = State::get().await?;
|
||||||
|
|
||||||
|
// Get default account and refresh credentials (preferred way to log in)
|
||||||
|
let default_account = state.settings.read().await.default_user;
|
||||||
|
let credentials = if let Some(default_account) = default_account {
|
||||||
|
refresh(default_account, false).await?
|
||||||
|
} else {
|
||||||
|
// If no default account, try to use a logged in account
|
||||||
|
let users = auth::users().await?;
|
||||||
|
let last_account = users.iter().next();
|
||||||
|
if let Some(last_account) = last_account {
|
||||||
|
refresh(last_account.id, false).await?
|
||||||
|
} else {
|
||||||
|
return Err(crate::ErrorKind::NoCredentialsError.as_error());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
run_credentials(path, &credentials).await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run Minecraft using a profile, and credentials for authentication
|
||||||
/// Returns Arc pointer to RwLock to Child
|
/// Returns Arc pointer to RwLock to Child
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn run(
|
pub async fn run_credentials(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
credentials: &crate::auth::Credentials,
|
credentials: &crate::auth::Credentials,
|
||||||
) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
|
) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
|
||||||
|
|||||||
@ -76,6 +76,9 @@ pub enum ErrorKind {
|
|||||||
#[error("Could not create profile: {0}")]
|
#[error("Could not create profile: {0}")]
|
||||||
ProfileCreationError(#[from] profile_create::ProfileCreationError),
|
ProfileCreationError(#[from] profile_create::ProfileCreationError),
|
||||||
|
|
||||||
|
#[error("User is not logged in, no credentials available!")]
|
||||||
|
NoCredentialsError,
|
||||||
|
|
||||||
#[error("JRE error: {0}")]
|
#[error("JRE error: {0}")]
|
||||||
JREError(#[from] crate::util::jre::JREError),
|
JREError(#[from] crate::util::jre::JREError),
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ struct ProfileInfoJSON {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Login information
|
// Login information
|
||||||
#[derive(Encode, Decode, Serialize, Deserialize)]
|
#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct Credentials {
|
pub struct Credentials {
|
||||||
#[bincode(with_serde)]
|
#[bincode(with_serde)]
|
||||||
pub id: uuid::Uuid,
|
pub id: uuid::Uuid,
|
||||||
|
|||||||
@ -332,7 +332,7 @@ impl ProfileRun {
|
|||||||
.await?;
|
.await?;
|
||||||
let credentials = auth::refresh(id, false).await?;
|
let credentials = auth::refresh(id, false).await?;
|
||||||
|
|
||||||
let proc_lock = profile::run(&path, &credentials).await?;
|
let proc_lock = profile::run_credentials(&path, &credentials).await?;
|
||||||
let mut proc = proc_lock.write().await;
|
let mut proc = proc_lock.write().await;
|
||||||
process::wait_for(&mut proc).await?;
|
process::wait_for(&mut proc).await?;
|
||||||
|
|
||||||
|
|||||||
@ -27,13 +27,13 @@ pub async fn profile_list(
|
|||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run Minecraft using a profile
|
// Run minecraft using a profile using the default credentials
|
||||||
// Returns a u32 representing the PID, which can be used to poll
|
// Returns a u32 representing the PID, which can be used to poll
|
||||||
// for the actual Child in the state.
|
// for the actual Child in the state.
|
||||||
// invoke('profile_run')
|
// invoke('profile_run', path)
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn profile_run(path: &Path, credentials: Credentials) -> Result<u32> {
|
pub async fn profile_run(path: &Path) -> Result<u32> {
|
||||||
let proc_lock = profile::run(path, &credentials).await?;
|
let proc_lock = profile::run(path).await?;
|
||||||
let pid = proc_lock.read().await.child.id().ok_or_else(|| {
|
let pid = proc_lock.read().await.child.id().ok_or_else(|| {
|
||||||
theseus::Error::from(theseus::ErrorKind::LauncherError(
|
theseus::Error::from(theseus::ErrorKind::LauncherError(
|
||||||
"Process failed to stay open.".to_string(),
|
"Process failed to stay open.".to_string(),
|
||||||
@ -42,14 +42,38 @@ pub async fn profile_run(path: &Path, credentials: Credentials) -> Result<u32> {
|
|||||||
Ok(pid)
|
Ok(pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run Minecraft using a profile, and wait for the result
|
// Run Minecraft using a profile using the default credentials, and wait for the result
|
||||||
// invoke('profile_run_wait', path, credentials)
|
// invoke('profile_run_wait', path)
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn profile_run_wait(
|
pub async fn profile_run_wait(path: &Path) -> Result<()> {
|
||||||
path: &Path,
|
let proc_lock = profile::run(path).await?;
|
||||||
credentials: Credentials,
|
let mut proc = proc_lock.write().await;
|
||||||
) -> Result<()> {
|
Ok(process::wait_for(&mut proc).await?)
|
||||||
let proc_lock = profile::run(path, &credentials).await?;
|
}
|
||||||
|
|
||||||
|
// Run Minecraft using a profile using chosen credentials
|
||||||
|
// Returns a u32 representing the PID, which can be used to poll
|
||||||
|
// for the actual Child in the state.
|
||||||
|
// invoke('profile_run_credentials', {path, credentials})')
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn profile_run_credentials(path: &Path, credentials: Credentials) -> Result<u32> {
|
||||||
|
let proc_lock = profile::run_credentials(path, &credentials).await?;
|
||||||
|
let pid = proc_lock.read().await.child.id().ok_or_else(|| {
|
||||||
|
theseus::Error::from(theseus::ErrorKind::LauncherError(
|
||||||
|
"Process failed to stay open.".to_string(),
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
Ok(pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run Minecraft using a profile using the chosen credentials, and wait for the result
|
||||||
|
// invoke('profile_run_wait', {path, credentials)
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn profile_run_wait_credentials(
|
||||||
|
path: &Path,
|
||||||
|
credentials: Credentials,
|
||||||
|
) -> Result<()> {
|
||||||
|
let proc_lock = profile::run_credentials(path, &credentials).await?;
|
||||||
let mut proc = proc_lock.write().await;
|
let mut proc = proc_lock.write().await;
|
||||||
Ok(process::wait_for(&mut proc).await?)
|
Ok(process::wait_for(&mut proc).await?)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,8 @@ fn main() {
|
|||||||
api::profile::profile_list,
|
api::profile::profile_list,
|
||||||
api::profile::profile_run,
|
api::profile::profile_run,
|
||||||
api::profile::profile_run_wait,
|
api::profile::profile_run_wait,
|
||||||
|
api::profile::profile_run_credentials,
|
||||||
|
api::profile::profile_run_wait_credentials,
|
||||||
api::pack::pack_install_version_id,
|
api::pack::pack_install_version_id,
|
||||||
api::pack::pack_install_file,
|
api::pack::pack_install_file,
|
||||||
api::auth::auth_authenticate_begin_flow,
|
api::auth::auth_authenticate_begin_flow,
|
||||||
|
|||||||
@ -64,39 +64,16 @@ async fn main() -> theseus::Result<()> {
|
|||||||
.await?;
|
.await?;
|
||||||
State::sync().await?;
|
State::sync().await?;
|
||||||
|
|
||||||
// Attempt to get the default user, if it exists, and refresh their credentials
|
|
||||||
let default_user_uuid = {
|
|
||||||
let settings = st.settings.read().await;
|
|
||||||
settings.default_user
|
|
||||||
};
|
|
||||||
let credentials = if let Some(uuid) = default_user_uuid {
|
|
||||||
println!("Attempting to refresh existing authentication.");
|
|
||||||
auth::refresh(uuid, false).await
|
|
||||||
} else {
|
|
||||||
println!("Freshly authenticating.");
|
|
||||||
authenticate_run().await
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check attempt to get Credentials
|
|
||||||
// If successful, run the profile and store the RwLock to the process
|
// Attempt to run game
|
||||||
let proc_lock = match credentials {
|
if auth::users().await?.len() == 0 {
|
||||||
Ok(credentials) => {
|
println!("No users found, authenticating.");
|
||||||
println!("Preparing to run Minecraft.");
|
authenticate_run().await?; // could take credentials from here direct, but also deposited in state users
|
||||||
profile::run(&canonicalize(&profile_path)?, &credentials).await
|
}
|
||||||
}
|
|
||||||
Err(e) => {
|
// Run a profile, running minecraft and store the RwLock to the process
|
||||||
// If Hydra could not be accessed, for testing, attempt to load credentials from disk and do the same
|
let proc_lock = profile::run(&canonicalize(&profile_path)?).await?;
|
||||||
println!("Could not authenticate: {}.\nAttempting stored authentication.",e);
|
|
||||||
let users = auth::users().await.expect(
|
|
||||||
"Could not access any stored users- state was dropped.",
|
|
||||||
);
|
|
||||||
let credentials = users
|
|
||||||
.first()
|
|
||||||
.expect("Hydra failed, and no stored users were found.");
|
|
||||||
println!("Preparing to run Minecraft.");
|
|
||||||
profile::run(&canonicalize(&profile_path)?, credentials).await
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let pid = proc_lock
|
let pid = proc_lock
|
||||||
.read()
|
.read()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user