You've already forked AstralRinth
forked from didirus/AstralRinth
Auth bindings (#58)
* basic framework. still has errors * added functionality for main endpoints + some structuring * formatting * unused code * mimicked CLI function with wait_for process * added basic auth bindings * made PR changes, added playground * cargo fmt * removed missed println * misc tests fixes * cargo fmt * added windows support * cargo fmt * all OS use dunce * restructured profile slightly; fixed mac bug * profile changes, new main.rs * fixed requested pr + canonicaliation bug * fixed regressed bug in ui * fixed regressed bugs * fixed git error * typo * ran prettier * clippy * playground clippy * ported profile loading fix * profile change for real, url println and clippy * PR changes * auth bindings + semisynch flow * fixed dropping task error * prettier, eslint, clippy * removed debugging modifications * removed unused function that eslinter missed :( * fixed settings not being released --------- Co-authored-by: Wyatt <wyatt@modrinth.com>
This commit is contained in:
@@ -7,30 +7,22 @@ use dunce::canonicalize;
|
||||
use std::path::Path;
|
||||
use theseus::{prelude::*, profile_create::profile_create};
|
||||
use tokio::process::Child;
|
||||
use tokio::sync::{oneshot, RwLockWriteGuard};
|
||||
use tokio::sync::RwLockWriteGuard;
|
||||
|
||||
// We use this function directly to call authentication procedure
|
||||
// Note: "let url = match url" logic is handled differently, so that if there is a rate limit in the other set causing that one to end early,
|
||||
// we can see the error message in this thread rather than a Recv error on 'rx' when the receiver is mysteriously droppped
|
||||
// A simple Rust implementation of the authentication run
|
||||
// 1) call the authenticate_begin_flow() function to get the URL to open (like you would in the frontend)
|
||||
// 2) open the URL in a browser
|
||||
// 3) call the authenticate_await_complete_flow() function to get the credentials (like you would in the frontend)
|
||||
pub async fn authenticate_run() -> theseus::Result<Credentials> {
|
||||
println!("Adding new user account to Theseus");
|
||||
println!("A browser window will now open, follow the login flow there.");
|
||||
let url = auth::authenticate_begin_flow().await?;
|
||||
|
||||
let (tx, rx) = oneshot::channel::<url::Url>();
|
||||
let flow = tokio::spawn(auth::authenticate(tx));
|
||||
|
||||
let url = rx.await;
|
||||
let url = match url {
|
||||
Ok(url) => url,
|
||||
Err(e) => {
|
||||
flow.await.unwrap()?;
|
||||
return Err(e.into());
|
||||
}
|
||||
};
|
||||
println!("URL {}", url.as_str());
|
||||
webbrowser::open(url.as_str())?;
|
||||
let credentials = flow.await.unwrap()?;
|
||||
|
||||
let credentials = auth::authenticate_await_complete_flow().await?;
|
||||
State::sync().await?;
|
||||
|
||||
println!("Logged in user {}.", credentials.username);
|
||||
Ok(credentials)
|
||||
}
|
||||
@@ -92,28 +84,44 @@ async fn main() -> theseus::Result<()> {
|
||||
.await?;
|
||||
State::sync().await?;
|
||||
|
||||
println!("Authenticating.");
|
||||
// Attempt to create credentials and run.
|
||||
let proc_lock = match authenticate_run().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.clone()
|
||||
};
|
||||
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!("Running.");
|
||||
println!("Preparing to run Minecraft.");
|
||||
profile::run(&canonicalize(&profile_path)?, &credentials).await
|
||||
}
|
||||
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);
|
||||
// Attempt to load credentials if Hydra is down/rate limit hit
|
||||
let users = auth::users().await.unwrap();
|
||||
let credentials = users.first().unwrap();
|
||||
|
||||
println!("Running.");
|
||||
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
|
||||
}
|
||||
}?;
|
||||
|
||||
println!("Started. Waiting...");
|
||||
// Spawn a thread and hold the lock to the process until it ends
|
||||
println!("Started Minecraft. Waiting for process to end...");
|
||||
let mut proc: RwLockWriteGuard<Child> = proc_lock.write().await;
|
||||
profile::wait_for(&mut proc).await?;
|
||||
|
||||
// Run MC
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user