Skip to content

Commit

Permalink
Add support for /api/devices/knowndevice with HTTP header params
Browse files Browse the repository at this point in the history
  • Loading branch information
jjlin committed Mar 11, 2023
1 parent f210899 commit daaa03d
Showing 1 changed file with 56 additions and 1 deletion.
57 changes: 56 additions & 1 deletion src/api/core/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ use crate::{
mail, CONFIG,
};

use rocket::{
http::Status,
request::{FromRequest, Outcome, Request},
};

pub fn routes() -> Vec<rocket::Route> {
routes![
register,
Expand Down Expand Up @@ -39,6 +44,7 @@ pub fn routes() -> Vec<rocket::Route> {
api_key,
rotate_api_key,
get_known_device,
get_known_device_from_path,
put_avatar,
]
}
Expand Down Expand Up @@ -872,12 +878,61 @@ async fn rotate_api_key(data: JsonUpcase<SecretVerificationRequest>, headers: He
_api_key(data, true, headers, conn).await
}

// This variant is deprecated: https://github.com/bitwarden/server/pull/2682
#[get("/devices/knowndevice/<email>/<uuid>")]
async fn get_known_device(email: String, uuid: String, mut conn: DbConn) -> JsonResult {
async fn get_known_device_from_path(email: String, uuid: String, mut conn: DbConn) -> JsonResult {
// This endpoint doesn't have auth header
let mut result = false;
if let Some(user) = User::find_by_mail(&email, &mut conn).await {
result = Device::find_by_uuid_and_user(&uuid, &user.uuid, &mut conn).await.is_some();
}
Ok(Json(json!(result)))
}

#[get("/devices/knowndevice")]
async fn get_known_device(device: KnownDevice, conn: DbConn) -> JsonResult {
get_known_device_from_path(device.email, device.uuid, conn).await
}

struct KnownDevice {
email: String,
uuid: String,
}

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

async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
let email = if let Some(email_b64) = req.headers().get_one("X-Request-Email") {
let email_bytes = match data_encoding::BASE64URL.decode(email_b64.as_bytes()) {
Ok(bytes) => bytes,
Err(_) => {
return Outcome::Failure((
Status::BadRequest,
"X-Request-Email value failed to decode as base64url",
));
}
};
match String::from_utf8(email_bytes) {
Ok(email) => email,
Err(_) => {
return Outcome::Failure((Status::BadRequest, "X-Request-Email value failed to decode as UTF-8"));
}
}
} else {
return Outcome::Failure((Status::BadRequest, "X-Request-Email value is required"));
};

let uuid = if let Some(uuid) = req.headers().get_one("X-Device-Identifier") {
uuid.to_string()
} else {
return Outcome::Failure((Status::BadRequest, "X-Device-Identifier value is required"));
};

Outcome::Success(KnownDevice {
email,
uuid,
})
}
}

0 comments on commit daaa03d

Please sign in to comment.