summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/api/core/accounts.rs15
-rw-r--r--src/api/core/emergency_access.rs167
-rw-r--r--src/db/models/emergency_access.rs29
3 files changed, 116 insertions, 95 deletions
diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs
index da787ac7..a747f3ec 100644
--- a/src/api/core/accounts.rs
+++ b/src/api/core/accounts.rs
@@ -515,15 +515,12 @@ async fn post_rotatekey(data: Json<KeyData>, headers: Headers, mut conn: DbConn,
// Update emergency access data
for emergency_access_data in data.emergency_access_keys {
- let mut saved_emergency_access = match EmergencyAccess::find_by_uuid(&emergency_access_data.id, &mut conn).await
- {
- Some(emergency_access) => emergency_access,
- None => err!("Emergency access doesn't exist"),
- };
-
- if &saved_emergency_access.grantor_uuid != user_uuid {
- err!("The emergency access is not owned by the user")
- }
+ let mut saved_emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(&emergency_access_data.id, user_uuid, &mut conn).await
+ {
+ Some(emergency_access) => emergency_access,
+ None => err!("Emergency access doesn't exist or is not owned by the user"),
+ };
saved_emergency_access.key_encrypted = Some(emergency_access_data.key_encrypted);
saved_emergency_access.save(&mut conn).await?
diff --git a/src/api/core/emergency_access.rs b/src/api/core/emergency_access.rs
index 8f9e0015..1c29b774 100644
--- a/src/api/core/emergency_access.rs
+++ b/src/api/core/emergency_access.rs
@@ -93,10 +93,10 @@ async fn get_grantees(headers: Headers, mut conn: DbConn) -> Json<Value> {
}
#[get("/emergency-access/<emer_id>")]
-async fn get_emergency_access(emer_id: &str, mut conn: DbConn) -> JsonResult {
+async fn get_emergency_access(emer_id: &str, headers: Headers, mut conn: DbConn) -> JsonResult {
check_emergency_access_enabled()?;
- match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &headers.user.uuid, &mut conn).await {
Some(emergency_access) => Ok(Json(
emergency_access.to_json_grantee_details(&mut conn).await.expect("Grantee user should exist but does not!"),
)),
@@ -117,20 +117,31 @@ struct EmergencyAccessUpdateData {
}
#[put("/emergency-access/<emer_id>", data = "<data>")]
-async fn put_emergency_access(emer_id: &str, data: Json<EmergencyAccessUpdateData>, conn: DbConn) -> JsonResult {
- post_emergency_access(emer_id, data, conn).await
+async fn put_emergency_access(
+ emer_id: &str,
+ data: Json<EmergencyAccessUpdateData>,
+ headers: Headers,
+ conn: DbConn,
+) -> JsonResult {
+ post_emergency_access(emer_id, data, headers, conn).await
}
#[post("/emergency-access/<emer_id>", data = "<data>")]
-async fn post_emergency_access(emer_id: &str, data: Json<EmergencyAccessUpdateData>, mut conn: DbConn) -> JsonResult {
+async fn post_emergency_access(
+ emer_id: &str,
+ data: Json<EmergencyAccessUpdateData>,
+ headers: Headers,
+ mut conn: DbConn,
+) -> JsonResult {
check_emergency_access_enabled()?;
let data: EmergencyAccessUpdateData = data.into_inner();
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emergency_access) => emergency_access,
- None => err!("Emergency access not valid."),
- };
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &headers.user.uuid, &mut conn).await {
+ Some(emergency_access) => emergency_access,
+ None => err!("Emergency access not valid."),
+ };
let new_type = match EmergencyAccessType::from_str(&data.r#type.into_string()) {
Some(new_type) => new_type as i32,
@@ -155,17 +166,21 @@ async fn post_emergency_access(emer_id: &str, data: Json<EmergencyAccessUpdateDa
async fn delete_emergency_access(emer_id: &str, headers: Headers, mut conn: DbConn) -> EmptyResult {
check_emergency_access_enabled()?;
- let grantor_user = headers.user;
-
- let emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => {
- if emer.grantor_uuid != grantor_user.uuid && emer.grantee_uuid != Some(grantor_user.uuid) {
- err!("Emergency access not valid.")
- }
- emer
+ let emergency_access = match (
+ EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &headers.user.uuid, &mut conn).await,
+ EmergencyAccess::find_by_uuid_and_grantee_uuid(emer_id, &headers.user.uuid, &mut conn).await,
+ ) {
+ (Some(grantor_emer), None) => {
+ info!("Grantor deleted emergency access {emer_id}");
+ grantor_emer
}
- None => err!("Emergency access not valid."),
+ (None, Some(grantee_emer)) => {
+ info!("Grantee deleted emergency access {emer_id}");
+ grantee_emer
+ }
+ _ => err!("Emergency access not valid."),
};
+
emergency_access.delete(&mut conn).await?;
Ok(())
}
@@ -269,14 +284,11 @@ async fn send_invite(data: Json<EmergencyAccessInviteData>, headers: Headers, mu
async fn resend_invite(emer_id: &str, headers: Headers, mut conn: DbConn) -> EmptyResult {
check_emergency_access_enabled()?;
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
-
- if emergency_access.grantor_uuid != headers.user.uuid {
- err!("Emergency access not valid.");
- }
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &headers.user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
if emergency_access.status != EmergencyAccessStatus::Invited as i32 {
err!("The grantee user is already accepted or confirmed to the organization");
@@ -342,10 +354,13 @@ async fn accept_invite(emer_id: &str, data: Json<AcceptData>, headers: Headers,
None => err!("Invited user not found"),
};
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ // We need to search for the uuid in combination with the email, since we do not yet store the uuid of the grantee in the database.
+ // The uuid of the grantee gets stored once accepted.
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantee_email(emer_id, &headers.user.email, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
// get grantor user to send Accepted email
let grantor_user = match User::find_by_uuid(&emergency_access.grantor_uuid, &mut conn).await {
@@ -388,10 +403,11 @@ async fn confirm_emergency_access(
let data: ConfirmData = data.into_inner();
let key = data.key;
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &confirming_user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
if emergency_access.status != EmergencyAccessStatus::Accepted as i32
|| emergency_access.grantor_uuid != confirming_user.uuid
@@ -434,14 +450,13 @@ async fn initiate_emergency_access(emer_id: &str, headers: Headers, mut conn: Db
check_emergency_access_enabled()?;
let initiating_user = headers.user;
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantee_uuid(emer_id, &initiating_user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
- if emergency_access.status != EmergencyAccessStatus::Confirmed as i32
- || emergency_access.grantee_uuid != Some(initiating_user.uuid)
- {
+ if emergency_access.status != EmergencyAccessStatus::Confirmed as i32 {
err!("Emergency access not valid.")
}
@@ -473,14 +488,13 @@ async fn initiate_emergency_access(emer_id: &str, headers: Headers, mut conn: Db
async fn approve_emergency_access(emer_id: &str, headers: Headers, mut conn: DbConn) -> JsonResult {
check_emergency_access_enabled()?;
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &headers.user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
- if emergency_access.status != EmergencyAccessStatus::RecoveryInitiated as i32
- || emergency_access.grantor_uuid != headers.user.uuid
- {
+ if emergency_access.status != EmergencyAccessStatus::RecoveryInitiated as i32 {
err!("Emergency access not valid.")
}
@@ -511,23 +525,18 @@ async fn approve_emergency_access(emer_id: &str, headers: Headers, mut conn: DbC
async fn reject_emergency_access(emer_id: &str, headers: Headers, mut conn: DbConn) -> JsonResult {
check_emergency_access_enabled()?;
- let mut emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let mut emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantor_uuid(emer_id, &headers.user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
- if (emergency_access.status != EmergencyAccessStatus::RecoveryInitiated as i32
- && emergency_access.status != EmergencyAccessStatus::RecoveryApproved as i32)
- || emergency_access.grantor_uuid != headers.user.uuid
+ if emergency_access.status != EmergencyAccessStatus::RecoveryInitiated as i32
+ && emergency_access.status != EmergencyAccessStatus::RecoveryApproved as i32
{
err!("Emergency access not valid.")
}
- let grantor_user = match User::find_by_uuid(&headers.user.uuid, &mut conn).await {
- Some(user) => user,
- None => err!("Grantor user not found."),
- };
-
if let Some(grantee_uuid) = emergency_access.grantee_uuid.as_ref() {
let grantee_user = match User::find_by_uuid(grantee_uuid, &mut conn).await {
Some(user) => user,
@@ -538,7 +547,7 @@ async fn reject_emergency_access(emer_id: &str, headers: Headers, mut conn: DbCo
emergency_access.save(&mut conn).await?;
if CONFIG.mail_enabled() {
- mail::send_emergency_access_recovery_rejected(&grantee_user.email, &grantor_user.name).await?;
+ mail::send_emergency_access_recovery_rejected(&grantee_user.email, &headers.user.name).await?;
}
Ok(Json(emergency_access.to_json()))
} else {
@@ -554,10 +563,11 @@ async fn reject_emergency_access(emer_id: &str, headers: Headers, mut conn: DbCo
async fn view_emergency_access(emer_id: &str, headers: Headers, mut conn: DbConn) -> JsonResult {
check_emergency_access_enabled()?;
- let emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantee_uuid(emer_id, &headers.user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
if !is_valid_request(&emergency_access, &headers.user.uuid, EmergencyAccessType::View) {
err!("Emergency access not valid.")
@@ -592,10 +602,11 @@ async fn takeover_emergency_access(emer_id: &str, headers: Headers, mut conn: Db
check_emergency_access_enabled()?;
let requesting_user = headers.user;
- let emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantee_uuid(emer_id, &requesting_user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
if !is_valid_request(&emergency_access, &requesting_user.uuid, EmergencyAccessType::Takeover) {
err!("Emergency access not valid.")
@@ -639,10 +650,11 @@ async fn password_emergency_access(
//let key = &data.Key;
let requesting_user = headers.user;
- let emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantee_uuid(emer_id, &requesting_user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
if !is_valid_request(&emergency_access, &requesting_user.uuid, EmergencyAccessType::Takeover) {
err!("Emergency access not valid.")
@@ -674,10 +686,11 @@ async fn password_emergency_access(
#[get("/emergency-access/<emer_id>/policies")]
async fn policies_emergency_access(emer_id: &str, headers: Headers, mut conn: DbConn) -> JsonResult {
let requesting_user = headers.user;
- let emergency_access = match EmergencyAccess::find_by_uuid(emer_id, &mut conn).await {
- Some(emer) => emer,
- None => err!("Emergency access not valid."),
- };
+ let emergency_access =
+ match EmergencyAccess::find_by_uuid_and_grantee_uuid(emer_id, &requesting_user.uuid, &mut conn).await {
+ Some(emer) => emer,
+ None => err!("Emergency access not valid."),
+ };
if !is_valid_request(&emergency_access, &requesting_user.uuid, EmergencyAccessType::Takeover) {
err!("Emergency access not valid.")
diff --git a/src/db/models/emergency_access.rs b/src/db/models/emergency_access.rs
index b5e4eb86..ecfe86fe 100644
--- a/src/db/models/emergency_access.rs
+++ b/src/db/models/emergency_access.rs
@@ -238,15 +238,6 @@ impl EmergencyAccess {
}}
}
- pub async fn find_by_uuid(uuid: &str, conn: &mut DbConn) -> Option<Self> {
- db_run! { conn: {
- emergency_access::table
- .filter(emergency_access::uuid.eq(uuid))
- .first::<EmergencyAccessDb>(conn)
- .ok().from_db()
- }}
- }
-
pub async fn find_by_grantor_uuid_and_grantee_uuid_or_email(
grantor_uuid: &str,
grantee_uuid: &str,
@@ -281,6 +272,26 @@ impl EmergencyAccess {
}}
}
+ pub async fn find_by_uuid_and_grantee_uuid(uuid: &str, grantee_uuid: &str, conn: &mut DbConn) -> Option<Self> {
+ db_run! { conn: {
+ emergency_access::table
+ .filter(emergency_access::uuid.eq(uuid))
+ .filter(emergency_access::grantee_uuid.eq(grantee_uuid))
+ .first::<EmergencyAccessDb>(conn)
+ .ok().from_db()
+ }}
+ }
+
+ pub async fn find_by_uuid_and_grantee_email(uuid: &str, grantee_email: &str, conn: &mut DbConn) -> Option<Self> {
+ db_run! { conn: {
+ emergency_access::table
+ .filter(emergency_access::uuid.eq(uuid))
+ .filter(emergency_access::email.eq(grantee_email))
+ .first::<EmergencyAccessDb>(conn)
+ .ok().from_db()
+ }}
+ }
+
pub async fn find_all_by_grantee_uuid(grantee_uuid: &str, conn: &mut DbConn) -> Vec<Self> {
db_run! { conn: {
emergency_access::table