Skip to content

Commit

Permalink
Merge pull request #3332 from BlackDex/merge-clientip-with-headers
Browse files Browse the repository at this point in the history
Merge ClientIp with Headers.
  • Loading branch information
dani-garcia authored Mar 15, 2023
2 parents 6b5618a + 9e5b949 commit 729b563
Show file tree
Hide file tree
Showing 17 changed files with 256 additions and 422 deletions.
37 changes: 19 additions & 18 deletions src/api/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ async fn get_user_json(uuid: String, _token: AdminToken, mut conn: DbConn) -> Js
}

#[post("/users/<uuid>/delete")]
async fn delete_user(uuid: String, _token: AdminToken, mut conn: DbConn, ip: ClientIp) -> EmptyResult {
async fn delete_user(uuid: String, token: AdminToken, mut conn: DbConn) -> EmptyResult {
let user = get_user_or_404(&uuid, &mut conn).await?;

// Get the user_org records before deleting the actual user
Expand All @@ -383,7 +383,7 @@ async fn delete_user(uuid: String, _token: AdminToken, mut conn: DbConn, ip: Cli
user_org.org_uuid,
String::from(ACTING_ADMIN_USER),
14, // Use UnknownBrowser type
&ip.ip,
&token.ip.ip,
&mut conn,
)
.await;
Expand Down Expand Up @@ -443,12 +443,7 @@ struct UserOrgTypeData {
}

#[post("/users/org_type", data = "<data>")]
async fn update_user_org_type(
data: Json<UserOrgTypeData>,
_token: AdminToken,
mut conn: DbConn,
ip: ClientIp,
) -> EmptyResult {
async fn update_user_org_type(data: Json<UserOrgTypeData>, token: AdminToken, mut conn: DbConn) -> EmptyResult {
let data: UserOrgTypeData = data.into_inner();

let mut user_to_edit =
Expand Down Expand Up @@ -489,7 +484,7 @@ async fn update_user_org_type(
data.org_uuid,
String::from(ACTING_ADMIN_USER),
14, // Use UnknownBrowser type
&ip.ip,
&token.ip.ip,
&mut conn,
)
.await;
Expand Down Expand Up @@ -724,15 +719,24 @@ async fn backup_db(_token: AdminToken, mut conn: DbConn) -> EmptyResult {
}
}

pub struct AdminToken {}
pub struct AdminToken {
ip: ClientIp,
}

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

async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let ip = match ClientIp::from_request(request).await {
Outcome::Success(ip) => ip,
_ => err_handler!("Error getting Client IP"),
};

if CONFIG.disable_admin_token() {
Outcome::Success(Self {})
Outcome::Success(Self {
ip,
})
} else {
let cookies = request.cookies();

Expand All @@ -741,19 +745,16 @@ impl<'r> FromRequest<'r> for AdminToken {
None => return Outcome::Failure((Status::Unauthorized, "Unauthorized")),
};

let ip = match ClientIp::from_request(request).await {
Outcome::Success(ip) => ip.ip,
_ => err_handler!("Error getting Client IP"),
};

if decode_admin(access_token).is_err() {
// Remove admin cookie
cookies.remove(Cookie::build(COOKIE_NAME, "").path(admin_path()).finish());
error!("Invalid or expired admin JWT. IP: {}.", ip);
error!("Invalid or expired admin JWT. IP: {}.", &ip.ip);
return Outcome::Failure((Status::Unauthorized, "Session expired"));
}

Outcome::Success(Self {})
Outcome::Success(Self {
ip,
})
}
}
}
16 changes: 5 additions & 11 deletions src/api/core/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
api::{
core::log_user_event, EmptyResult, JsonResult, JsonUpcase, Notify, NumberOrString, PasswordData, UpdateType,
},
auth::{decode_delete, decode_invite, decode_verify_email, ClientIp, Headers},
auth::{decode_delete, decode_invite, decode_verify_email, Headers},
crypto,
db::{models::*, DbConn},
mail, CONFIG,
Expand Down Expand Up @@ -311,7 +311,6 @@ async fn post_password(
data: JsonUpcase<ChangePassData>,
headers: Headers,
mut conn: DbConn,
ip: ClientIp,
nt: Notify<'_>,
) -> EmptyResult {
let data: ChangePassData = data.into_inner().data;
Expand All @@ -324,7 +323,8 @@ async fn post_password(
user.password_hint = clean_password_hint(&data.MasterPasswordHint);
enforce_password_hint_setting(&user.password_hint)?;

log_user_event(EventType::UserChangedPassword as i32, &user.uuid, headers.device.atype, &ip.ip, &mut conn).await;
log_user_event(EventType::UserChangedPassword as i32, &user.uuid, headers.device.atype, &headers.ip.ip, &mut conn)
.await;

user.set_password(
&data.NewMasterPasswordHash,
Expand Down Expand Up @@ -420,13 +420,7 @@ struct KeyData {
}

#[post("/accounts/key", data = "<data>")]
async fn post_rotatekey(
data: JsonUpcase<KeyData>,
headers: Headers,
mut conn: DbConn,
ip: ClientIp,
nt: Notify<'_>,
) -> EmptyResult {
async fn post_rotatekey(data: JsonUpcase<KeyData>, headers: Headers, mut conn: DbConn, nt: Notify<'_>) -> EmptyResult {
let data: KeyData = data.into_inner().data;

if !headers.user.check_valid_password(&data.MasterPasswordHash) {
Expand Down Expand Up @@ -472,7 +466,7 @@ async fn post_rotatekey(
// Prevent triggering cipher updates via WebSockets by settings UpdateType::None
// The user sessions are invalidated because all the ciphers were re-encrypted and thus triggering an update could cause issues.
// We force the users to logout after the user has been saved to try and prevent these issues.
update_cipher_from_data(&mut saved_cipher, cipher_data, &headers, false, &mut conn, &ip, &nt, UpdateType::None)
update_cipher_from_data(&mut saved_cipher, cipher_data, &headers, false, &mut conn, &nt, UpdateType::None)
.await?
}

Expand Down
Loading

0 comments on commit 729b563

Please sign in to comment.