Skip to content

Commit e0be59e

Browse files
authored
refactor(core): split allowlist configuration per module (#1263)
* refactor(core): split allowlist configuration per module * fix: build with all features * fix(cli): run fmt * fix(core): run fmt
1 parent 75eaaf0 commit e0be59e

File tree

23 files changed

+729
-160
lines changed

23 files changed

+729
-160
lines changed

.changes/refactor-allowlist.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": minor
3+
---
4+
5+
The `allowlist` configuration now has one object per module.

.github/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ The code for the bundler is located in `[Tauri repo root]/cli/tauri-bundler`. Bu
7878

7979
### Developing Tauri Core
8080

81-
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`.
81+
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`.
8282

8383
## Financial Contribution
8484

.github/workflows/core-lint-fmt.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ jobs:
6262
runs-on: ubuntu-latest
6363
strategy:
6464
matrix:
65-
feature: [embedded-server, all-api]
65+
feature: [embedded-server, api-all]
6666

6767
steps:
6868
- uses: actions/checkout@v2

cli/core/Cargo.lock

-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/core/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ serde_json = "1.0"
2121
notify = "4.0"
2222
shared_child = "0.3"
2323
toml_edit = "0.2"
24-
convert_case = "0.4"
2524
json-patch = "0.2"
2625
schemars = "0.8"
2726
valico = "3.5"

cli/core/config_definition.rs

+234-1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,232 @@ pub struct SecurityConfig {
250250
csp: Option<String>,
251251
}
252252

253+
trait Allowlist {
254+
fn to_features(&self) -> Vec<&str>;
255+
}
256+
257+
macro_rules! check_feature {
258+
($self:ident, $features:ident, $flag:ident, $feature_name: expr) => {
259+
if $self.$flag {
260+
$features.push($feature_name)
261+
}
262+
};
263+
}
264+
265+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
266+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
267+
struct FsAllowlistConfig {
268+
#[serde(default)]
269+
all: bool,
270+
#[serde(default)]
271+
read_text_file: bool,
272+
#[serde(default)]
273+
read_binary_file: bool,
274+
#[serde(default)]
275+
write_file: bool,
276+
#[serde(default)]
277+
write_binary_file: bool,
278+
#[serde(default)]
279+
read_dir: bool,
280+
#[serde(default)]
281+
copy_file: bool,
282+
#[serde(default)]
283+
create_dir: bool,
284+
#[serde(default)]
285+
remove_dir: bool,
286+
#[serde(default)]
287+
remove_file: bool,
288+
#[serde(default)]
289+
rename_file: bool,
290+
#[serde(default)]
291+
path: bool,
292+
}
293+
294+
impl Allowlist for FsAllowlistConfig {
295+
fn to_features(&self) -> Vec<&str> {
296+
if self.all {
297+
vec!["fs-all"]
298+
} else {
299+
let mut features = Vec::new();
300+
check_feature!(self, features, read_text_file, "fs-read-text-file");
301+
check_feature!(self, features, read_binary_file, "fs-read-binary-file");
302+
check_feature!(self, features, write_file, "fs-write-file");
303+
check_feature!(self, features, write_binary_file, "fs-write-binary-file");
304+
check_feature!(self, features, read_dir, "fs-read-dir");
305+
check_feature!(self, features, copy_file, "fs-copy-file");
306+
check_feature!(self, features, create_dir, "fs-create-dir");
307+
check_feature!(self, features, remove_dir, "fs-remove-dir");
308+
check_feature!(self, features, remove_file, "fs-remove-file");
309+
check_feature!(self, features, rename_file, "fs-rename-file");
310+
check_feature!(self, features, path, "fs-path");
311+
features
312+
}
313+
}
314+
}
315+
316+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
317+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
318+
struct WindowAllowlistConfig {
319+
#[serde(default)]
320+
all: bool,
321+
#[serde(default)]
322+
create: bool,
323+
}
324+
325+
impl Allowlist for WindowAllowlistConfig {
326+
fn to_features(&self) -> Vec<&str> {
327+
if self.all {
328+
vec!["window-all"]
329+
} else {
330+
let mut features = Vec::new();
331+
check_feature!(self, features, create, "window-create");
332+
features
333+
}
334+
}
335+
}
336+
337+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
338+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
339+
struct ShellAllowlistConfig {
340+
#[serde(default)]
341+
all: bool,
342+
#[serde(default)]
343+
execute: bool,
344+
#[serde(default)]
345+
open: bool,
346+
}
347+
348+
impl Allowlist for ShellAllowlistConfig {
349+
fn to_features(&self) -> Vec<&str> {
350+
if self.all {
351+
vec!["shell-all"]
352+
} else {
353+
let mut features = Vec::new();
354+
check_feature!(self, features, execute, "shell-execute");
355+
check_feature!(self, features, open, "shell-open");
356+
features
357+
}
358+
}
359+
}
360+
361+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
362+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
363+
struct DialogAllowlistConfig {
364+
#[serde(default)]
365+
all: bool,
366+
#[serde(default)]
367+
open: bool,
368+
#[serde(default)]
369+
save: bool,
370+
}
371+
372+
impl Allowlist for DialogAllowlistConfig {
373+
fn to_features(&self) -> Vec<&str> {
374+
if self.all {
375+
vec!["dialog-all"]
376+
} else {
377+
let mut features = Vec::new();
378+
check_feature!(self, features, open, "dialog-open");
379+
check_feature!(self, features, save, "dialog-save");
380+
features
381+
}
382+
}
383+
}
384+
385+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
386+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
387+
struct HttpAllowlistConfig {
388+
#[serde(default)]
389+
all: bool,
390+
#[serde(default)]
391+
request: bool,
392+
}
393+
394+
impl Allowlist for HttpAllowlistConfig {
395+
fn to_features(&self) -> Vec<&str> {
396+
if self.all {
397+
vec!["http-all"]
398+
} else {
399+
let mut features = Vec::new();
400+
check_feature!(self, features, request, "http-request");
401+
features
402+
}
403+
}
404+
}
405+
406+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
407+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
408+
struct NotificationAllowlistConfig {
409+
#[serde(default)]
410+
all: bool,
411+
}
412+
413+
impl Allowlist for NotificationAllowlistConfig {
414+
fn to_features(&self) -> Vec<&str> {
415+
if self.all {
416+
vec!["notification-all"]
417+
} else {
418+
vec![]
419+
}
420+
}
421+
}
422+
423+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
424+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
425+
struct GlobalShortcutAllowlistConfig {
426+
#[serde(default)]
427+
all: bool,
428+
}
429+
430+
impl Allowlist for GlobalShortcutAllowlistConfig {
431+
fn to_features(&self) -> Vec<&str> {
432+
if self.all {
433+
vec!["global-shortcut-all"]
434+
} else {
435+
vec![]
436+
}
437+
}
438+
}
439+
440+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
441+
#[serde(rename_all = "camelCase", deny_unknown_fields)]
442+
struct AllowlistConfig {
443+
#[serde(default)]
444+
all: bool,
445+
#[serde(default)]
446+
fs: FsAllowlistConfig,
447+
#[serde(default)]
448+
window: WindowAllowlistConfig,
449+
#[serde(default)]
450+
shell: ShellAllowlistConfig,
451+
#[serde(default)]
452+
dialog: DialogAllowlistConfig,
453+
#[serde(default)]
454+
http: HttpAllowlistConfig,
455+
#[serde(default)]
456+
notification: NotificationAllowlistConfig,
457+
#[serde(default)]
458+
global_shortcut: GlobalShortcutAllowlistConfig,
459+
}
460+
461+
impl Allowlist for AllowlistConfig {
462+
fn to_features(&self) -> Vec<&str> {
463+
if self.all {
464+
vec!["api-all"]
465+
} else {
466+
let mut features = Vec::new();
467+
features.extend(self.fs.to_features());
468+
features.extend(self.window.to_features());
469+
features.extend(self.shell.to_features());
470+
features.extend(self.dialog.to_features());
471+
features.extend(self.http.to_features());
472+
features.extend(self.notification.to_features());
473+
features.extend(self.global_shortcut.to_features());
474+
features
475+
}
476+
}
477+
}
478+
253479
/// The Tauri configuration object.
254480
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
255481
#[serde(rename_all = "camelCase", deny_unknown_fields)]
@@ -265,10 +491,17 @@ pub struct TauriConfig {
265491
#[serde(default)]
266492
pub bundle: BundleConfig,
267493
#[serde(default)]
268-
pub allowlist: HashMap<String, bool>,
494+
allowlist: AllowlistConfig,
269495
pub security: Option<SecurityConfig>,
270496
}
271497

498+
impl TauriConfig {
499+
#[allow(dead_code)]
500+
pub fn features(&self) -> Vec<&str> {
501+
self.allowlist.to_features()
502+
}
503+
}
504+
272505
/// The Build configuration object.
273506
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
274507
#[serde(rename_all = "camelCase", deny_unknown_fields)]

0 commit comments

Comments
 (0)