Skip to content

Commit e5c077b

Browse files
authored
Remove unsafe permissions and add dialog (#985)
Fixes #915
1 parent d79bc8c commit e5c077b

16 files changed

+838
-8
lines changed

build-aux/re.sonny.Workbench.Devel.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
"--share=ipc",
2121
"--socket=fallback-x11",
2222
"--socket=wayland",
23-
"--device=dri",
24-
"--share=network",
25-
"--socket=pulseaudio"
23+
"--device=dri"
2624
],
2725
"cleanup": [
2826
"#/include",

build-aux/re.sonny.Workbench.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@
2020
"--share=ipc",
2121
"--socket=fallback-x11",
2222
"--socket=wayland",
23-
"--device=dri",
24-
"--share=network",
25-
"--socket=pulseaudio"
23+
"--device=dri"
2624
],
2725
"cleanup": [
2826
"#/include",

build-aux/wip/run.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@ async function runCommand(argv) {
164164
"--allow=devel",
165165
`--bind-mount=/run/user/1000/doc=/run/user/1000/doc/by-app/${flatpak_id}`,
166166
...manifest["finish-args"],
167+
168+
// Non default permissions
169+
// see Permissions.js
170+
// consider getting installed overrides instead
171+
"--share=network",
172+
"--socket=pulseaudio",
173+
"--device=input",
174+
167175
"--talk-name=org.freedesktop.portal.*",
168176
"--talk-name=org.a11y.Bus",
169177
"--bind-mount=/run/flatpak/at-spi-bus=/run/user/1000/at-spi/bus",

src/Library/Library.blp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,13 @@ Adw.Window window {
6363

6464
DropDown dropdown_language {
6565
valign: end;
66+
6667
model: Gtk.StringList {};
6768
}
6869

6970
DropDown dropdown_category {
7071
valign: end;
72+
7173
model: Gtk.StringList {};
7274
}
7375
}
@@ -105,7 +107,10 @@ Adw.Window window {
105107
Button button_reset {
106108
label: _("Reset filters");
107109
halign: center;
108-
styles ["pill"]
110+
111+
styles [
112+
"pill"
113+
]
109114
}
110115
}
111116

src/Library/Library.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import illustration from "./library.svg";
1717
import { gettext as _ } from "gettext";
1818

1919
import { build } from "../../troll/src/builder.js";
20+
import {
21+
needsAdditionalPermissions,
22+
showPermissionsDialog,
23+
} from "../Permissions/Permissions.js";
2024

2125
export default function Library({ application }) {
2226
const objects = build(resource);
@@ -204,9 +208,17 @@ async function openDemo({ application, demo_name, language }) {
204208
);
205209
}
206210

207-
const { load, runCode } = Window({ application, session });
211+
const { load, runCode, window } = Window({
212+
application,
213+
session,
214+
});
208215
await load();
209216

217+
if (needsAdditionalPermissions({ demo })) {
218+
showPermissionsDialog({ window });
219+
return;
220+
}
221+
210222
const code_language = session.getCodeLanguage();
211223
const run = autorun && code_language.id === "javascript";
212224
if (run) {

src/Permissions/Permissions.blp

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
using Gtk 4.0;
2+
using Adw 1;
3+
4+
Adw.Dialog dialog {
5+
content-height: 750;
6+
content-width: 600;
7+
8+
Adw.ToolbarView {
9+
[top]
10+
Adw.HeaderBar {}
11+
12+
content: ScrolledWindow {
13+
hscrollbar-policy: never;
14+
15+
Adw.Clamp {
16+
maximum-size: 520;
17+
tightening-threshold: 400;
18+
margin-start: 12;
19+
margin-end: 12;
20+
margin-bottom: 24;
21+
22+
Box {
23+
orientation: vertical;
24+
halign: fill;
25+
spacing: 24;
26+
// Gtk.Picture needs to be wrapped in a box to behave properly
27+
Box {
28+
halign: center;
29+
30+
Picture picture_illustration {
31+
can-shrink: false;
32+
margin-bottom: 24;
33+
}
34+
}
35+
36+
Label {
37+
label: _("Permissions Needed");
38+
39+
styles [
40+
"title-1"
41+
]
42+
}
43+
44+
Label {
45+
label: _("Workbench needs additional permissions. Please run the following command in a terminal and restart the app.");
46+
wrap: true;
47+
justify: center;
48+
}
49+
50+
Label label_command {
51+
use-markup: true;
52+
wrap: true;
53+
wrap-mode: word_char;
54+
selectable: true;
55+
xalign: 0;
56+
57+
styles [
58+
"command_snippet"
59+
]
60+
}
61+
62+
Box {
63+
orientation: vertical;
64+
65+
Box {
66+
margin-bottom: 6;
67+
68+
Label {
69+
label: _("What it does");
70+
halign: start;
71+
hexpand: true;
72+
73+
styles [
74+
"heading"
75+
]
76+
}
77+
78+
Button button_info {
79+
icon-name: "re.sonny.Workbench-external-link-symbolic";
80+
81+
styles [
82+
"flat"
83+
]
84+
}
85+
}
86+
87+
ListBox {
88+
selection-mode: none;
89+
90+
styles [
91+
"boxed-list"
92+
]
93+
94+
Adw.ActionRow {
95+
[prefix]
96+
Image {
97+
icon-name: "re.sonny.Workbench-person-symbolic";
98+
}
99+
100+
title: _("--user");
101+
subtitle: _("Grant for your account only");
102+
103+
styles [
104+
"property"
105+
]
106+
}
107+
108+
Adw.ActionRow {
109+
[prefix]
110+
Image {
111+
icon-name: "re.sonny.Workbench-network-wireless-symbolic";
112+
}
113+
114+
title: _("--share-network");
115+
subtitle: _("Network access");
116+
117+
styles [
118+
"property"
119+
]
120+
}
121+
122+
Adw.ActionRow {
123+
[prefix]
124+
Image {
125+
icon-name: "re.sonny.Workbench-speakers-symbolic";
126+
}
127+
128+
title: _("--socket=pulseaudio");
129+
subtitle: _("Record and play audio");
130+
131+
styles [
132+
"property"
133+
]
134+
}
135+
136+
Adw.ActionRow {
137+
[prefix]
138+
Image {
139+
icon-name: "re.sonny.Workbench-gamepad-symbolic";
140+
}
141+
142+
title: _("--device=input");
143+
subtitle: _("Access to input device such as gamepads");
144+
145+
styles [
146+
"property"
147+
]
148+
}
149+
}
150+
}
151+
}
152+
}
153+
};
154+
}
155+
}

src/Permissions/Permissions.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import Gio from "gi://Gio";
2+
import GLib from "gi://GLib";
3+
import Gtk from "gi://Gtk";
4+
5+
import { build } from "../../troll/src/main.js";
6+
7+
import Interface from "./Permissions.blp" with { type: "uri" };
8+
9+
import illustration from "./permissions.svg";
10+
11+
import { getFlatpakInfo } from "../util.js";
12+
13+
const action_permissions = new Gio.SimpleAction({
14+
name: "permissions",
15+
parameter_type: null,
16+
});
17+
18+
export function Permissions({ window }) {
19+
const { dialog, picture_illustration, label_command, button_info } =
20+
build(Interface);
21+
22+
picture_illustration.set_resource(illustration);
23+
label_command.label = `flatpak override --user --share=network --socket=pulseaudio --device=input ${GLib.getenv(
24+
"FLATPAK_ID",
25+
)}`;
26+
27+
button_info.connect("clicked", () => {
28+
new Gtk.UriLauncher({
29+
uri: "https://docs.flatpak.org/en/latest/sandbox-permissions.html",
30+
})
31+
.launch(window, null)
32+
.catch(console.error);
33+
});
34+
35+
action_permissions.connect("activate", () => {
36+
dialog.present(window);
37+
});
38+
39+
window.add_action(action_permissions);
40+
}
41+
42+
const missing_permissions = (() => {
43+
const flatpak_info = getFlatpakInfo();
44+
const shared = flatpak_info.get_string_list("Context", "shared");
45+
const sockets = flatpak_info.get_string_list("Context", "sockets");
46+
const devices = flatpak_info.get_string_list("Context", "devices");
47+
48+
return (
49+
!shared.includes("network") ||
50+
!sockets.includes("pulseaudio") ||
51+
!devices.includes("all")
52+
);
53+
})();
54+
55+
export function needsAdditionalPermissions({ demo }) {
56+
if (!demo["flatpak-finish-args"]) return false;
57+
return missing_permissions;
58+
}
59+
60+
export function showPermissionsDialog({ window }) {
61+
window.activate_action("permissions", null);
62+
}

0 commit comments

Comments
 (0)