use glob::Pattern;
use serde::{Deserialize, Serialize};
use std::num::NonZeroU64;
use thiserror::Error;
pub use self::{identifier::*, value::*};
#[cfg(feature = "build")]
pub mod build;
pub mod capability;
pub mod identifier;
pub mod plugin;
pub mod resolved;
pub mod value;
#[derive(Debug, Error)]
pub enum Error {
#[error("expected build script env var {0}, but it was not found - ensure this is called in a build script")]
BuildVar(&'static str),
#[error("package.links field in the Cargo manifest is not set, it should be set to the same as package.name")]
LinksMissing,
#[error(
"package.links field in the Cargo manifest MUST be set to the same value as package.name"
)]
LinksName,
#[error("failed to read file: {0}")]
ReadFile(std::io::Error),
#[error("failed to write file: {0}")]
WriteFile(std::io::Error),
#[error("failed to create file: {0}")]
CreateFile(std::io::Error),
#[cfg(feature = "build")]
#[error("failed to execute: {0}")]
Metadata(#[from] ::cargo_metadata::Error),
#[error("failed to run glob: {0}")]
Glob(#[from] glob::PatternError),
#[error("failed to parse TOML: {0}")]
Toml(#[from] toml::de::Error),
#[error("failed to parse JSON: {0}")]
Json(#[from] serde_json::Error),
#[error("unknown permission format {0}")]
UnknownPermissionFormat(String),
#[error("unknown capability format {0}")]
UnknownCapabilityFormat(String),
#[error("permission {permission} not found from set {set}")]
SetPermissionNotFound {
permission: String,
set: String,
},
#[error("plugin {plugin} has no default permission")]
MissingDefaultPermission {
plugin: String,
},
#[error("unknown plugin {plugin}, expected one of {available}")]
UnknownPlugin {
plugin: String,
available: String,
},
#[error("unknown permission {permission} for plugin {plugin}")]
UnknownPermission {
plugin: String,
permission: String,
},
}
#[derive(Debug, Default, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct Commands {
#[serde(default)]
pub allow: Vec<String>,
#[serde(default)]
pub deny: Vec<String>,
}
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct Scopes {
#[serde(skip_serializing_if = "Option::is_none")]
pub allow: Option<Vec<Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deny: Option<Vec<Value>>,
}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct Permission {
pub version: Option<NonZeroU64>,
pub identifier: String,
pub description: Option<String>,
#[serde(default)]
pub commands: Commands,
#[serde(default)]
pub scope: Scopes,
}
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct PermissionSet {
pub identifier: String,
pub description: String,
pub permissions: Vec<String>,
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub enum ExecutionContext {
Local,
Remote {
url: Pattern,
},
}
#[cfg(feature = "build")]
mod build_ {
use std::convert::identity;
use crate::{literal_struct, tokens::*};
use super::*;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens, TokenStreamExt};
impl ToTokens for ExecutionContext {
fn to_tokens(&self, tokens: &mut TokenStream) {
let prefix = quote! { ::tauri::utils::acl::ExecutionContext };
tokens.append_all(match self {
Self::Local => {
quote! { #prefix::Local }
}
Self::Remote { url } => {
let url = url.as_str();
quote! { #prefix::Remote { url: #url.parse().unwrap() } }
}
});
}
}
impl ToTokens for Commands {
fn to_tokens(&self, tokens: &mut TokenStream) {
let allow = vec_lit(&self.allow, str_lit);
let deny = vec_lit(&self.deny, str_lit);
literal_struct!(tokens, ::tauri::utils::acl::Commands, allow, deny)
}
}
impl ToTokens for Scopes {
fn to_tokens(&self, tokens: &mut TokenStream) {
let allow = opt_vec_lit(self.allow.as_ref(), identity);
let deny = opt_vec_lit(self.deny.as_ref(), identity);
literal_struct!(tokens, ::tauri::utils::acl::Scopes, allow, deny)
}
}
impl ToTokens for Permission {
fn to_tokens(&self, tokens: &mut TokenStream) {
let version = opt_lit_owned(self.version.as_ref().map(|v| {
let v = v.get();
quote!(::core::num::NonZeroU64::new(#v).unwrap())
}));
let identifier = str_lit(&self.identifier);
let description = opt_str_lit(self.description.as_ref());
let commands = &self.commands;
let scope = &self.scope;
literal_struct!(
tokens,
::tauri::utils::acl::Permission,
version,
identifier,
description,
commands,
scope
)
}
}
impl ToTokens for PermissionSet {
fn to_tokens(&self, tokens: &mut TokenStream) {
let identifier = str_lit(&self.identifier);
let description = str_lit(&self.description);
let permissions = vec_lit(&self.permissions, str_lit);
literal_struct!(
tokens,
::tauri::utils::acl::PermissionSet,
identifier,
description,
permissions
)
}
}
}