mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
@@ -1,9 +1,13 @@
|
||||
use super::HbbHttpResponse;
|
||||
use hbb_common::{config::Config, log, sleep, tokio, tokio::sync::RwLock, ResultType};
|
||||
use hbb_common::{
|
||||
config::{Config, LocalConfig},
|
||||
log, sleep, tokio, ResultType,
|
||||
};
|
||||
use reqwest::blocking::Client;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::Arc,
|
||||
sync::{Arc, RwLock},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use url::Url;
|
||||
@@ -15,12 +19,12 @@ lazy_static::lazy_static! {
|
||||
}
|
||||
|
||||
const QUERY_INTERVAL_SECS: f32 = 1.0;
|
||||
const QUERY_TIMEOUT_SECS: u64 = 60;
|
||||
const QUERY_TIMEOUT_SECS: u64 = 60 * 3;
|
||||
const REQUESTING_ACCOUNT_AUTH: &str = "Requesting account auth";
|
||||
const WAITING_ACCOUNT_AUTH: &str = "Waiting account auth";
|
||||
const LOGIN_ACCOUNT_AUTH: &str = "Login account auth";
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct OidcAuthUrl {
|
||||
code: String,
|
||||
url: Url,
|
||||
@@ -45,7 +49,7 @@ pub struct AuthBody {
|
||||
}
|
||||
|
||||
pub struct OidcSession {
|
||||
client: reqwest::Client,
|
||||
client: Client,
|
||||
state_msg: &'static str,
|
||||
failed_msg: String,
|
||||
code_url: Option<OidcAuthUrl>,
|
||||
@@ -66,7 +70,7 @@ pub struct AuthResult {
|
||||
impl OidcSession {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
client: reqwest::Client::new(),
|
||||
client: Client::new(),
|
||||
state_msg: REQUESTING_ACCOUNT_AUTH,
|
||||
failed_msg: "".to_owned(),
|
||||
code_url: None,
|
||||
@@ -77,30 +81,28 @@ impl OidcSession {
|
||||
}
|
||||
}
|
||||
|
||||
async fn auth(op: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
|
||||
fn auth(op: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<OidcAuthUrl>> {
|
||||
Ok(OIDC_SESSION
|
||||
.read()
|
||||
.await
|
||||
.unwrap()
|
||||
.client
|
||||
.post(format!("{}/api/oidc/auth", *API_SERVER))
|
||||
.json(&HashMap::from([("op", op), ("id", id), ("uuid", uuid)]))
|
||||
.send()
|
||||
.await?
|
||||
.send()?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
async fn query(code: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<AuthBody>> {
|
||||
fn query(code: &str, id: &str, uuid: &str) -> ResultType<HbbHttpResponse<AuthBody>> {
|
||||
let url = reqwest::Url::parse_with_params(
|
||||
&format!("{}/api/oidc/auth-query", *API_SERVER),
|
||||
&[("code", code), ("id", id), ("uuid", uuid)],
|
||||
)?;
|
||||
Ok(OIDC_SESSION
|
||||
.read()
|
||||
.await
|
||||
.unwrap()
|
||||
.client
|
||||
.get(url)
|
||||
.send()
|
||||
.await?
|
||||
.send()?
|
||||
.try_into()?)
|
||||
}
|
||||
|
||||
@@ -113,36 +115,42 @@ impl OidcSession {
|
||||
self.auth_body = None;
|
||||
}
|
||||
|
||||
async fn before_task(&mut self) {
|
||||
fn before_task(&mut self) {
|
||||
self.reset();
|
||||
self.running = true;
|
||||
}
|
||||
|
||||
async fn after_task(&mut self) {
|
||||
fn after_task(&mut self) {
|
||||
self.running = false;
|
||||
}
|
||||
|
||||
async fn auth_task(op: String, id: String, uuid: String) {
|
||||
let code_url = match Self::auth(&op, &id, &uuid).await {
|
||||
fn sleep(secs: f32) {
|
||||
std::thread::sleep(std::time::Duration::from_secs_f32(secs));
|
||||
}
|
||||
|
||||
fn auth_task(op: String, id: String, uuid: String) {
|
||||
let auth_request_res = Self::auth(&op, &id, &uuid);
|
||||
log::info!("Request oidc auth result: {:?}", &auth_request_res);
|
||||
let code_url = match auth_request_res {
|
||||
Ok(HbbHttpResponse::<_>::Data(code_url)) => code_url,
|
||||
Ok(HbbHttpResponse::<_>::Error(err)) => {
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(REQUESTING_ACCOUNT_AUTH, err);
|
||||
return;
|
||||
}
|
||||
Ok(_) => {
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(REQUESTING_ACCOUNT_AUTH, "Invalid auth response".to_owned());
|
||||
return;
|
||||
}
|
||||
Err(err) => {
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(REQUESTING_ACCOUNT_AUTH, err.to_string());
|
||||
return;
|
||||
}
|
||||
@@ -150,22 +158,29 @@ impl OidcSession {
|
||||
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(WAITING_ACCOUNT_AUTH, "".to_owned());
|
||||
OIDC_SESSION.write().await.code_url = Some(code_url.clone());
|
||||
OIDC_SESSION.write().unwrap().code_url = Some(code_url.clone());
|
||||
|
||||
let begin = Instant::now();
|
||||
let query_timeout = OIDC_SESSION.read().await.query_timeout;
|
||||
while OIDC_SESSION.read().await.keep_querying && begin.elapsed() < query_timeout {
|
||||
match Self::query(&code_url.code, &id, &uuid).await {
|
||||
let query_timeout = OIDC_SESSION.read().unwrap().query_timeout;
|
||||
while OIDC_SESSION.read().unwrap().keep_querying && begin.elapsed() < query_timeout {
|
||||
match Self::query(&code_url.code, &id, &uuid) {
|
||||
Ok(HbbHttpResponse::<_>::Data(auth_body)) => {
|
||||
LocalConfig::set_option(
|
||||
"access_token".to_owned(),
|
||||
auth_body.access_token.clone(),
|
||||
);
|
||||
LocalConfig::set_option(
|
||||
"user_info".to_owned(),
|
||||
serde_json::to_string(&auth_body.user).unwrap_or_default(),
|
||||
);
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(LOGIN_ACCOUNT_AUTH, "".to_owned());
|
||||
OIDC_SESSION.write().await.auth_body = Some(auth_body);
|
||||
OIDC_SESSION.write().unwrap().auth_body = Some(auth_body);
|
||||
return;
|
||||
// to-do, set access-token
|
||||
}
|
||||
Ok(HbbHttpResponse::<_>::Error(err)) => {
|
||||
if err.contains("No authed oidc is found") {
|
||||
@@ -173,7 +188,7 @@ impl OidcSession {
|
||||
} else {
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(WAITING_ACCOUNT_AUTH, err);
|
||||
return;
|
||||
}
|
||||
@@ -186,13 +201,13 @@ impl OidcSession {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
sleep(QUERY_INTERVAL_SECS).await;
|
||||
Self::sleep(QUERY_INTERVAL_SECS);
|
||||
}
|
||||
|
||||
if begin.elapsed() >= query_timeout {
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
.await
|
||||
.unwrap()
|
||||
.set_state(WAITING_ACCOUNT_AUTH, "timeout".to_owned());
|
||||
}
|
||||
|
||||
@@ -204,20 +219,20 @@ impl OidcSession {
|
||||
self.failed_msg = failed_msg;
|
||||
}
|
||||
|
||||
pub async fn account_auth(op: String, id: String, uuid: String) {
|
||||
if OIDC_SESSION.read().await.running {
|
||||
OIDC_SESSION.write().await.keep_querying = false;
|
||||
}
|
||||
fn wait_stop_querying() {
|
||||
let wait_secs = 0.3;
|
||||
sleep(wait_secs).await;
|
||||
while OIDC_SESSION.read().await.running {
|
||||
sleep(wait_secs).await;
|
||||
while OIDC_SESSION.read().unwrap().running {
|
||||
Self::sleep(wait_secs);
|
||||
}
|
||||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
OIDC_SESSION.write().await.before_task().await;
|
||||
Self::auth_task(op, id, uuid).await;
|
||||
OIDC_SESSION.write().await.after_task().await;
|
||||
pub fn account_auth(op: String, id: String, uuid: String) {
|
||||
Self::auth_cancel();
|
||||
Self::wait_stop_querying();
|
||||
OIDC_SESSION.write().unwrap().before_task();
|
||||
std::thread::spawn(|| {
|
||||
Self::auth_task(op, id, uuid);
|
||||
OIDC_SESSION.write().unwrap().after_task();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -230,7 +245,11 @@ impl OidcSession {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_result() -> AuthResult {
|
||||
OIDC_SESSION.read().await.get_result_()
|
||||
pub fn auth_cancel() {
|
||||
OIDC_SESSION.write().unwrap().keep_querying = false;
|
||||
}
|
||||
|
||||
pub fn get_result() -> AuthResult {
|
||||
OIDC_SESSION.read().unwrap().get_result_()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user