diff --git a/v-api-permission-derive/src/lib.rs b/v-api-permission-derive/src/lib.rs index bc54152..320465d 100644 --- a/v-api-permission-derive/src/lib.rs +++ b/v-api-permission-derive/src/lib.rs @@ -2,7 +2,10 @@ use heck::ToSnakeCase; use proc_macro::TokenStream; use proc_macro2::Literal; use quote::{format_ident, quote, quote_spanned}; -use std::{collections::HashMap, hash::{Hash, Hasher}}; +use std::{ + collections::HashMap, + hash::{Hash, Hasher}, +}; use syn::{ parse::{Parse, ParseStream}, parse_macro_input, @@ -179,9 +182,10 @@ impl Parse for ExpandSettings { .find(|s| s.name == "variant") .expect("Expand must contain a \"variant\" setting") .value, - value: settings.iter().find(|s| s.name == "value").map(|s| { - s.value.clone() - }), + value: settings + .iter() + .find(|s| s.name == "value") + .map(|s| s.value.clone()), source: settings.iter().find(|s| s.name == "source").map(|s| { match s.value.to_string().as_str() { "actor" => ExternalSource::Actor, @@ -223,7 +227,7 @@ pub fn v_api(attr: TokenStream, input: TokenStream) -> TokenStream { let mut input = parse_macro_input!(input as DeriveInput); input = match inject_system_permission_variants(input) { Ok(input) => input, - Err(err) => return err.to_compile_error().into() + Err(err) => return err.to_compile_error().into(), }; let input_span = input.span(); @@ -241,15 +245,12 @@ pub fn v_api(attr: TokenStream, input: TokenStream) -> TokenStream { Ok(VariantSettings(settings)) => { for setting in settings { match setting { - VariantSetting::Contract(setting) => { - contract_settings.push((variant_clone.clone(), setting.clone())) - } - VariantSetting::Expand(setting) => { - expand_settings.push((variant_clone.clone(), setting.clone())) - } - VariantSetting::Scope(setting) => { - scope_settings.push((variant_clone.clone(), setting.clone())) - } + VariantSetting::Contract(setting) => contract_settings + .push((variant_clone.clone(), setting.clone())), + VariantSetting::Expand(setting) => expand_settings + .push((variant_clone.clone(), setting.clone())), + VariantSetting::Scope(setting) => scope_settings + .push((variant_clone.clone(), setting.clone())), } } } @@ -261,12 +262,14 @@ pub fn v_api(attr: TokenStream, input: TokenStream) -> TokenStream { variant.attrs.retain(|attr| !attr.path.is_ident(MACRO_ID)); } let as_scope_out = as_scope_trait_tokens(input.ident.clone(), scope_settings); - let permission_storage_out = permission_storage_trait_tokens(&input.ident, contract_settings, expand_settings); + let permission_storage_out = + permission_storage_trait_tokens(&input.ident, contract_settings, expand_settings); quote! { #as_scope_out #permission_storage_out - }.into() + } + .into() } _ => quote_spanned! { input_span => compile_error!("v_api may only be applied to enums"); @@ -285,7 +288,8 @@ pub fn v_api(attr: TokenStream, input: TokenStream) -> TokenStream { #input #from #trait_impl_tokens - }.into() + } + .into() } struct LiteralKey { @@ -316,7 +320,10 @@ impl Hash for LiteralKey { } } -fn from_system_permission_tokens(source: &Ident, permission_type: &Ident) -> proc_macro2::TokenStream { +fn from_system_permission_tokens( + source: &Ident, + permission_type: &Ident, +) -> proc_macro2::TokenStream { if source != permission_type { quote! { impl From<#source> for #permission_type { @@ -387,10 +394,8 @@ fn inject_system_permission_variants(mut input: DeriveInput) -> Result { - data_enum.variants - } - _ => unreachable!("System permissions are always an enum") + Data::Enum(data_enum) => data_enum.variants, + _ => unreachable!("System permissions are always an enum"), }; match input.data { @@ -609,7 +614,8 @@ fn system_permission_tokens() -> TokenStream { #[serde(other)] Removed, } - }.into() + } + .into() } fn as_scope_trait_tokens( @@ -617,22 +623,20 @@ fn as_scope_trait_tokens( scope_settings: Vec<(Variant, ScopeSettings)>, ) -> proc_macro2::TokenStream { let as_scope_mapping = scope_settings.iter().filter_map(|(variant, settings)| { - settings - .to - .as_ref() - .map(|to| { - let fields = if variant.fields.len() > 0 { - let mut fields = quote! {}; - variant.fields.iter().for_each(|_| { - fields = quote! { _, #fields } - }); - quote! { (#fields) } - } else { - quote! { } - }; - let variant_ident = variant.ident.clone(); - quote! { #permission_type::#variant_ident #fields => Some(#to) } - }) + settings.to.as_ref().map(|to| { + let fields = if variant.fields.len() > 0 { + let mut fields = quote! {}; + variant + .fields + .iter() + .for_each(|_| fields = quote! { _, #fields }); + quote! { (#fields) } + } else { + quote! {} + }; + let variant_ident = variant.ident.clone(); + quote! { #permission_type::#variant_ident #fields => Some(#to) } + }) }); let from_scope_mapping = scope_settings .iter() @@ -730,13 +734,17 @@ fn permission_storage_contract_tokens( let fields = if variant.fields.len() > 0 { let mut fields = quote! {}; - variant.fields.iter().enumerate().for_each(|(index, field)| { - let field_ident = field.ident.as_ref().unwrap_or(&stock_field_names[index]); - fields = quote! { #field_ident, #fields } - }); + variant + .fields + .iter() + .enumerate() + .for_each(|(index, field)| { + let field_ident = field.ident.as_ref().unwrap_or(&stock_field_names[index]); + fields = quote! { #field_ident, #fields } + }); fields } else { - quote! { } + quote! {} }; branches.push(match setting.kind { diff --git a/v-api-permission-derive/tests/derive.rs b/v-api-permission-derive/tests/derive.rs index bced2e5..24202a2 100644 --- a/v-api-permission-derive/tests/derive.rs +++ b/v-api-permission-derive/tests/derive.rs @@ -2,7 +2,10 @@ use std::collections::BTreeSet; use uuid::Uuid; use v_api::permissions::VPermission; use v_api_permission_derive::v_api; -use v_model::{permissions::{AsScope, PermissionStorage}, Permissions}; +use v_model::{ + permissions::{AsScope, PermissionStorage}, + Permissions, +}; #[test] fn test_derive() { @@ -11,7 +14,16 @@ fn test_derive() { // } #[v_api(From(VPermission))] #[derive( - Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, schemars::JsonSchema, PartialOrd, Ord, + Debug, + Clone, + PartialEq, + Eq, + Hash, + serde::Serialize, + serde::Deserialize, + schemars::JsonSchema, + PartialOrd, + Ord, )] enum AppPermissions { #[v_api(contract(kind = append, variant = CreateItems))] diff --git a/v-api/src/authn/jwt.rs b/v-api/src/authn/jwt.rs index b68e23a..364f868 100644 --- a/v-api/src/authn/jwt.rs +++ b/v-api/src/authn/jwt.rs @@ -19,15 +19,9 @@ use rsa::traits::PublicKeyParts; use serde::{Deserialize, Serialize}; use thiserror::Error; use tracing::instrument; -use v_model::{ - AccessTokenId, ApiUser, ApiUserProvider, UserId, UserProviderId, -}; +use v_model::{AccessTokenId, ApiUser, ApiUserProvider, UserId, UserProviderId}; -use crate::{ - config::AsymmetricKey, - context::VContext, - permissions::VAppPermission, -}; +use crate::{config::AsymmetricKey, context::VContext, permissions::VAppPermission}; use super::{Signer, SigningKeyError}; diff --git a/v-api/src/context.rs b/v-api/src/context.rs index 7963cf1..2c1f48d 100644 --- a/v-api/src/context.rs +++ b/v-api/src/context.rs @@ -18,7 +18,10 @@ use thiserror::Error; use tracing::{info_span, instrument, Instrument}; use uuid::Uuid; use v_model::{ - permissions::{AsScopeInternal, Caller, Permission, PermissionError, PermissionStorageInternal, Permissions}, + permissions::{ + AsScopeInternal, Caller, Permission, PermissionError, PermissionStorageInternal, + Permissions, + }, schema_ext::LoginAttemptState, storage::{ AccessGroupFilter, AccessGroupStore, AccessTokenStore, ApiKeyFilter, ApiKeyStore, @@ -350,8 +353,11 @@ where let combined_permissions = match &base_permissions { BasePermissions::Full => user_permissions.clone(), BasePermissions::Restricted(permissions) => { - let token_permissions = - ::expand(permissions, &user.id, Some(&user_permissions)); + let token_permissions = ::expand( + permissions, + &user.id, + Some(&user_permissions), + ); token_permissions.intersect(&user_permissions) } }; @@ -810,7 +816,11 @@ where .await .map(|opt| { opt.map(|mut user| { - user.permissions = ::expand(&user.permissions, &user.id, None); + user.permissions = ::expand( + &user.permissions, + &user.id, + None, + ); user }) }) @@ -853,7 +863,8 @@ where permissions: permissions, groups: groups, }; - new_user.permissions = ::contract(&new_user.permissions); + new_user.permissions = + ::contract(&new_user.permissions); ApiUserStore::upsert(&*self.storage, new_user) .await .to_resource_result() @@ -872,7 +883,8 @@ where &VPermission::ManageApiUser(api_user.id).into(), &VPermission::ManageApiUsersAll.into(), ]) { - api_user.permissions = ::contract(&api_user.permissions); + api_user.permissions = + ::contract(&api_user.permissions); ApiUserStore::upsert(&*self.storage, api_user) .await .to_resource_result() diff --git a/v-api/src/endpoints/api_user.rs b/v-api/src/endpoints/api_user.rs index b34567b..6d80204 100644 --- a/v-api/src/endpoints/api_user.rs +++ b/v-api/src/endpoints/api_user.rs @@ -17,7 +17,7 @@ use tap::TapFallible; use tracing::instrument; use uuid::Uuid; use v_model::{ - permissions::{Caller, Permission, Permissions, PermissionStorage}, + permissions::{Caller, Permission, PermissionStorage, Permissions}, storage::{ApiUserProviderFilter, ListPagination}, AccessGroupId, ApiKeyId, ApiUser, ApiUserProvider, NewApiKey, NewApiUser, UserId, }; diff --git a/v-api/src/endpoints/api_user_provider.rs b/v-api/src/endpoints/api_user_provider.rs index a9cd018..7b109fa 100644 --- a/v-api/src/endpoints/api_user_provider.rs +++ b/v-api/src/endpoints/api_user_provider.rs @@ -7,13 +7,9 @@ use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tracing::instrument; -use v_model::{UserId, UserProviderId, permissions::PermissionStorage}; +use v_model::{permissions::PermissionStorage, UserId, UserProviderId}; -use crate::{ - context::ApiContext, - permissions::VAppPermission, - secrets::OpenApiSecretString, -}; +use crate::{context::ApiContext, permissions::VAppPermission, secrets::OpenApiSecretString}; #[derive(Debug, Deserialize, JsonSchema)] pub struct ApiUserProviderPath { diff --git a/v-api/src/endpoints/group.rs b/v-api/src/endpoints/group.rs index 0d38206..30ce3b6 100644 --- a/v-api/src/endpoints/group.rs +++ b/v-api/src/endpoints/group.rs @@ -10,14 +10,11 @@ use schemars::JsonSchema; use serde::Deserialize; use tracing::instrument; use v_model::{ - permissions::{Permission, Permissions, PermissionStorage}, + permissions::{Permission, PermissionStorage, Permissions}, AccessGroup, AccessGroupId, NewAccessGroup, }; -use crate::{ - context::ApiContext, - permissions::VAppPermission, -}; +use crate::{context::ApiContext, permissions::VAppPermission}; fn into_group_response(group: AccessGroup) -> AccessGroup where diff --git a/v-api/src/endpoints/login/oauth/client.rs b/v-api/src/endpoints/login/oauth/client.rs index ad6efe1..85561a8 100644 --- a/v-api/src/endpoints/login/oauth/client.rs +++ b/v-api/src/endpoints/login/oauth/client.rs @@ -9,8 +9,9 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tracing::instrument; use v_model::{ - permissions::{Caller, PermissionStorage}, OAuthClient, OAuthClientId, OAuthClientRedirectUri, OAuthClientSecret, - OAuthRedirectUriId, OAuthSecretId, + permissions::{Caller, PermissionStorage}, + OAuthClient, OAuthClientId, OAuthClientRedirectUri, OAuthClientSecret, OAuthRedirectUriId, + OAuthSecretId, }; use crate::{ diff --git a/v-api/src/endpoints/login/oauth/code.rs b/v-api/src/endpoints/login/oauth/code.rs index 8157cd9..60da065 100644 --- a/v-api/src/endpoints/login/oauth/code.rs +++ b/v-api/src/endpoints/login/oauth/code.rs @@ -26,8 +26,8 @@ use std::{fmt::Debug, ops::Add}; use tap::TapFallible; use tracing::instrument; use v_model::{ - schema_ext::LoginAttemptState, LoginAttempt, LoginAttemptId, NewLoginAttempt, OAuthClient, - OAuthClientId, permissions::PermissionStorage + permissions::PermissionStorage, schema_ext::LoginAttemptState, LoginAttempt, LoginAttemptId, + NewLoginAttempt, OAuthClient, OAuthClientId, }; use super::{OAuthProvider, OAuthProviderNameParam, UserInfoProvider}; diff --git a/v-api/src/endpoints/login/oauth/device_token.rs b/v-api/src/endpoints/login/oauth/device_token.rs index 35ecd00..304ea37 100644 --- a/v-api/src/endpoints/login/oauth/device_token.rs +++ b/v-api/src/endpoints/login/oauth/device_token.rs @@ -20,11 +20,8 @@ use super::{ ClientType, OAuthProvider, OAuthProviderInfo, OAuthProviderNameParam, UserInfoProvider, }; use crate::{ - context::ApiContext, - endpoints::login::LoginError, - error::ApiError, - permissions::VAppPermission, - util::response::bad_request, + context::ApiContext, endpoints::login::LoginError, error::ApiError, + permissions::VAppPermission, util::response::bad_request, }; #[instrument(skip(rqctx), err(Debug))] diff --git a/v-api/src/endpoints/mappers.rs b/v-api/src/endpoints/mappers.rs index d9d17cf..31c23ae 100644 --- a/v-api/src/endpoints/mappers.rs +++ b/v-api/src/endpoints/mappers.rs @@ -7,7 +7,10 @@ use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tracing::instrument; -use v_model::{permissions::{Permission, AsScope, PermissionStorage}, Mapper, MapperId, NewMapper}; +use v_model::{ + permissions::{AsScope, Permission, PermissionStorage}, + Mapper, MapperId, NewMapper, +}; use crate::{ context::ApiContext, diff --git a/v-api/src/endpoints/well_known/mod.rs b/v-api/src/endpoints/well_known/mod.rs index cae594f..db59b96 100644 --- a/v-api/src/endpoints/well_known/mod.rs +++ b/v-api/src/endpoints/well_known/mod.rs @@ -9,10 +9,7 @@ use serde::{Deserialize, Serialize}; use tracing::instrument; use v_model::permissions::PermissionStorage; -use crate::{ - context::ApiContext, - permissions::VAppPermission, -}; +use crate::{context::ApiContext, permissions::VAppPermission}; #[derive(Debug, Deserialize, Serialize, JsonSchema)] pub struct OpenIdConfiguration { diff --git a/v-api/src/initial_data.rs b/v-api/src/initial_data.rs index 7ed0ed0..6bbb6a7 100644 --- a/v-api/src/initial_data.rs +++ b/v-api/src/initial_data.rs @@ -8,12 +8,14 @@ use newtype_uuid::TypedUuid; use serde::Deserialize; use thiserror::Error; use tracing::Instrument; -use v_model::{permissions::{Permissions, PermissionStorage}, storage::StoreError, NewAccessGroup, NewMapper}; +use v_model::{ + permissions::{PermissionStorage, Permissions}, + storage::StoreError, + NewAccessGroup, NewMapper, +}; use crate::{ - context::VContext, - mapper::MappingRules, - permissions::VAppPermission, + context::VContext, mapper::MappingRules, permissions::VAppPermission, util::response::ResourceError, }; diff --git a/v-api/src/mapper/default.rs b/v-api/src/mapper/default.rs index fab4163..d5a798c 100644 --- a/v-api/src/mapper/default.rs +++ b/v-api/src/mapper/default.rs @@ -7,16 +7,10 @@ use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::collections::BTreeSet; -use v_model::{ - permissions::Permissions, - storage::StoreError, - AccessGroupId, -}; +use v_model::{permissions::Permissions, storage::StoreError, AccessGroupId}; use crate::{ - context::VContext, - endpoints::login::UserInfo, - permissions::VAppPermission, + context::VContext, endpoints::login::UserInfo, permissions::VAppPermission, util::response::ResourceResult, }; diff --git a/v-api/src/mapper/email_address.rs b/v-api/src/mapper/email_address.rs index 3f5762c..9baa6fe 100644 --- a/v-api/src/mapper/email_address.rs +++ b/v-api/src/mapper/email_address.rs @@ -8,16 +8,10 @@ use async_trait::async_trait; use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use v_model::{ - permissions::Permissions, - storage::StoreError, - AccessGroupId, -}; +use v_model::{permissions::Permissions, storage::StoreError, AccessGroupId}; use crate::{ - context::VContext, - endpoints::login::UserInfo, - permissions::VAppPermission, + context::VContext, endpoints::login::UserInfo, permissions::VAppPermission, util::response::ResourceResult, }; @@ -34,7 +28,7 @@ pub struct EmailAddressMapper { #[async_trait] impl MapperRule for EmailAddressMapper where - T: VAppPermission + T: VAppPermission, { async fn permissions_for( &self, diff --git a/v-api/src/mapper/email_domain.rs b/v-api/src/mapper/email_domain.rs index a2d7318..b63c401 100644 --- a/v-api/src/mapper/email_domain.rs +++ b/v-api/src/mapper/email_domain.rs @@ -8,16 +8,10 @@ use async_trait::async_trait; use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use v_model::{ - permissions::Permissions, - storage::StoreError, - AccessGroupId, -}; +use v_model::{permissions::Permissions, storage::StoreError, AccessGroupId}; use crate::{ - context::VContext, - endpoints::login::UserInfo, - permissions::VAppPermission, + context::VContext, endpoints::login::UserInfo, permissions::VAppPermission, util::response::ResourceResult, }; diff --git a/v-api/src/mapper/github_username.rs b/v-api/src/mapper/github_username.rs index e90a8d0..c2403ce 100644 --- a/v-api/src/mapper/github_username.rs +++ b/v-api/src/mapper/github_username.rs @@ -8,16 +8,10 @@ use async_trait::async_trait; use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use v_model::{ - permissions::Permissions, - storage::StoreError, - AccessGroupId, -}; +use v_model::{permissions::Permissions, storage::StoreError, AccessGroupId}; use crate::{ - context::VContext, - endpoints::login::UserInfo, - permissions::VAppPermission, + context::VContext, endpoints::login::UserInfo, permissions::VAppPermission, util::response::ResourceResult, }; diff --git a/v-api/src/mapper/mod.rs b/v-api/src/mapper/mod.rs index 3505dae..563d70b 100644 --- a/v-api/src/mapper/mod.rs +++ b/v-api/src/mapper/mod.rs @@ -9,16 +9,10 @@ use newtype_uuid::TypedUuid; use schemars::JsonSchema; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tap::TapFallible; -use v_model::{ - permissions::Permissions, - storage::StoreError, - AccessGroupId, Mapper, MapperId, -}; +use v_model::{permissions::Permissions, storage::StoreError, AccessGroupId, Mapper, MapperId}; use crate::{ - context::VContext, - endpoints::login::UserInfo, - permissions::VAppPermission, + context::VContext, endpoints::login::UserInfo, permissions::VAppPermission, util::response::ResourceResult, }; diff --git a/v-api/src/permissions.rs b/v-api/src/permissions.rs index 54b1092..6fd5ea6 100644 --- a/v-api/src/permissions.rs +++ b/v-api/src/permissions.rs @@ -3,15 +3,23 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. use partial_struct::partial; -use v_api_permission_derive::v_api; use schemars::JsonSchema; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use std::collections::BTreeSet; -use v_model::permissions::{AsScopeInternal, Permission, PermissionStorage, PermissionStorageInternal, Permissions}; +use v_api_permission_derive::v_api; use v_model::permissions::AsScope; +use v_model::permissions::{ + AsScopeInternal, Permission, PermissionStorage, PermissionStorageInternal, Permissions, +}; -pub trait VAppPermission: Permission + From + AsScopeInternal + PermissionStorageInternal {} -impl VAppPermission for T where T: Permission + From + AsScopeInternal + PermissionStorageInternal {} +pub trait VAppPermission: + Permission + From + AsScopeInternal + PermissionStorageInternal +{ +} +impl VAppPermission for T where + T: Permission + From + AsScopeInternal + PermissionStorageInternal +{ +} pub trait VAppPermissionResponse: Permission {} impl VAppPermissionResponse for T where T: Permission {} diff --git a/v-model/src/permissions.rs b/v-model/src/permissions.rs index 85229c3..93e1c25 100644 --- a/v-model/src/permissions.rs +++ b/v-model/src/permissions.rs @@ -206,12 +206,11 @@ pub trait AsScope: Sized { fn from_scope_arg(scope_arg: &str) -> Permissions { Self::from_scope(scope_arg.split(' ')) } - fn from_scope( - _scope: T, - ) -> Permissions + fn from_scope(_scope: T) -> Permissions where T: Iterator + Clone, - S: AsRef { + S: AsRef, + { Permissions::default() } } @@ -221,9 +220,7 @@ pub trait AsScopeInternal: Sized + AsScope { fn from_scope_arg(scope_arg: &str) -> Permissions { ::from_scope(scope_arg.split(' ')) } - fn from_scope( - scope: T, - ) -> Permissions + fn from_scope(scope: T) -> Permissions where T: Iterator + Clone, S: AsRef; @@ -232,7 +229,8 @@ pub trait AsScopeInternal: Sized + AsScope { pub trait PermissionStorage { fn contract(_collection: &Permissions) -> Permissions where - Self: Sized { + Self: Sized, + { Permissions::default() } fn expand( @@ -241,7 +239,8 @@ pub trait PermissionStorage { _actor_permissions: Option<&Permissions>, ) -> Permissions where - Self: Sized { + Self: Sized, + { Permissions::default() } }