mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +00:00
refresh token run loop
Need central-side work to complete
This commit is contained in:
parent
43c528fdb6
commit
1192b1b422
@ -411,7 +411,6 @@ bool NetworkConfig::fromDictionary(const Dictionary<ZT_NETWORKCONFIG_DICT_CAPACI
|
||||
}
|
||||
if (d.get(ZT_NETWORKCONFIG_DICT_KEY_ISSUER_URL, this->issuerURL, (unsigned int)sizeof(this->issuerURL)) > 0) {
|
||||
this->issuerURL[sizeof(this->issuerURL) - 1] = 0;
|
||||
fprintf(stderr, "Loaded issuer url: %s\n", this->issuerURL);
|
||||
}
|
||||
if (d.get(ZT_NETWORKCONFIG_DICT_KEY_CENTRAL_ENDPOINT_URL, this->centralAuthURL, (unsigned int)sizeof(this->centralAuthURL)) > 0) {
|
||||
this->centralAuthURL[sizeof(this->centralAuthURL) - 1] = 0;
|
||||
|
@ -249,23 +249,23 @@ public:
|
||||
void setConfig(const ZT_VirtualNetworkConfig *nwc) {
|
||||
char nwbuf[17] = {};
|
||||
const char* nwid = Utils::hex(nwc->nwid, nwbuf);
|
||||
fprintf(stderr, "NetworkState::setConfig(%s)\n", nwid);
|
||||
// fprintf(stderr, "NetworkState::setConfig(%s)\n", nwid);
|
||||
|
||||
memcpy(&_config, nwc, sizeof(ZT_VirtualNetworkConfig));
|
||||
fprintf(stderr, "ssoEnabled: %s, ssoVersion: %d\n",
|
||||
_config.ssoEnabled ? "true" : "false", _config.ssoVersion);
|
||||
// fprintf(stderr, "ssoEnabled: %s, ssoVersion: %d\n",
|
||||
// _config.ssoEnabled ? "true" : "false", _config.ssoVersion);
|
||||
|
||||
if (_config.ssoEnabled && _config.ssoVersion == 1) {
|
||||
fprintf(stderr, "ssoEnabled for %s\n", nwid);
|
||||
// fprintf(stderr, "ssoEnabled for %s\n", nwid);
|
||||
if (_idc == nullptr)
|
||||
{
|
||||
assert(_config.issuerURL != nullptr);
|
||||
assert(_config.ssoClientID != nullptr);
|
||||
assert(_config.centralAuthURL != nullptr);
|
||||
|
||||
fprintf(stderr, "Issuer URL: %s\n", _config.issuerURL);
|
||||
fprintf(stderr, "Client ID: %s\n", _config.ssoClientID);
|
||||
fprintf(stderr, "Central Auth URL: %s\n", _config.centralAuthURL);
|
||||
// fprintf(stderr, "Issuer URL: %s\n", _config.issuerURL);
|
||||
// fprintf(stderr, "Client ID: %s\n", _config.ssoClientID);
|
||||
// fprintf(stderr, "Central Auth URL: %s\n", _config.centralAuthURL);
|
||||
|
||||
char buf[17] = {};
|
||||
_idc = zeroidc::zeroidc_new(
|
||||
@ -281,7 +281,7 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "idc created (%s, %s, %s)\n", _config.issuerURL, _config.ssoClientID, _config.centralAuthURL);
|
||||
// fprintf(stderr, "idc created (%s, %s, %s)\n", _config.issuerURL, _config.ssoClientID, _config.centralAuthURL);
|
||||
}
|
||||
|
||||
if (_ainfo != nullptr) {
|
||||
|
13
zeroidc/Cargo.lock
generated
13
zeroidc/Cargo.lock
generated
@ -108,7 +108,7 @@ dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"time",
|
||||
"time 0.1.43",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@ -1144,6 +1144,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.0"
|
||||
@ -1489,5 +1499,6 @@ dependencies = [
|
||||
"openidconnect",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"time 0.3.5",
|
||||
"url",
|
||||
]
|
||||
|
@ -18,6 +18,7 @@ url = "2.2.2"
|
||||
reqwest = "0.11.7"
|
||||
jsonwebtoken = "7.2.0"
|
||||
serde = "1.0.130"
|
||||
time = { version = "0.3.5", features = ["formatting"] }
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = "0.20.0"
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
use url::{Url, ParseError};
|
||||
use url::{Url};
|
||||
|
||||
use crate::{AuthInfo, ZeroIDC};
|
||||
|
||||
@ -101,23 +101,23 @@ pub extern "C" fn zeroidc_get_exp_time(ptr: *mut ZeroIDC) -> u64 {
|
||||
id.get_exp_time()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn zeroidc_process_form_post(ptr: *mut ZeroIDC, body: *const c_char) -> bool {
|
||||
let idc = unsafe {
|
||||
assert!(!ptr.is_null());
|
||||
&mut *ptr
|
||||
};
|
||||
// #[no_mangle]
|
||||
// pub extern "C" fn zeroidc_process_form_post(ptr: *mut ZeroIDC, body: *const c_char) -> bool {
|
||||
// let idc = unsafe {
|
||||
// assert!(!ptr.is_null());
|
||||
// &mut *ptr
|
||||
// };
|
||||
|
||||
if body.is_null() {
|
||||
println!("body is null");
|
||||
return false
|
||||
}
|
||||
// if body.is_null() {
|
||||
// println!("body is null");
|
||||
// return false
|
||||
// }
|
||||
|
||||
let body = unsafe { CStr::from_ptr(body) }
|
||||
.to_str().unwrap().to_string();
|
||||
// let body = unsafe { CStr::from_ptr(body) }
|
||||
// .to_str().unwrap().to_string();
|
||||
|
||||
false
|
||||
}
|
||||
// false
|
||||
// }
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn zeroidc_get_auth_info(
|
||||
|
@ -2,11 +2,13 @@ pub mod ext;
|
||||
|
||||
extern crate base64;
|
||||
extern crate openidconnect;
|
||||
extern crate time;
|
||||
extern crate url;
|
||||
|
||||
use std::time::{SystemTime, UNIX_EPOCH, Duration};
|
||||
use time::{OffsetDateTime, format_description};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread::{sleep, spawn, JoinHandle};
|
||||
use std::time::Duration;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType};
|
||||
use openidconnect::reqwest::http_client;
|
||||
@ -50,6 +52,23 @@ pub struct AuthInfo {
|
||||
pkce_verifier: Option<PkceCodeVerifier>,
|
||||
}
|
||||
|
||||
fn systemtime_strftime<T>(dt: T, format: &str) -> String
|
||||
where T: Into<OffsetDateTime>
|
||||
{
|
||||
let f = format_description::parse(format);
|
||||
match f {
|
||||
Ok(f) => {
|
||||
match dt.into().format(&f) {
|
||||
Ok(s) => s,
|
||||
Err(_e) => "".to_string(),
|
||||
}
|
||||
},
|
||||
Err(_e) => {
|
||||
"".to_string()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl ZeroIDC {
|
||||
fn new(
|
||||
network_id: &str,
|
||||
@ -124,10 +143,84 @@ impl ZeroIDC {
|
||||
let inner_local = Arc::clone(&self.inner);
|
||||
(*local.lock().unwrap()).oidc_thread = Some(spawn(move || {
|
||||
(*inner_local.lock().unwrap()).running = true;
|
||||
let mut running = true;
|
||||
|
||||
while running {
|
||||
let exp = UNIX_EPOCH + Duration::from_secs((*inner_local.lock().unwrap()).exp_time);
|
||||
let now = SystemTime::now();
|
||||
|
||||
println!("refresh token thread tick, now: {}, exp: {}", systemtime_strftime(now, "[year]-[month]-[day] [hour]:[minute]:[second]"), systemtime_strftime(exp, "[year]-[month]-[day] [hour]:[minute]:[second]"));
|
||||
let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone();
|
||||
if let Some(refresh_token) = refresh_token {
|
||||
if now >= (exp - Duration::from_secs(15)) {
|
||||
let token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| {
|
||||
let res = c.exchange_refresh_token(&refresh_token)
|
||||
.request(http_client);
|
||||
|
||||
res
|
||||
|
||||
});
|
||||
|
||||
if let Some(res) = token_response {
|
||||
if let Ok(res) = res {
|
||||
let id_token = res.id_token();
|
||||
|
||||
if let Some(id_token) = id_token {
|
||||
let params = [("id_token", id_token.to_string()),("state", "refresh".to_string())];
|
||||
let client = reqwest::blocking::Client::new();
|
||||
let r = client.post((*inner_local.lock().unwrap()).auth_endpoint.clone())
|
||||
.form(¶ms)
|
||||
.send();
|
||||
|
||||
match r {
|
||||
Ok(r) => {
|
||||
if r.status().is_success() {
|
||||
println!("hit url: {}", r.url().as_str());
|
||||
println!("status: {}", r.status());
|
||||
|
||||
|
||||
let access_token = res.access_token();
|
||||
let at = access_token.secret();
|
||||
let exp = dangerous_insecure_decode::<Exp>(&at);
|
||||
|
||||
if let Ok(e) = exp {
|
||||
(*inner_local.lock().unwrap()).exp_time = e.claims.exp
|
||||
}
|
||||
|
||||
(*inner_local.lock().unwrap()).access_token = Some(access_token.clone());
|
||||
if let Some(t) = res.refresh_token() {
|
||||
println!("New Refresh Token: {}", t.secret());
|
||||
(*inner_local.lock().unwrap()).refresh_token = Some(t.clone());
|
||||
}
|
||||
println!("Central post succeeded");
|
||||
} else {
|
||||
println!("Central post failed: {}", r.status().to_string());
|
||||
println!("hit url: {}", r.url().as_str());
|
||||
println!("Status: {}", r.status());
|
||||
(*inner_local.lock().unwrap()).exp_time = 0;
|
||||
(*inner_local.lock().unwrap()).running = false;
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Central post failed: {}", e.to_string());
|
||||
println!("hit url: {}", e.url().unwrap().as_str());
|
||||
println!("Status: {}", e.status().unwrap());
|
||||
// (*inner_local.lock().unwrap()).exp_time = 0;
|
||||
(*inner_local.lock().unwrap()).running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("waiting to refresh");
|
||||
}
|
||||
} else {
|
||||
println!("no refresh token?");
|
||||
}
|
||||
|
||||
while (*inner_local.lock().unwrap()).running {
|
||||
println!("tick");
|
||||
sleep(Duration::from_secs(1));
|
||||
running = (*inner_local.lock().unwrap()).running;
|
||||
}
|
||||
|
||||
println!("thread done!")
|
||||
@ -207,12 +300,14 @@ impl ZeroIDC {
|
||||
(*self.inner.lock().unwrap()).access_token = Some(tok.access_token().clone());
|
||||
if let Some(t) = tok.refresh_token() {
|
||||
(*self.inner.lock().unwrap()).refresh_token = Some(t.clone());
|
||||
self.start();
|
||||
}
|
||||
},
|
||||
Err(res) => {
|
||||
println!("hit url: {}", res.url().unwrap().as_str());
|
||||
println!("Status: {}", res.status().unwrap());
|
||||
println!("Post error: {}", res.to_string());
|
||||
(*self.inner.lock().unwrap()).exp_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,7 +341,7 @@ impl ZeroIDC {
|
||||
.add_extra_param("network_id", network_id)
|
||||
.url();
|
||||
|
||||
println!("URL: {}", auth_url);
|
||||
// println!("URL: {}", auth_url);
|
||||
|
||||
return AuthInfo {
|
||||
url: auth_url,
|
||||
|
Loading…
x
Reference in New Issue
Block a user