Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple domains support #3870

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
80d3c61
add configuration support for multiple domains
BlockListed Sep 9, 2023
40edfa5
implement mutli domain support for auth headers
BlockListed Sep 9, 2023
303eb30
remove domain_paths hashmap, since it's no longer used
BlockListed Sep 9, 2023
17923c3
replace domain with base_url
BlockListed Sep 9, 2023
0ebd877
make admin work with multi-domains
BlockListed Sep 9, 2023
2c7b739
make fido app-id.json work with multi-domains
BlockListed Sep 9, 2023
e313745
make domain protocol validation work with multi-domains
BlockListed Sep 9, 2023
0d7e678
make mail work with multi-domains
BlockListed Sep 9, 2023
5462b97
make cors work with multi-domains
BlockListed Sep 9, 2023
f82a142
get domain and origin with single extractor
BlockListed Sep 9, 2023
b5dea32
make attachments / ciphers support multi-domains
BlockListed Sep 9, 2023
968ed8a
make sends support multi-domain
BlockListed Sep 9, 2023
42e1018
make admin support hostinfo
BlockListed Sep 9, 2023
12c0005
make webauthn support multi-domain
BlockListed Sep 9, 2023
ac3c1d4
make web support hostinfo
BlockListed Sep 9, 2023
6867099
make headers use hostinfo
BlockListed Sep 9, 2023
2670db1
make accounts support multi-domains
BlockListed Sep 9, 2023
81dd479
make ciphers work with multi-domains
BlockListed Sep 9, 2023
3421dfc
make emergency access work with multi-domains
BlockListed Sep 9, 2023
ab96b26
make getting config work with multi-domains
BlockListed Sep 9, 2023
901bf57
make organizations work with multi-domains
BlockListed Sep 9, 2023
df524c7
make PublicToken support multi-domains
BlockListed Sep 9, 2023
7639a2b
make identity support multi-domains
BlockListed Sep 9, 2023
1dfc68a
make auth support multi-domains
BlockListed Sep 9, 2023
f208630
fix issue in config
BlockListed Sep 9, 2023
c0db0d8
make clippy happy
BlockListed Sep 9, 2023
3a66772
use single hashmap instead of two for domain lookups
BlockListed Sep 9, 2023
12bdcd4
clippy and format
BlockListed Sep 9, 2023
fc78b6f
implement error handling for HostInfo extractor
BlockListed Sep 9, 2023
d627b02
remove admin_path function
BlockListed Sep 9, 2023
96261f1
remove breaking parameter from to_json methods
BlockListed Sep 9, 2023
edcd264
cargo clippy and cargo fmt
BlockListed Sep 9, 2023
09c0367
re-add domain_origin field to configuration
BlockListed Sep 9, 2023
298cf8a
change back name of domain configuration option
BlockListed Sep 9, 2023
335984e
cargo clippy and cargo fmt
BlockListed Sep 9, 2023
d1cb726
fix bug when extracing host from domain
BlockListed Sep 9, 2023
6375a20
cargo clippy and cargo fmt
BlockListed Sep 9, 2023
aceaf61
switch back to admin_path, since cookies break otherwise
BlockListed Sep 9, 2023
fae770a
remove some outdated comments / move import
BlockListed Sep 9, 2023
c150818
rebase and fix rebase issues
BlockListed Mar 19, 2024
158f834
Merge branch 'main' into multiple-domains-support
BlackDex May 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
make identity support multi-domains
  • Loading branch information
BlockListed committed Mar 19, 2024

Verified

This commit was signed with the committer’s verified signature.
BlockListed BlockListed
commit 7639a2b03d212097feba2cd012c2eaa872ad9210
22 changes: 13 additions & 9 deletions src/api/identity.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ use crate::{
push::register_push_device,
ApiResult, EmptyResult, JsonResult, JsonUpcase,
},
auth::{generate_organization_api_key_login_claims, ClientHeaders, ClientIp},
auth::{generate_organization_api_key_login_claims, ClientHeaders, ClientIp, HostInfo},
db::{models::*, DbConn},
error::MapResult,
mail, util, CONFIG,
@@ -28,7 +28,7 @@ pub fn routes() -> Vec<Route> {
}

