Skip to content

Commit

Permalink
refactor(core): split allowlist configuration per module (#1263)
Browse files Browse the repository at this point in the history
* refactor(core): split allowlist configuration per module

* fix: build with all features

* fix(cli): run fmt

* fix(core): run fmt
  • Loading branch information
lucasfernog committed Feb 20, 2021
1 parent 75eaaf0 commit e0be59e
Show file tree
Hide file tree
Showing 23 changed files with 729 additions and 160 deletions.
5 changes: 5 additions & 0 deletions .changes/refactor-allowlist.md
@@ -0,0 +1,5 @@
---
"tauri": minor
---

The `allowlist` configuration now has one object per module.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Expand Up @@ -78,7 +78,7 @@ The code for the bundler is located in `[Tauri repo root]/cli/tauri-bundler`. Bu

### Developing Tauri Core

The code for Tauri core is located in `[Tauri repo root]/tauri`. The easiest way to test your changes is to use the `[Tauri repo root]/tauri/examples/communication` app. It automatically rebuilds and uses your local codebase. Just run `yarn tauri build` or `yarn tauri dev` in the communication app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "all-api", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/tauri`.
The code for Tauri core is located in `[Tauri repo root]/tauri`. The easiest way to test your changes is to use the `[Tauri repo root]/tauri/examples/communication` app. It automatically rebuilds and uses your local codebase. Just run `yarn tauri build` or `yarn tauri dev` in the communication app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "api-all", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/tauri`.

## Financial Contribution

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/core-lint-fmt.yml
Expand Up @@ -62,7 +62,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
feature: [embedded-server, all-api]
feature: [embedded-server, api-all]

steps:
- uses: actions/checkout@v2
Expand Down
7 changes: 0 additions & 7 deletions cli/core/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cli/core/Cargo.toml
Expand Up @@ -21,7 +21,6 @@ serde_json = "1.0"
notify = "4.0"
shared_child = "0.3"
toml_edit = "0.2"
convert_case = "0.4"
json-patch = "0.2"
schemars = "0.8"
valico = "3.5"
Expand Down
235 changes: 234 additions & 1 deletion cli/core/config_definition.rs
Expand Up @@ -250,6 +250,232 @@ pub struct SecurityConfig {
csp: Option<String>,
}

trait Allowlist {
fn to_features(&self) -> Vec<&str>;
}

macro_rules! check_feature {
($self:ident, $features:ident, $flag:ident, $feature_name: expr) => {
if $self.$flag {
$features.push($feature_name)
}
};
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct FsAllowlistConfig {
#[serde(default)]
all: bool,
#[serde(default)]
read_text_file: bool,
#[serde(default)]
read_binary_file: bool,
#[serde(default)]
write_file: bool,
#[serde(default)]
write_binary_file: bool,
#[serde(default)]
read_dir: bool,
#[serde(default)]
copy_file: bool,
#[serde(default)]
create_dir: bool,
#[serde(default)]
remove_dir: bool,
#[serde(default)]
remove_file: bool,
#[serde(default)]
rename_file: bool,
#[serde(default)]
path: bool,
}

impl Allowlist for FsAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["fs-all"]
} else {
let mut features = Vec::new();
check_feature!(self, features, read_text_file, "fs-read-text-file");
check_feature!(self, features, read_binary_file, "fs-read-binary-file");
check_feature!(self, features, write_file, "fs-write-file");
check_feature!(self, features, write_binary_file, "fs-write-binary-file");
check_feature!(self, features, read_dir, "fs-read-dir");
check_feature!(self, features, copy_file, "fs-copy-file");
check_feature!(self, features, create_dir, "fs-create-dir");
check_feature!(self, features, remove_dir, "fs-remove-dir");
check_feature!(self, features, remove_file, "fs-remove-file");
check_feature!(self, features, rename_file, "fs-rename-file");
check_feature!(self, features, path, "fs-path");
features
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct WindowAllowlistConfig {
#[serde(default)]
all: bool,
#[serde(default)]
create: bool,
}

impl Allowlist for WindowAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["window-all"]
} else {
let mut features = Vec::new();
check_feature!(self, features, create, "window-create");
features
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct ShellAllowlistConfig {
#[serde(default)]
all: bool,
#[serde(default)]
execute: bool,
#[serde(default)]
open: bool,
}

impl Allowlist for ShellAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["shell-all"]
} else {
let mut features = Vec::new();
check_feature!(self, features, execute, "shell-execute");
check_feature!(self, features, open, "shell-open");
features
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct DialogAllowlistConfig {
#[serde(default)]
all: bool,
#[serde(default)]
open: bool,
#[serde(default)]
save: bool,
}

impl Allowlist for DialogAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["dialog-all"]
} else {
let mut features = Vec::new();
check_feature!(self, features, open, "dialog-open");
check_feature!(self, features, save, "dialog-save");
features
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct HttpAllowlistConfig {
#[serde(default)]
all: bool,
#[serde(default)]
request: bool,
}

impl Allowlist for HttpAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["http-all"]
} else {
let mut features = Vec::new();
check_feature!(self, features, request, "http-request");
features
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct NotificationAllowlistConfig {
#[serde(default)]
all: bool,
}

impl Allowlist for NotificationAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["notification-all"]
} else {
vec![]
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct GlobalShortcutAllowlistConfig {
#[serde(default)]
all: bool,
}

impl Allowlist for GlobalShortcutAllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["global-shortcut-all"]
} else {
vec![]
}
}
}

#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
struct AllowlistConfig {
#[serde(default)]
all: bool,
#[serde(default)]
fs: FsAllowlistConfig,
#[serde(default)]
window: WindowAllowlistConfig,
#[serde(default)]
shell: ShellAllowlistConfig,
#[serde(default)]
dialog: DialogAllowlistConfig,
#[serde(default)]
http: HttpAllowlistConfig,
#[serde(default)]
notification: NotificationAllowlistConfig,
#[serde(default)]
global_shortcut: GlobalShortcutAllowlistConfig,
}

impl Allowlist for AllowlistConfig {
fn to_features(&self) -> Vec<&str> {
if self.all {
vec!["api-all"]
} else {
let mut features = Vec::new();
features.extend(self.fs.to_features());
features.extend(self.window.to_features());
features.extend(self.shell.to_features());
features.extend(self.dialog.to_features());
features.extend(self.http.to_features());
features.extend(self.notification.to_features());
features.extend(self.global_shortcut.to_features());
features
}
}
}

/// The Tauri configuration object.
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
Expand All @@ -265,10 +491,17 @@ pub struct TauriConfig {
#[serde(default)]
pub bundle: BundleConfig,
#[serde(default)]
pub allowlist: HashMap<String, bool>,
allowlist: AllowlistConfig,
pub security: Option<SecurityConfig>,
}

impl TauriConfig {
#[allow(dead_code)]
pub fn features(&self) -> Vec<&str> {
self.allowlist.to_features()
}
}

/// The Build configuration object.
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
Expand Down

0 comments on commit e0be59e

Please sign in to comment.