Prevent invalidation of api tokens (#1397)

This commit is contained in:
Firstyear 2023-02-22 12:25:14 +10:00 committed by GitHub
parent 854ca808e7
commit 9a70942544
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -35,8 +35,80 @@ impl ValueSetSession {
.into_iter() .into_iter()
.filter_map(|dbv| { .filter_map(|dbv| {
match dbv { match dbv {
// Skip due to lack of credential id // MISTAKE - Skip due to lack of credential id
DbValueSession::V1 { .. } => None, // Don't actually skip, generate a random cred id. Session cleanup will
// trim sessions on users, but if we skip blazenly we invalidate every api
// token ever issued. OPPS!
DbValueSession::V1 {
refer,
label,
expiry,
issued_at,
issued_by,
scope,
} => {
let cred_id = Uuid::new_v4();
// Convert things.
let issued_at = OffsetDateTime::parse(issued_at, time::Format::Rfc3339)
.map(|odt| odt.to_offset(time::UtcOffset::UTC))
.map_err(|e| {
admin_error!(
?e,
"Invalidating session {} due to invalid issued_at timestamp",
refer
)
})
.ok()?;
// This is a bit annoying. In the case we can't parse the optional
// expiry, we need to NOT return the session so that it's immediately
// invalidated. To do this we have to invert some of the options involved
// here.
let expiry = expiry
.map(|e_inner| {
OffsetDateTime::parse(e_inner, time::Format::Rfc3339)
.map(|odt| odt.to_offset(time::UtcOffset::UTC))
// We now have an
// Option<Result<ODT, _>>
})
.transpose()
// Result<Option<ODT>, _>
.map_err(|e| {
admin_error!(
?e,
"Invalidating session {} due to invalid expiry timestamp",
refer
)
})
// Option<Option<ODT>>
.ok()?;
let issued_by = match issued_by {
DbValueIdentityId::V1Internal => IdentityId::Internal,
DbValueIdentityId::V1Uuid(u) => IdentityId::User(u),
DbValueIdentityId::V1Sync(u) => IdentityId::Synch(u),
};
let scope = match scope {
DbValueAccessScopeV1::IdentityOnly => AccessScope::IdentityOnly,
DbValueAccessScopeV1::ReadOnly => AccessScope::ReadOnly,
DbValueAccessScopeV1::ReadWrite => AccessScope::ReadWrite,
DbValueAccessScopeV1::Synchronise => AccessScope::Synchronise,
};
Some((
refer,
Session {
label,
expiry,
issued_at,
issued_by,
cred_id,
scope,
},
))
}
DbValueSession::V2 { DbValueSession::V2 {
refer, refer,
label, label,