#[post("/connect/token", data = "<data>")]
async fn login(data: Form<ConnectData>, client_header: ClientHeaders, mut conn: DbConn) -> JsonResult {
async fn login(data: Form<ConnectData>, client_header: ClientHeaders, host_info: HostInfo, mut conn: DbConn) -> JsonResult {
let data: ConnectData = data.into_inner();

let mut user_uuid: Option<String> = None;
@@ -48,7 +48,7 @@ async fn login(data: Form<ConnectData>, client_header: ClientHeaders, mut conn:
_check_is_some(&data.device_name, "device_name cannot be blank")?;
_check_is_some(&data.device_type, "device_type cannot be blank")?;

_password_login(data, &mut user_uuid, &mut conn, &client_header.ip).await
_password_login(data, &mut user_uuid, &mut conn, &client_header.ip, &host_info.base_url, &host_info.origin).await
}
"client_credentials" => {
_check_is_some(&data.client_id, "client_id cannot be blank")?;
@@ -140,6 +140,8 @@ async fn _password_login(
user_uuid: &mut Option<String>,
conn: &mut DbConn,
ip: &ClientIp,
base_url: &str,
origin: &str,
) -> JsonResult {
// Validate scope
let scope = data.scope.as_ref().unwrap();
@@ -250,7 +252,7 @@ async fn _password_login(

let (mut device, new_device) = get_device(&data, conn, &user).await;

let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, conn).await?;
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, base_url, origin, conn).await?;

if CONFIG.mail_enabled() && new_device {
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name).await {
@@ -480,6 +482,8 @@ async fn twofactor_auth(
data: &ConnectData,
device: &mut Device,
ip: &ClientIp,
base_url: &str,
origin: &str,
conn: &mut DbConn,
) -> ApiResult<Option<String>> {
let twofactors = TwoFactor::find_by_user(&user.uuid, conn).await;
@@ -497,7 +501,7 @@ async fn twofactor_auth(

let twofactor_code = match data.two_factor_token {
Some(ref code) => code,
None => err_json!(_json_err_twofactor(&twofactor_ids, &user.uuid, conn).await?, "2FA token not provided"),
None => err_json!(_json_err_twofactor(&twofactor_ids, &user.uuid, base_url, origin, conn).await?, "2FA token not provided"),
};

let selected_twofactor = twofactors.into_iter().find(|tf| tf.atype == selected_id && tf.enabled);
@@ -511,7 +515,7 @@ async fn twofactor_auth(
Some(TwoFactorType::Authenticator) => {
authenticator::validate_totp_code_str(&user.uuid, twofactor_code, &selected_data?, ip, conn).await?
}
Some(TwoFactorType::Webauthn) => webauthn::validate_webauthn_login(&user.uuid, twofactor_code, conn).await?,
Some(TwoFactorType::Webauthn) => webauthn::validate_webauthn_login(&user.uuid, twofactor_code, base_url, origin, conn).await?,
Some(TwoFactorType::YubiKey) => yubikey::validate_yubikey_login(twofactor_code, &selected_data?).await?,
Some(TwoFactorType::Duo) => {
duo::validate_duo_login(data.username.as_ref().unwrap().trim(), twofactor_code, conn).await?
@@ -527,7 +531,7 @@ async fn twofactor_auth(
}
_ => {
err_json!(
_json_err_twofactor(&twofactor_ids, &user.uuid, conn).await?,
_json_err_twofactor(&twofactor_ids, &user.uuid, base_url, origin, conn).await?,
"2FA Remember token not provided"
)
}
@@ -555,7 +559,7 @@ fn _selected_data(tf: Option<TwoFactor>) -> ApiResult<String> {
tf.map(|t| t.data).map_res("Two factor doesn't exist")
}

async fn _json_err_twofactor(providers: &[i32], user_uuid: &str, conn: &mut DbConn) -> ApiResult<Value> {
async fn _json_err_twofactor(providers: &[i32], user_uuid: &str, base_url: &str, origin: &str, conn: &mut DbConn) -> ApiResult<Value> {
let mut result = json!({
"error" : "invalid_grant",
"error_description" : "Two factor required.",
@@ -570,7 +574,7 @@ async fn _json_err_twofactor(providers: &[i32], user_uuid: &str, conn: &mut DbCo
Some(TwoFactorType::Authenticator) => { /* Nothing to do for TOTP */ }

Some(TwoFactorType::Webauthn) if CONFIG.domain_set() => {
let request = webauthn::generate_webauthn_login(user_uuid, conn).await?;
let request = webauthn::generate_webauthn_login(user_uuid, base_url, origin, conn).await?;
result["TwoFactorProviders2"][provider.to_string()] = request.0;
}