mirror of
https://github.com/dani-garcia/vaultwarden.wiki.git
synced 2026-10-27 21:56:47 +02:00
Implement V2 key rotation support
This commit is contained in:
11 files changed
+891
-231
No files matched your search
+15
-26
@@ -30,7 +30,7 @@ use crate::{
|
||||
models::{
|
||||
AttachmentId, CipherId, Collection, CollectionId, Device, DeviceId, DeviceType, EmergencyAccessId,
|
||||
EventType, Membership, MembershipId, MembershipStatus, MembershipType, OrgApiKeyId, OrganizationId,
|
||||
SendFileId, SendId, User, UserId, UserStampException,
|
||||
SendFileId, SendId, User, UserId,
|
||||
},
|
||||
},
|
||||
error::Error,
|
||||
@@ -662,36 +662,25 @@ impl<'r> FromRequest<'r> for Headers {
|
||||
err_handler!("Invalid device id")
|
||||
};
|
||||
|
||||
let Some(user) = User::find_by_uuid(&user_id, &conn).await else {
|
||||
let Some(mut user) = User::find_by_uuid(&user_id, &conn).await else {
|
||||
err_handler!("Device has no user associated")
|
||||
};
|
||||
|
||||
if user.security_stamp != claims.sstamp {
|
||||
if let Some(stamp_exception) =
|
||||
user.stamp_exception.as_deref().and_then(|s| serde_json::from_str::<UserStampException>(s).ok())
|
||||
{
|
||||
let Some(current_route) = request.route().and_then(|r| r.name.as_deref()) else {
|
||||
err_handler!("Error getting current route for stamp exception")
|
||||
};
|
||||
let Some(current_route) = request.route().and_then(|r| r.name.as_deref()) else {
|
||||
err_handler!("Error getting current route for stamp exception")
|
||||
};
|
||||
|
||||
// Check if the stamp exception has expired first.
|
||||
// Then, check if the current route matches any of the allowed routes.
|
||||
// After that check the stamp in exception matches the one in the claims.
|
||||
if Utc::now().timestamp() > stamp_exception.expire {
|
||||
// If the stamp exception has been expired remove it from the database.
|
||||
// This prevents checking this stamp exception for new requests.
|
||||
let mut user = user;
|
||||
user.reset_stamp_exception();
|
||||
if let Err(e) = user.save(&conn).await {
|
||||
error!("Error updating user: {e:#?}");
|
||||
}
|
||||
err_handler!("Stamp exception is expired")
|
||||
} else if !stamp_exception.routes.contains(¤t_route.to_owned()) {
|
||||
err_handler!("Invalid security stamp: Current route and exception route do not match")
|
||||
} else if stamp_exception.security_stamp != claims.sstamp {
|
||||
err_handler!("Invalid security stamp for matched stamp exception")
|
||||
}
|
||||
} else {
|
||||
let allowed = user.stamp_exceptions().iter().any(|e| e.allows(&claims.sstamp, current_route));
|
||||
|
||||
// Drop the expired exceptions, so they aren't checked for every request from now on.
|
||||
if user.retain_stamp_exceptions(|e| !e.is_expired())
|
||||
&& let Err(e) = user.save_stamp_exceptions(&conn).await
|
||||
{
|
||||
error!("Error updating user: {e:#?}");
|
||||
}
|
||||
|
||||
if !allowed {
|
||||
err_handler!("Invalid security stamp")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user