Skip to content

Commit

Permalink
feat: key rotation events
Browse files Browse the repository at this point in the history
  • Loading branch information
simbleau committed Dec 6, 2023
1 parent 908dd22 commit 9f71b59
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe

## Unreleased

### added

- Added `KeyRotationEvent` events triggered on start, rotation, failure, and stoppage

### changed

- Changed `instant::{Duration, Instant}` to `web_time::{Duration, Instant}`
Expand Down
5 changes: 4 additions & 1 deletion src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{data_types::Keygen, Keystore, KeystoreState};
use crate::{data_types::Keygen, KeyRotationEvent, Keystore, KeystoreState};
use bevy::{ecs::system::Command, prelude::*};
use bevy_async_task::AsyncTask;

Expand All @@ -23,6 +23,7 @@ impl Command for StartKeyRotation {
if keystore.access_token_valid_for() > crate::Duration::ZERO {
let mut state = world.resource_mut::<NextState<KeystoreState>>();
state.set(KeystoreState::Conformant);
world.send_event(KeyRotationEvent::Started(keystore.clone()));
} else {
warn!("auth provider authenticated, but returned an expired access token, remaining nonconformant");
}
Expand All @@ -42,6 +43,7 @@ impl Command for StartKeyRotationWithKeystore {
if keystore.access_token_valid_for() > crate::Duration::ZERO {
let mut state = world.resource_mut::<NextState<KeystoreState>>();
state.set(KeystoreState::Conformant);
world.send_event(KeyRotationEvent::Started(self.keystore.clone()));
} else {
warn!("started key rotation with an expired keystore, remaining nonconformant");
}
Expand Down Expand Up @@ -73,6 +75,7 @@ impl Command for StopKeyRotation {
fn apply(self, world: &mut bevy::prelude::World) {
let mut state = world.resource_mut::<NextState<KeystoreState>>();
state.set(KeystoreState::NonConformant);
world.send_event(KeyRotationEvent::Stopped);
info!("stopping key rotation");
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/data_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,16 @@ impl Default for KeyRotationSettings {
}
}
}

/// An event triggered for important key rotation events.
#[derive(Event)]
pub enum KeyRotationEvent {
/// Key rotation has started
Started(Keystore),
/// Keys were rotated successfully
Rotated(Keystore),
/// Tokens failed to rotate
FailedRotation(TokenRotationError),
/// Key rotation became non-conformant
Stopped,
}
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use thiserror::Error;

#[derive(Error, Debug)]
#[error(transparent)]
pub struct TokenRotationError(#[from] Box<dyn std::error::Error + Send>);
pub struct TokenRotationError(#[from] Box<dyn std::error::Error + Send + Sync>);

impl TokenRotationError {
pub fn new(source: impl std::error::Error + Send + 'static) -> Self {
pub fn new(source: impl std::error::Error + Send + Sync + 'static) -> Self {
Self(Box::new(source))
}
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pub use web_time::{Duration, Instant};

pub use commands::{StartKeyRotationExt, StopKeyRotationExt};
pub use data_types::{
AuthProvider, KeyRotationSettings, Keygen, Keystore, KeystoreState,
AuthProvider, KeyRotationEvent, KeyRotationSettings, Keygen, Keystore,
KeystoreState,
};
pub use error::TokenRotationError;
pub use plugin::KeyRotationPlugin;
13 changes: 8 additions & 5 deletions src/systems.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
data_types::{KeyRotationSettings, Keygen, Keystore},
data_types::{KeyRotationEvent, KeyRotationSettings, Keygen, Keystore},
error::TokenRotationError,
Duration, KeystoreState,
};
Expand All @@ -15,15 +15,16 @@ pub(crate) fn rotate_tokens(
mut tr_rotate: AsyncTaskRunner<
Result<Result<Keystore, TokenRotationError>, TimeoutError>,
>,
mut event_writer: EventWriter<KeyRotationEvent>,
mut rotation_timer: Local<Option<Timer>>,
time: Res<Time>,
) {
if let AsyncTaskStatus::Finished(resp) = tr_rotate.poll() {
match resp {
Ok(Ok(keys)) => {
*keystore = keys;
// todo send event
info!("token rotation successful");
*keystore = keys;
event_writer.send(KeyRotationEvent::Rotated(keystore.clone()));
}
err @ (Err(_) | Ok(Err(_))) => {
if let Err(_timeout) = err {
Expand All @@ -33,8 +34,8 @@ pub(crate) fn rotate_tokens(
);
} else if let Ok(Err(e)) = err {
warn!("key rotation failed: {e}");
event_writer.send(KeyRotationEvent::FailedRotation(e));
}
// Todo send event for warnings
}
}
}
Expand Down Expand Up @@ -77,11 +78,13 @@ pub(crate) fn rotate_tokens(
}
}

pub fn state_transfer(
pub(crate) fn state_transfer(
mut token_state: ResMut<NextState<KeystoreState>>,
mut event_writer: EventWriter<KeyRotationEvent>,
keystore: Res<Keystore>,
) {
if keystore.access_token_valid_for() == Duration::ZERO {
token_state.set(KeystoreState::NonConformant);
event_writer.send(KeyRotationEvent::Stopped);
}
}

0 comments on commit 9f71b59

Please sign in to comment.