Skip to content

Commit 4942d80

Browse files
feat: Auto Generation of ACL Schema File for Documentation (#9903)
* Add auto generated acl schema files for docs * update CI --------- Co-authored-by: Lucas Nogueira <[email protected]> Co-authored-by: Lucas Nogueira <[email protected]>
1 parent 594e3e2 commit 4942d80

File tree

12 files changed

+603
-4
lines changed

12 files changed

+603
-4
lines changed

.github/workflows/check-generated-files.yml

+6-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ jobs:
3737
- 'core/tauri-utils/src/config.rs'
3838
- 'tooling/cli/schema.json'
3939
- 'core/tauri-config-schema/schema.json'
40+
- 'core/tauri-acl-schema/*.json'
41+
4042
4143
api:
4244
runs-on: ubuntu-latest
@@ -70,8 +72,11 @@ jobs:
7072
with:
7173
workspaces: core -> ../target
7274

73-
- name: generate schema.json
75+
- name: generate config schema
7476
run: cargo build --manifest-path ./core/tauri-config-schema/Cargo.toml
7577

78+
- name: generate ACL schema
79+
run: cargo build --manifest-path ./core/tauri-acl-schema/Cargo.toml
80+
7681
- name: check schema
7782
run: ./.scripts/ci/has-diff.sh

Cargo.lock

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

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ members = [
1010
"core/tauri-build",
1111
"core/tauri-codegen",
1212
"core/tauri-config-schema",
13+
"core/tauri-acl-schema",
1314
"core/tauri-plugin",
1415

1516
# integration tests

core/tauri-acl-schema/Cargo.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "tauri-acl-schema"
3+
version = "0.0.0"
4+
edition = "2021"
5+
publish = false
6+
7+
[build-dependencies]
8+
tauri-utils = { features = [ "schema" ], path = "../tauri-utils" }
9+
schemars = { version = "0.8", features = ["url", "preserve_order"] }
10+
serde = { version = "1.0", features = ["derive"] }
11+
serde_json = "1.0"
12+
url = { version = "2.3", features = ["serde"] }

core/tauri-acl-schema/build.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
use std::{
6+
error::Error,
7+
fs::File,
8+
io::{BufWriter, Write},
9+
path::PathBuf,
10+
};
11+
12+
use schemars::schema::RootSchema;
13+
14+
pub fn main() -> Result<(), Box<dyn Error>> {
15+
let cap_schema = schemars::schema_for!(tauri_utils::acl::capability::Capability);
16+
let perm_schema = schemars::schema_for!(tauri_utils::acl::Permission);
17+
let scope_schema = schemars::schema_for!(tauri_utils::acl::Scopes);
18+
19+
let crate_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?);
20+
21+
write_schema_file(cap_schema, crate_dir.join("capability-schema.json"))?;
22+
write_schema_file(perm_schema, crate_dir.join("permission-schema.json"))?;
23+
write_schema_file(scope_schema, crate_dir.join("scope-schema.json"))?;
24+
25+
Ok(())
26+
}
27+
28+
fn write_schema_file(schema: RootSchema, outpath: PathBuf) -> Result<(), Box<dyn Error>> {
29+
let schema_str = serde_json::to_string_pretty(&schema).unwrap();
30+
let mut schema_file = BufWriter::new(File::create(outpath)?);
31+
write!(schema_file, "{schema_str}")?;
32+
33+
Ok(())
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "Capability",
4+
"description": "A grouping and boundary mechanism developers can use to separate windows or plugins functionality from each other at runtime.\n\nIf a window is not matching any capability then it has no access to the IPC layer at all.\n\nThis can be done to create trust groups and reduce impact of vulnerabilities in certain plugins or windows. Windows can be added to a capability by exact name or glob patterns like *, admin-* or main-window.",
5+
"type": "object",
6+
"required": [
7+
"identifier",
8+
"permissions"
9+
],
10+
"properties": {
11+
"identifier": {
12+
"description": "Identifier of the capability.",
13+
"type": "string"
14+
},
15+
"description": {
16+
"description": "Description of the capability.",
17+
"default": "",
18+
"type": "string"
19+
},
20+
"remote": {
21+
"description": "Configure remote URLs that can use the capability permissions.",
22+
"anyOf": [
23+
{
24+
"$ref": "#/definitions/CapabilityRemote"
25+
},
26+
{
27+
"type": "null"
28+
}
29+
]
30+
},
31+
"local": {
32+
"description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.",
33+
"default": true,
34+
"type": "boolean"
35+
},
36+
"windows": {
37+
"description": "List of windows that uses this capability. Can be a glob pattern.\n\nOn multiwebview windows, prefer [`Self::webviews`] for a fine grained access control.",
38+
"type": "array",
39+
"items": {
40+
"type": "string"
41+
}
42+
},
43+
"webviews": {
44+
"description": "List of webviews that uses this capability. Can be a glob pattern.\n\nThis is only required when using on multiwebview contexts, by default all child webviews of a window that matches [`Self::windows`] are linked.",
45+
"type": "array",
46+
"items": {
47+
"type": "string"
48+
}
49+
},
50+
"permissions": {
51+
"description": "List of permissions attached to this capability. Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.",
52+
"type": "array",
53+
"items": {
54+
"$ref": "#/definitions/PermissionEntry"
55+
}
56+
},
57+
"platforms": {
58+
"description": "Target platforms this capability applies. By default all platforms are affected by this capability.",
59+
"type": [
60+
"array",
61+
"null"
62+
],
63+
"items": {
64+
"$ref": "#/definitions/Target"
65+
}
66+
}
67+
},
68+
"definitions": {
69+
"CapabilityRemote": {
70+
"description": "Configuration for remote URLs that are associated with the capability.",
71+
"type": "object",
72+
"required": [
73+
"urls"
74+
],
75+
"properties": {
76+
"urls": {
77+
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n# Examples\n\n- \"https://*.mydomain.dev\": allows subdomains of mydomain.dev - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api",
78+
"type": "array",
79+
"items": {
80+
"type": "string"
81+
}
82+
}
83+
}
84+
},
85+
"PermissionEntry": {
86+
"description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`] or an object that references a permission and extends its scope.",
87+
"anyOf": [
88+
{
89+
"description": "Reference a permission or permission set by identifier.",
90+
"allOf": [
91+
{
92+
"$ref": "#/definitions/Identifier"
93+
}
94+
]
95+
},
96+
{
97+
"description": "Reference a permission or permission set by identifier and extends its scope.",
98+
"type": "object",
99+
"required": [
100+
"identifier"
101+
],
102+
"properties": {
103+
"identifier": {
104+
"description": "Identifier of the permission or permission set.",
105+
"allOf": [
106+
{
107+
"$ref": "#/definitions/Identifier"
108+
}
109+
]
110+
},
111+
"allow": {
112+
"description": "Data that defines what is allowed by the scope.",
113+
"type": [
114+
"array",
115+
"null"
116+
],
117+
"items": {
118+
"$ref": "#/definitions/Value"
119+
}
120+
},
121+
"deny": {
122+
"description": "Data that defines what is denied by the scope.",
123+
"type": [
124+
"array",
125+
"null"
126+
],
127+
"items": {
128+
"$ref": "#/definitions/Value"
129+
}
130+
}
131+
}
132+
}
133+
]
134+
},
135+
"Identifier": {
136+
"type": "string"
137+
},
138+
"Value": {
139+
"description": "All supported ACL values.",
140+
"anyOf": [
141+
{
142+
"description": "Represents a null JSON value.",
143+
"type": "null"
144+
},
145+
{
146+
"description": "Represents a [`bool`].",
147+
"type": "boolean"
148+
},
149+
{
150+
"description": "Represents a valid ACL [`Number`].",
151+
"allOf": [
152+
{
153+
"$ref": "#/definitions/Number"
154+
}
155+
]
156+
},
157+
{
158+
"description": "Represents a [`String`].",
159+
"type": "string"
160+
},
161+
{
162+
"description": "Represents a list of other [`Value`]s.",
163+
"type": "array",
164+
"items": {
165+
"$ref": "#/definitions/Value"
166+
}
167+
},
168+
{
169+
"description": "Represents a map of [`String`] keys to [`Value`]s.",
170+
"type": "object",
171+
"additionalProperties": {
172+
"$ref": "#/definitions/Value"
173+
}
174+
}
175+
]
176+
},
177+
"Number": {
178+
"description": "A valid ACL number.",
179+
"anyOf": [
180+
{
181+
"description": "Represents an [`i64`].",
182+
"type": "integer",
183+
"format": "int64"
184+
},
185+
{
186+
"description": "Represents a [`f64`].",
187+
"type": "number",
188+
"format": "double"
189+
}
190+
]
191+
},
192+
"Target": {
193+
"description": "Platform target.",
194+
"oneOf": [
195+
{
196+
"description": "MacOS.",
197+
"type": "string",
198+
"enum": [
199+
"macOS"
200+
]
201+
},
202+
{
203+
"description": "Windows.",
204+
"type": "string",
205+
"enum": [
206+
"windows"
207+
]
208+
},
209+
{
210+
"description": "Linux.",
211+
"type": "string",
212+
"enum": [
213+
"linux"
214+
]
215+
},
216+
{
217+
"description": "Android.",
218+
"type": "string",
219+
"enum": [
220+
"android"
221+
]
222+
},
223+
{
224+
"description": "iOS.",
225+
"type": "string",
226+
"enum": [
227+
"iOS"
228+
]
229+
}
230+
]
231+
}
232+
}
233+
}

0 commit comments

Comments
 (0)