fix oidc login

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-05-30 15:32:19 +08:00
parent b9fd9f343f
commit c28387c8c6
6 changed files with 93 additions and 23 deletions

1
Cargo.lock generated
View File

@ -5250,6 +5250,7 @@ dependencies = [
"serde 1.0.163",
"serde_derive",
"serde_json 1.0.96",
"serde_repr",
"sha2",
"shared_memory",
"shutdown_hooks",

View File

@ -43,6 +43,7 @@ hbb_common = { path = "libs/hbb_common" }
serde_derive = "1.0"
serde = "1.0"
serde_json = "1.0"
serde_repr = "0.1"
cfg-if = "1.0"
lazy_static = "1.4"
sha2 = "0.10"

View File

@ -95,11 +95,13 @@ class ConfigOP {
class WidgetOP extends StatefulWidget {
final ConfigOP config;
final RxString curOP;
final RxBool autoLogin;
final Function(String) cbLogin;
const WidgetOP({
Key? key,
required this.config,
required this.curOP,
required this.autoLogin,
required this.cbLogin,
}) : super(key: key);
@ -188,7 +190,7 @@ class _WidgetOPState extends State<WidgetOP> {
onTap: () async {
_resetState();
widget.curOP.value = widget.config.op;
await bind.mainAccountAuth(op: widget.config.op);
await bind.mainAccountAuth(op: widget.config.op, rememberMe: widget.autoLogin.value);
_beginQueryState();
},
),
@ -254,12 +256,14 @@ class _WidgetOPState extends State<WidgetOP> {
class LoginWidgetOP extends StatelessWidget {
final List<ConfigOP> ops;
final RxString curOP;
final RxBool autoLogin;
final Function(String) cbLogin;
LoginWidgetOP({
Key? key,
required this.ops,
required this.curOP,
required this.autoLogin,
required this.cbLogin,
}) : super(key: key);
@ -270,6 +274,7 @@ class LoginWidgetOP extends StatelessWidget {
WidgetOP(
config: op,
curOP: curOP,
autoLogin: autoLogin,
cbLogin: cbLogin,
),
const Divider(
@ -500,6 +505,7 @@ Future<bool?> loginDialog() async {
ConfigOP(op: 'Okta', iconWidth: 38),
],
curOP: curOP,
autoLogin: autoLogin,
cbLogin: (String username) {
gFFI.userModel.userName.value = username;
close(true);

View File

@ -1359,10 +1359,10 @@ pub fn install_install_path() -> SyncReturn<String> {
SyncReturn(install_path())
}
pub fn main_account_auth(op: String) {
pub fn main_account_auth(op: String, remember_me: bool) {
let id = get_id();
let uuid = get_uuid();
account_auth(op, id, uuid);
account_auth(op, id, uuid, remember_me);
}
pub fn main_account_auth_cancel() {

View File

@ -5,6 +5,7 @@ use hbb_common::{
};
use reqwest::blocking::Client;
use serde_derive::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::{
collections::HashMap,
sync::{Arc, RwLock},
@ -30,21 +31,80 @@ pub struct OidcAuthUrl {
url: Url,
}
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
pub struct DeviceInfo {
/// Linux , Windows , Android ...
#[serde(default)]
pub os: String,
/// `browser` or `client`
#[serde(default)]
pub r#type: String,
/// device name from rustdesk client,
/// browser info(name + version) from browser
#[serde(default)]
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct WhitelistItem {
data: String, // ip / device uuid
info: DeviceInfo,
exp: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct UserInfo {
#[serde(default)]
pub settings: UserSettings,
#[serde(default)]
pub login_ip_whitelist: Vec<WhitelistItem>,
#[serde(default)]
pub login_device_whitelist: Vec<WhitelistItem>,
#[serde(default)]
pub other: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct UserSettings {
#[serde(default)]
pub email_verification: bool,
#[serde(default)]
pub email_alarm_notification: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize_repr, Deserialize_repr)]
#[repr(i64)]
pub enum UserStatus {
Disabled = 0,
Normal = 1,
Unverified = -1,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize_repr, Deserialize_repr)]
#[repr(i64)]
pub enum UserRole {
Owner = 10,
Admin = 1,
Member = 0,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserPayload {
pub id: String,
pub name: String,
pub email: Option<String>,
pub note: Option<String>,
pub status: Option<i64>,
pub grp: Option<String>,
pub is_admin: Option<bool>,
pub status: UserStatus,
pub info: UserInfo,
pub role: UserRole,
pub is_admin: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthBody {
pub access_token: String,
pub token_type: String,
pub r#type: String,
pub user: UserPayload,
}
@ -128,7 +188,7 @@ impl OidcSession {
std::thread::sleep(std::time::Duration::from_secs_f32(secs));
}
fn auth_task(op: String, id: String, uuid: String) {
fn auth_task(op: String, id: String, uuid: String, remember_me: bool) {
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 {
@ -167,14 +227,16 @@ impl OidcSession {
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(),
);
if remember_me {
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()
.unwrap()
@ -226,12 +288,12 @@ impl OidcSession {
}
}
pub fn account_auth(op: String, id: String, uuid: String) {
pub fn account_auth(op: String, id: String, uuid: String, remember_me: bool) {
Self::auth_cancel();
Self::wait_stop_querying();
OIDC_SESSION.write().unwrap().before_task();
std::thread::spawn(|| {
Self::auth_task(op, id, uuid);
std::thread::spawn(move || {
Self::auth_task(op, id, uuid, remember_me);
OIDC_SESSION.write().unwrap().after_task();
});
}

View File

@ -822,8 +822,8 @@ fn check_connect_status(reconnect: bool) -> mpsc::UnboundedSender<ipc::Data> {
}
#[cfg(feature = "flutter")]
pub fn account_auth(op: String, id: String, uuid: String) {
account::OidcSession::account_auth(op, id, uuid);
pub fn account_auth(op: String, id: String, uuid: String, remember_me: bool) {
account::OidcSession::account_auth(op, id, uuid, remember_me);
}
#[cfg(feature = "flutter")]