summaryrefslogtreecommitdiff
path: root/src/api/core/accounts.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/core/accounts.rs')
-rw-r--r--src/api/core/accounts.rs176
1 files changed, 89 insertions, 87 deletions
diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs
index f9822629..71609b37 100644
--- a/src/api/core/accounts.rs
+++ b/src/api/core/accounts.rs
@@ -1,5 +1,5 @@
use crate::db::DbPool;
-use chrono::{SecondsFormat, Utc};
+use chrono::Utc;
use rocket::serde::json::Json;
use serde_json::Value;
@@ -13,7 +13,7 @@ use crate::{
crypto,
db::{models::*, DbConn},
mail,
- util::NumberOrString,
+ util::{format_date, NumberOrString},
CONFIG,
};
@@ -901,14 +901,12 @@ pub async fn _prelogin(data: Json<PreloginData>, mut conn: DbConn) -> Json<Value
None => (User::CLIENT_KDF_TYPE_DEFAULT, User::CLIENT_KDF_ITER_DEFAULT, None, None),
};
- let result = json!({
+ Json(json!({
"kdf": kdf_type,
"kdfIterations": kdf_iter,
"kdfMemory": kdf_mem,
"kdfParallelism": kdf_para,
- });
-
- Json(result)
+ }))
}
// https://github.com/bitwarden/server/blob/master/src/Api/Models/Request/Accounts/SecretVerificationRequestModel.cs
@@ -1084,14 +1082,15 @@ struct AuthRequestRequest {
device_identifier: String,
email: String,
public_key: String,
- #[serde(alias = "type")]
- _type: i32,
+ // Not used for now
+ // #[serde(alias = "type")]
+ // _type: i32,
}
#[post("/auth-requests", data = "<data>")]
async fn post_auth_request(
data: Json<AuthRequestRequest>,
- headers: ClientHeaders,
+ client_headers: ClientHeaders,
mut conn: DbConn,
nt: Notify<'_>,
) -> JsonResult {
@@ -1099,16 +1098,20 @@ async fn post_auth_request(
let user = match User::find_by_mail(&data.email, &mut conn).await {
Some(user) => user,
- None => {
- err!("AuthRequest doesn't exist")
- }
+ None => err!("AuthRequest doesn't exist", "User not found"),
};
+ // Validate device uuid and type
+ match Device::find_by_uuid_and_user(&data.device_identifier, &user.uuid, &mut conn).await {
+ Some(device) if device.atype == client_headers.device_type => {}
+ _ => err!("AuthRequest doesn't exist", "Device verification failed"),
+ }
+
let mut auth_request = AuthRequest::new(
user.uuid.clone(),
data.device_identifier.clone(),
- headers.device_type,
- headers.ip.ip.to_string(),
+ client_headers.device_type,
+ client_headers.ip.ip.to_string(),
data.access_code,
data.public_key,
);
@@ -1123,7 +1126,7 @@ async fn post_auth_request(
"requestIpAddress": auth_request.request_ip,
"key": null,
"masterPasswordHash": null,
- "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
+ "creationDate": format_date(&auth_request.creation_date),
"responseDate": null,
"requestApproved": false,
"origin": CONFIG.domain_origin(),
@@ -1132,33 +1135,31 @@ async fn post_auth_request(
}
#[get("/auth-requests/<uuid>")]
-async fn get_auth_request(uuid: &str, mut conn: DbConn) -> JsonResult {
+async fn get_auth_request(uuid: &str, headers: Headers, mut conn: DbConn) -> JsonResult {
+ if headers.user.uuid != uuid {
+ err!("AuthRequest doesn't exist", "User uuid's do not match")
+ }
+
let auth_request = match AuthRequest::find_by_uuid(uuid, &mut conn).await {
Some(auth_request) => auth_request,
- None => {
- err!("AuthRequest doesn't exist")
- }
+ None => err!("AuthRequest doesn't exist", "Record not found"),
};
- let response_date_utc = auth_request
- .response_date
- .map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
-
- Ok(Json(json!(
- {
- "id": uuid,
- "publicKey": auth_request.public_key,
- "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(),
- "requestIpAddress": auth_request.request_ip,
- "key": auth_request.enc_key,
- "masterPasswordHash": auth_request.master_password_hash,
- "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
- "responseDate": response_date_utc,
- "requestApproved": auth_request.approved,
- "origin": CONFIG.domain_origin(),
- "object":"auth-request"
- }
- )))
+ let response_date_utc = auth_request.response_date.map(|response_date| format_date(&response_date));
+
+ Ok(Json(json!({
+ "id": uuid,
+ "publicKey": auth_request.public_key,
+ "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(),
+ "requestIpAddress": auth_request.request_ip,
+ "key": auth_request.enc_key,
+ "masterPasswordHash": auth_request.master_password_hash,
+ "creationDate": format_date(&auth_request.creation_date),
+ "responseDate": response_date_utc,
+ "requestApproved": auth_request.approved,
+ "origin": CONFIG.domain_origin(),
+ "object":"auth-request"
+ })))
}
#[derive(Debug, Deserialize)]
@@ -1174,6 +1175,7 @@ struct AuthResponseRequest {
async fn put_auth_request(
uuid: &str,
data: Json<AuthResponseRequest>,
+ headers: Headers,
mut conn: DbConn,
ant: AnonymousNotify<'_>,
nt: Notify<'_>,
@@ -1181,11 +1183,13 @@ async fn put_auth_request(
let data = data.into_inner();
let mut auth_request: AuthRequest = match AuthRequest::find_by_uuid(uuid, &mut conn).await {
Some(auth_request) => auth_request,
- None => {
- err!("AuthRequest doesn't exist")
- }
+ None => err!("AuthRequest doesn't exist", "Record not found"),
};
+ if headers.user.uuid != auth_request.user_uuid {
+ err!("AuthRequest doesn't exist", "User uuid's do not match")
+ }
+
auth_request.approved = Some(data.request_approved);
auth_request.enc_key = Some(data.key);
auth_request.master_password_hash = data.master_password_hash;
@@ -1197,59 +1201,57 @@ async fn put_auth_request(
nt.send_auth_response(&auth_request.user_uuid, &auth_request.uuid, data.device_identifier, &mut conn).await;
}
- let response_date_utc = auth_request
- .response_date
- .map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
-
- Ok(Json(json!(
- {
- "id": uuid,
- "publicKey": auth_request.public_key,
- "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(),
- "requestIpAddress": auth_request.request_ip,
- "key": auth_request.enc_key,
- "masterPasswordHash": auth_request.master_password_hash,
- "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
- "responseDate": response_date_utc,
- "requestApproved": auth_request.approved,
- "origin": CONFIG.domain_origin(),
- "object":"auth-request"
- }
- )))
+ let response_date_utc = auth_request.response_date.map(|response_date| format_date(&response_date));
+
+ Ok(Json(json!({
+ "id": uuid,
+ "publicKey": auth_request.public_key,
+ "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(),
+ "requestIpAddress": auth_request.request_ip,
+ "key": auth_request.enc_key,
+ "masterPasswordHash": auth_request.master_password_hash,
+ "creationDate": format_date(&auth_request.creation_date),
+ "responseDate": response_date_utc,
+ "requestApproved": auth_request.approved,
+ "origin": CONFIG.domain_origin(),
+ "object":"auth-request"
+ })))
}
#[get("/auth-requests/<uuid>/response?<code>")]
-async fn get_auth_request_response(uuid: &str, code: &str, mut conn: DbConn) -> JsonResult {
+async fn get_auth_request_response(
+ uuid: &str,
+ code: &str,
+ client_headers: ClientHeaders,
+ mut conn: DbConn,
+) -> JsonResult {
let auth_request = match AuthRequest::find_by_uuid(uuid, &mut conn).await {
Some(auth_request) => auth_request,
- None => {
- err!("AuthRequest doesn't exist")
- }
+ None => err!("AuthRequest doesn't exist", "User not found"),
};
- if !auth_request.check_access_code(code) {
- err!("Access code invalid doesn't exist")
+ if auth_request.device_type != client_headers.device_type
+ && auth_request.request_ip != client_headers.ip.ip.to_string()
+ && !auth_request.check_access_code(code)
+ {
+ err!("AuthRequest doesn't exist", "Invalid device, IP or code")
}
- let response_date_utc = auth_request
- .response_date
- .map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
-
- Ok(Json(json!(
- {
- "id": uuid,
- "publicKey": auth_request.public_key,
- "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(),
- "requestIpAddress": auth_request.request_ip,
- "key": auth_request.enc_key,
- "masterPasswordHash": auth_request.master_password_hash,
- "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
- "responseDate": response_date_utc,
- "requestApproved": auth_request.approved,
- "origin": CONFIG.domain_origin(),
- "object":"auth-request"
- }
- )))
+ let response_date_utc = auth_request.response_date.map(|response_date| format_date(&response_date));
+
+ Ok(Json(json!({
+ "id": uuid,
+ "publicKey": auth_request.public_key,
+ "requestDeviceType": DeviceType::from_i32(auth_request.device_type).to_string(),
+ "requestIpAddress": auth_request.request_ip,
+ "key": auth_request.enc_key,
+ "masterPasswordHash": auth_request.master_password_hash,
+ "creationDate": format_date(&auth_request.creation_date),
+ "responseDate": response_date_utc,
+ "requestApproved": auth_request.approved,
+ "origin": CONFIG.domain_origin(),
+ "object":"auth-request"
+ })))
}
#[get("/auth-requests")]
@@ -1261,7 +1263,7 @@ async fn get_auth_requests(headers: Headers, mut conn: DbConn) -> JsonResult {
.iter()
.filter(|request| request.approved.is_none())
.map(|request| {
- let response_date_utc = request.response_date.map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
+ let response_date_utc = request.response_date.map(|response_date| format_date(&response_date));
json!({
"id": request.uuid,
@@ -1270,7 +1272,7 @@ async fn get_auth_requests(headers: Headers, mut conn: DbConn) -> JsonResult {
"requestIpAddress": request.request_ip,
"key": request.enc_key,
"masterPasswordHash": request.master_password_hash,
- "creationDate": request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
+ "creationDate": format_date(&request.creation_date),
"responseDate": response_date_utc,
"requestApproved": request.approved,
"origin": CONFIG.domain_origin(),