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)
|
||||
}
|
||||
|
||||
|
||||
/// Refresh some credentials using Hydra, if needed
|
||||
/// This is the primary desired way to get credentials, as it will also refresh them.
|
||||
#[tracing::instrument]
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
//! Theseus profile management interface
|
||||
use crate::{launcher::download, state::MinecraftChild};
|
||||
use crate::{
|
||||
auth::{self, refresh},
|
||||
launcher::download,
|
||||
state::MinecraftChild,
|
||||
};
|
||||
pub use crate::{
|
||||
state::{JavaSettings, Profile},
|
||||
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
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn run(
|
||||
pub async fn run_credentials(
|
||||
path: &Path,
|
||||
credentials: &crate::auth::Credentials,
|
||||
) -> crate::Result<Arc<RwLock<MinecraftChild>>> {
|
||||
|
||||
@ -76,6 +76,9 @@ pub enum ErrorKind {
|
||||
#[error("Could not create profile: {0}")]
|
||||
ProfileCreationError(#[from] profile_create::ProfileCreationError),
|
||||
|
||||
#[error("User is not logged in, no credentials available!")]
|
||||
NoCredentialsError,
|
||||
|
||||
#[error("JRE error: {0}")]
|
||||
JREError(#[from] crate::util::jre::JREError),
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ struct ProfileInfoJSON {
|
||||
}
|
||||
|
||||
// Login information
|
||||
#[derive(Encode, Decode, Serialize, Deserialize)]
|
||||
#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Credentials {
|
||||
#[bincode(with_serde)]
|
||||
pub id: uuid::Uuid,
|
||||
|
||||
@ -332,7 +332,7 @@ impl ProfileRun {
|
||||
.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;
|
||||
process::wait_for(&mut proc).await?;
|
||||
|
||||
|
||||
@ -27,13 +27,13 @@ pub async fn profile_list(
|
||||
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
|
||||
// for the actual Child in the state.
|
||||
// invoke('profile_run')
|
||||
// invoke('profile_run', path)
|
||||
#[tauri::command]
|
||||
pub async fn profile_run(path: &Path, credentials: Credentials) -> Result<u32> {
|
||||
let proc_lock = profile::run(path, &credentials).await?;
|
||||
pub async fn profile_run(path: &Path) -> Result<u32> {
|
||||
let proc_lock = profile::run(path).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(),
|
||||
@ -42,14 +42,38 @@ pub async fn profile_run(path: &Path, credentials: Credentials) -> Result<u32> {
|
||||
Ok(pid)
|
||||
}
|
||||
|
||||
// Run Minecraft using a profile, and wait for the result
|
||||
// invoke('profile_run_wait', path, credentials)
|
||||
// Run Minecraft using a profile using the default credentials, and wait for the result
|
||||
// invoke('profile_run_wait', path)
|
||||
#[tauri::command]
|
||||
pub async fn profile_run_wait(
|
||||
path: &Path,
|
||||
credentials: Credentials,
|
||||
) -> Result<()> {
|
||||
let proc_lock = profile::run(path, &credentials).await?;
|
||||
pub async fn profile_run_wait(path: &Path) -> Result<()> {
|
||||
let proc_lock = profile::run(path).await?;
|
||||
let mut proc = proc_lock.write().await;
|
||||
Ok(process::wait_for(&mut proc).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;
|
||||
Ok(process::wait_for(&mut proc).await?)
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ fn main() {
|
||||
api::profile::profile_list,
|
||||
api::profile::profile_run,
|
||||
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_file,
|
||||
api::auth::auth_authenticate_begin_flow,
|
||||
|
||||
@ -64,39 +64,16 @@ async fn main() -> theseus::Result<()> {
|
||||
.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
|
||||
let proc_lock = match credentials {
|
||||
Ok(credentials) => {
|
||||
println!("Preparing to run Minecraft.");
|
||||
profile::run(&canonicalize(&profile_path)?, &credentials).await
|
||||
|
||||
// Attempt to run game
|
||||
if auth::users().await?.len() == 0 {
|
||||
println!("No users found, authenticating.");
|
||||
authenticate_run().await?; // could take credentials from here direct, but also deposited in state users
|
||||
}
|
||||
Err(e) => {
|
||||
// If Hydra could not be accessed, for testing, attempt to load credentials from disk and do the same
|
||||
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
|
||||
}
|
||||
}?;
|
||||
|
||||
// Run a profile, running minecraft and store the RwLock to the process
|
||||
let proc_lock = profile::run(&canonicalize(&profile_path)?).await?;
|
||||
|
||||
let pid = proc_lock
|
||||
.read()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user