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
replace domain with base_url
BlockListed committed Mar 19, 2024

Verified

This commit was signed with the committer’s verified signature.
BlockListed BlockListed
commit 17923c3fd0ca24a1d537c3e1e0d446f847ed0609
56 changes: 28 additions & 28 deletions src/auth.rs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have added several log:: entries here. log:: can be removed since those macro's should be callable directly.

But logging in this location could slow down the application a lot. Even though it only should do this during debug, it will do this for every call which will do something with that Struct.
If it is really needed to have this info here, i would then suggest to place it under trace! instead.

Original file line number Diff line number Diff line change
@@ -360,20 +360,20 @@ use crate::db::{
DbConn,
};

pub struct Domain {
pub domain: String,
pub struct BaseURL {
pub base_url: String,
}

#[rocket::async_trait]
impl<'r> FromRequest<'r> for Domain {
impl<'r> FromRequest<'r> for BaseURL {
type Error = &'static str;

async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = request.headers();

// Get host
// TODO: UPDATE THIS SECTION
let domain = if CONFIG.domain_set() {
let base_url = if CONFIG.domain_set() {
let host = if let Some(host) = headers.get_one("X-Forwarded-Host") {
host
} else if let Some(host) = headers.get_one("Host") {
@@ -385,13 +385,13 @@ impl<'r> FromRequest<'r> for Domain {
todo!()
};

let Some(domain) = CONFIG.host_to_domain(host) else {
let Some(base_url) = CONFIG.host_to_base_url(host) else {
// TODO fix error handling
// This is probably a 421 misdirected request.
todo!()
};

domain
base_url
} else if let Some(referer) = headers.get_one("Referer") {
referer.to_string()
} else {
@@ -417,14 +417,14 @@ impl<'r> FromRequest<'r> for Domain {
format!("{protocol}://{host}")
};

Outcome::Success(Domain {
domain,
Outcome::Success(BaseURL {
base_url,
})
}
}

pub struct ClientHeaders {
pub domain: String,
pub base_url: String,
pub device_type: i32,
pub ip: ClientIp,
}
@@ -434,7 +434,7 @@ impl<'r> FromRequest<'r> for ClientHeaders {
type Error = &'static str;

async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let domain = try_outcome!(Domain::from_request(request).await).domain;
let base_url = try_outcome!(Domain::from_request(request).await).base_url;
let ip = match ClientIp::from_request(request).await {
Outcome::Success(ip) => ip,
_ => err_handler!("Error getting Client IP"),
@@ -444,15 +444,15 @@ impl<'r> FromRequest<'r> for ClientHeaders {
request.headers().get_one("device-type").map(|d| d.parse().unwrap_or(14)).unwrap_or_else(|| 14);

Outcome::Success(ClientHeaders {
domain,
base_url,
device_type,
ip,
})
}
}

pub struct Headers {
pub domain: String,
pub base_url: String,
pub device: Device,
pub user: User,
pub ip: ClientIp,
@@ -465,7 +465,7 @@ impl<'r> FromRequest<'r> for Headers {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let headers = request.headers();

let domain = try_outcome!(Domain::from_request(request).await).domain;
let base_url = try_outcome!(BaseURL::from_request(request).await).base_url;
let ip = match ClientIp::from_request(request).await {
Outcome::Success(ip) => ip,
_ => err_handler!("Error getting Client IP"),
@@ -536,7 +536,7 @@ impl<'r> FromRequest<'r> for Headers {
}

Outcome::Success(Headers {
domain,
base_url,
device,
user,
ip,
@@ -545,7 +545,7 @@ impl<'r> FromRequest<'r> for Headers {
}

pub struct OrgHeaders {
pub domain: String,
pub base_url: String,
pub device: Device,
pub user: User,
pub org_user_type: UserOrgType,
@@ -601,7 +601,7 @@ impl<'r> FromRequest<'r> for OrgHeaders {
};

Outcome::Success(Self {
domain: headers.domain,
base_url: headers.base_url,
device: headers.device,
user,
org_user_type: {
@@ -623,7 +623,7 @@ impl<'r> FromRequest<'r> for OrgHeaders {
}

pub struct AdminHeaders {
pub domain: String,
pub base_url: String,
pub device: Device,
pub user: User,
pub org_user_type: UserOrgType,
@@ -640,7 +640,7 @@ impl<'r> FromRequest<'r> for AdminHeaders {
let client_version = request.headers().get_one("Bitwarden-Client-Version").map(String::from);
if headers.org_user_type >= UserOrgType::Admin {
Outcome::Success(Self {
domain: headers.domain,
base_url: headers.base_url,
device: headers.device,
user: headers.user,
org_user_type: headers.org_user_type,
@@ -656,7 +656,7 @@ impl<'r> FromRequest<'r> for AdminHeaders {
impl From<AdminHeaders> for Headers {
fn from(h: AdminHeaders) -> Headers {
Headers {
domain: h.domain,
base_url: h.base_url,
device: h.device,
user: h.user,
ip: h.ip,
@@ -687,7 +687,7 @@ fn get_col_id(request: &Request<'_>) -> Option<String> {
/// and have access to the specific collection provided via the <col_id>/collections/collectionId.
/// This does strict checking on the collection_id, ManagerHeadersLoose does not.
pub struct ManagerHeaders {
pub domain: String,
pub base_url: String,
pub device: Device,
pub user: User,
pub org_user_type: UserOrgType,
@@ -716,7 +716,7 @@ impl<'r> FromRequest<'r> for ManagerHeaders {
}

Outcome::Success(Self {
domain: headers.domain,
base_url: headers.base_url,
device: headers.device,
user: headers.user,
org_user_type: headers.org_user_type,
@@ -731,7 +731,7 @@ impl<'r> FromRequest<'r> for ManagerHeaders {
impl From<ManagerHeaders> for Headers {
fn from(h: ManagerHeaders) -> Headers {
Headers {
domain: h.domain,
base_url: h.base_url,
device: h.device,
user: h.user,
ip: h.ip,
@@ -742,7 +742,7 @@ impl From<ManagerHeaders> for Headers {
/// The ManagerHeadersLoose is used when you at least need to be a Manager,
/// but there is no collection_id sent with the request (either in the path or as form data).
pub struct ManagerHeadersLoose {
pub domain: String,
pub base_url: String,
pub device: Device,
pub user: User,
pub org_user: UserOrganization,
@@ -758,7 +758,7 @@ impl<'r> FromRequest<'r> for ManagerHeadersLoose {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.org_user_type >= UserOrgType::Manager {
Outcome::Success(Self {
domain: headers.domain,
base_url: headers.base_url,
device: headers.device,
user: headers.user,
org_user: headers.org_user,
@@ -774,7 +774,7 @@ impl<'r> FromRequest<'r> for ManagerHeadersLoose {
impl From<ManagerHeadersLoose> for Headers {
fn from(h: ManagerHeadersLoose) -> Headers {
Headers {
domain: h.domain,
base_url: h.base_url,
device: h.device,
user: h.user,
ip: h.ip,
@@ -802,7 +802,7 @@ impl ManagerHeaders {
}

Ok(ManagerHeaders {
domain: h.domain,
base_url: h.base_url,
device: h.device,
user: h.user,
org_user_type: h.org_user_type,
@@ -812,7 +812,7 @@ impl ManagerHeaders {
}

pub struct OwnerHeaders {
pub host: String,
pub base_url: String,
pub device: Device,
pub user: User,
pub ip: ClientIp,
@@ -826,7 +826,7 @@ impl<'r> FromRequest<'r> for OwnerHeaders {
let headers = try_outcome!(OrgHeaders::from_request(request).await);
if headers.org_user_type == UserOrgType::Owner {
Outcome::Success(Self {
host: headers.host,
base_url: headers.base_url,
device: headers.device,
user: headers.user,
ip: headers.ip,