diff --git a/kanidmd/lib/src/valueset/session.rs b/kanidmd/lib/src/valueset/session.rs index bcc93d446..39de18d45 100644 --- a/kanidmd/lib/src/valueset/session.rs +++ b/kanidmd/lib/src/valueset/session.rs @@ -35,8 +35,80 @@ impl ValueSetSession { .into_iter() .filter_map(|dbv| { match dbv { - // Skip due to lack of credential id - DbValueSession::V1 { .. } => None, + // MISTAKE - Skip due to lack of credential id + // 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> + }) + .transpose() + // Result, _> + .map_err(|e| { + admin_error!( + ?e, + "Invalidating session {} due to invalid expiry timestamp", + refer + ) + }) + // Option> + .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 { refer, label,