Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- check: `cargo check --quiet --all-features --workspace --all-targets`
- test: `cargo test --quiet --all-features --workspace --all-targets`
- format: `cargo fmt`
- clippy: `cargo clippy --fix --allow-dirty --all-features --workspace --all-targets`
- clippy: `cargo clippy --quiet --fix --allow-dirty --all-features --workspace --all-targets`

## Crates

Expand Down
4 changes: 4 additions & 0 deletions v-api-permission-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ publish.workspace = true
[lib]
proc-macro = true

[features]
default = []
sagas = []

[dependencies]
heck = { workspace = true }
proc-macro2 = { workspace = true }
Expand Down
28 changes: 22 additions & 6 deletions v-api-permission-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,15 @@ fn from_system_permission_tokens(
source: &Ident,
permission_type: &Ident,
) -> proc_macro2::TokenStream {
let saga_permission_from_tokens = if cfg!(feature = "sagas") {
quote! {
VPermission::GetSagasAll => Self::GetSagasAll,
VPermission::ManageSagasAll => Self::ManageSagasAll,
}
} else {
quote! {}
};

if source != permission_type {
quote! {
impl From<#source> for #permission_type {
Expand Down Expand Up @@ -440,8 +449,7 @@ fn from_system_permission_tokens(

VPermission::CreateAccessToken => Self::CreateAccessToken,

VPermission::GetSagasAll => Self::GetSagasAll,
VPermission::ManageSagasAll => Self::ManageSagasAll,
#saga_permission_from_tokens

VPermission::Unsupported(inner) => Self::Unsupported(inner),
}
Expand Down Expand Up @@ -473,6 +481,17 @@ fn inject_system_permission_variants(mut input: DeriveInput) -> Result<DeriveInp
}

fn system_permission_tokens() -> TokenStream {
let saga_permission_tokens = if cfg!(feature = "sagas") {
quote! {
#[v_api(scope(to = "saga:r", from = "saga:r"))]
GetSagasAll,
#[v_api(scope(to = "saga:w", from = "saga:w"))]
ManageSagasAll,
}
} else {
quote! {}
};

quote! {
enum VPermission {
#[v_api(scope(to = "user:info:w", from = "user:info:w"))]
Expand Down Expand Up @@ -723,10 +742,7 @@ fn system_permission_tokens() -> TokenStream {

CreateAccessToken,

#[v_api(scope(to = "saga:r", from = "saga:r"))]
GetSagasAll,
#[v_api(scope(to = "saga:w", from = "saga:w"))]
ManageSagasAll,
#saga_permission_tokens

#[serde(untagged)]
Unsupported(serde_json::Value),
Expand Down
2 changes: 1 addition & 1 deletion v-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish.workspace = true
[features]
default = ["sagas"]
local-dev = []
sagas = ["slog", "steno", "v-model/sagas"]
sagas = ["slog", "steno", "v-api-permission-derive/sagas", "v-model/sagas"]

[dependencies]
anyhow = { workspace = true }
Expand Down
36 changes: 20 additions & 16 deletions v-api/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,15 @@ pub(crate) mod test_mocks {
use newtype_uuid::{GenericUuid, TypedUuid};
use std::{collections::HashMap, sync::Arc};
use uuid::Uuid;
#[cfg(feature = "sagas")]
use v_model::saga::{
db::{ModelSagaCachedState, NewSagaEventModel, NewSagaModel, SagaEventModel, SagaModel},
storage::{
MockSagaEventStore, MockSagaStore, SagaEventFilter, SagaEventStore, SagaFilter,
SagaStore,
},
view::{SagaExecNodeId, SagaId},
};
use v_model::{
AccessGroupId, AccessToken, AccessTokenId, ApiKey, ApiKeyId, ApiUserContactEmail,
ApiUserProvider, LinkRequestId, LoginAttemptId, MagicLink, MagicLinkAttempt,
Expand All @@ -1220,16 +1229,6 @@ pub(crate) mod test_mocks {
NewMagicLinkAttempt, NewMagicLinkRedirectUri, NewMagicLinkSecret, NewMapper, OAuthClientId,
OAuthRedirectUriId, OAuthSecretId, UserContactEmailId, UserId, UserProviderId,
permissions::Caller,
saga::{
db::{
ModelSagaCachedState, NewSagaEventModel, NewSagaModel, SagaEventModel, SagaModel,
},
storage::{
MockSagaEventStore, MockSagaStore, SagaEventFilter, SagaEventStore, SagaFilter,
SagaStore,
},
view::{SagaExecNodeId, SagaId},
},
schema_ext::MagicLinkAttemptState,
storage::{
AccessGroupStore, AccessTokenStore, ApiKeyStore, ApiUserContactEmailStore,
Expand Down Expand Up @@ -1260,15 +1259,14 @@ pub(crate) mod test_mocks {
// Construct a mock context that can be used in tests
pub async fn mock_context(storage: Arc<MockStorage>) -> VContext<VPermission> {
let MockKey { signer, verifier } = mock_key("test");
let mut ctx = VContextBuilder::<VPermission>::new()
let ctx = VContextBuilder::<VPermission>::new()
.with_public_url("".to_string())
.with_storage(storage)
.with_jwt_expiration(JwtConfig::default().default_expiration)
.with_keys(vec![signer, verifier])
.with_saga_backend(TypedUuid::new_v4(), None)
.build()
.await
.unwrap();
.with_keys(vec![signer, verifier]);
#[cfg(feature = "sagas")]
let ctx = ctx.with_saga_backend(TypedUuid::new_v4(), None);
let mut ctx = ctx.build().await.unwrap();

let mapping_engine = Arc::new(DefaultMappingEngine::new(
ctx.builtin_registration_user(),
Expand Down Expand Up @@ -1310,7 +1308,9 @@ pub(crate) mod test_mocks {
pub magic_link_secret_store: Option<Arc<MockMagicLinkSecretStore>>,
pub magic_link_redirect_store: Option<Arc<MockMagicLinkRedirectUriStore>>,
pub magic_link_attempt_store: Option<Arc<MockMagicLinkAttemptStore>>,
#[cfg(feature = "sagas")]
pub saga_store: Option<Arc<MockSagaStore>>,
#[cfg(feature = "sagas")]
pub saga_event_store: Option<Arc<MockSagaEventStore>>,
}

Expand All @@ -1333,7 +1333,9 @@ pub(crate) mod test_mocks {
magic_link_secret_store: None,
magic_link_redirect_store: None,
magic_link_attempt_store: None,
#[cfg(feature = "sagas")]
saga_store: None,
#[cfg(feature = "sagas")]
saga_event_store: None,
}
}
Expand Down Expand Up @@ -1955,6 +1957,7 @@ pub(crate) mod test_mocks {
}
}

#[cfg(feature = "sagas")]
#[async_trait]
impl SagaStore for MockStorage {
async fn get(&self, saga_id: TypedUuid<SagaId>) -> Result<Option<SagaModel>, StoreError> {
Expand Down Expand Up @@ -2021,6 +2024,7 @@ pub(crate) mod test_mocks {
}
}

#[cfg(feature = "sagas")]
#[async_trait]
impl SagaEventStore for MockStorage {
async fn list(
Expand Down
Loading