Skip to content

Commit def02b3

Browse files
committed
LinuxChromiumPolicyInstaller: (WIP) Loop over all found apps.
1 parent 1a281c9 commit def02b3

File tree

1 file changed

+99
-48
lines changed

1 file changed

+99
-48
lines changed

src/qz/installer/apps/chromium/LinuxChromiumPolicyInstaller.java

Lines changed: 99 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import qz.common.Constants;
1010
import qz.installer.Installer;
1111
import qz.installer.apps.ChromiumPolicyInstaller;
12+
import qz.installer.apps.locator.AppAlias;
13+
import qz.installer.apps.locator.AppInfo;
14+
import qz.installer.apps.locator.AppLocator;
1215
import qz.utils.FileUtilities;
1316

1417
import java.io.BufferedWriter;
@@ -17,72 +20,120 @@
1720
import java.io.IOException;
1821
import java.nio.charset.StandardCharsets;
1922
import java.nio.file.Files;
23+
import java.nio.file.Path;
2024
import java.nio.file.Paths;
25+
import java.util.HashSet;
26+
import java.util.Locale;
2127

2228
public class LinuxChromiumPolicyInstaller extends ChromiumPolicyInstaller {
2329
private static final Logger log = LogManager.getLogger(LinuxChromiumPolicyInstaller.class);
2430

25-
private static final String[] MANAGED_POLICY_PATH_PATTERNS = {
26-
"/etc/chromium/policies/managed/%s.json",
27-
"/etc/opt/chrome/policies/managed/%s.json",
28-
"/etc/opt/edge/policies/managed/%s.json"
29-
};
31+
private static final String MANAGED_POLICY_PATH_PATTERN = "%s/policies/managed/%s.json";
32+
33+
public static void main(String ... args) {
34+
LinuxChromiumPolicyInstaller installer = new LinuxChromiumPolicyInstaller();
35+
installer.install(Installer.PrivilegeLevel.SYSTEM, "SafeBrowsingEnabled", "true");
36+
installer.uninstall(Installer.PrivilegeLevel.SYSTEM, "SafeBrowsingEnabled", "true");
37+
}
38+
39+
// TODO:
40+
// 1. Decide whether we loop over all apps or all found apps
41+
// 2. Decide if we should use a symlink to a JSON file in /opt/qz-tray or if we should
42+
// write each file individually
43+
// 3. JSON should support boolean/int/string and maybe array
3044

3145
@Override
3246
public boolean install(Installer.PrivilegeLevel scope, String policyName, String ... values) {
3347
if(scope != Installer.PrivilegeLevel.SYSTEM) {
48+
// TODO: Remove this if Linux user-level policies can be confirmed
3449
log.info("Skipping installation of Chromium policy {}, not supported as PrivilegeLevel {}", policyName, scope);
3550
return false;
3651
}
37-
for(String pattern : MANAGED_POLICY_PATH_PATTERNS) {
38-
// Chromium policy, e.g. /etc/chromium/policies/managed/qz-tray.json
39-
File location = Paths.get(String.format(pattern, Constants.PROPS_FILE)).toFile();
40-
log.info("Installing Chromium policy {} {}...", policyName, location);
41-
42-
43-
// Build JSON array (e.g. { "URLAllowlist": [ "qz://*"] } )
44-
JSONObject jsonPolicy = new JSONObject();
45-
JSONArray jsonArray = new JSONArray();
46-
47-
try {
48-
// Ensure parent is writable
49-
FileUtilities.setPermissionsParentally(Files.createDirectories(location.getParentFile().toPath()), false);
50-
51-
// Populate object
52-
if (location.exists()) {
53-
jsonPolicy = new JSONObject(FileUtils.readFileToString(location, StandardCharsets.UTF_8));
54-
JSONArray found = jsonPolicy.optJSONArray(policyName);
55-
if(found == null) {
56-
log.info("Chromium policy found {} but without entry for {}, we'll add it", location, policyName);
57-
} else {
58-
jsonArray = found;
59-
}
52+
boolean success = true;
53+
for(AppInfo appInfo : AppLocator.getInstance().locate(AppAlias.CHROMIUM)) {
54+
if(!writeJson(calculatePolicyFile(scope, appInfo), policyName, values)) {
55+
success = false;
56+
}
57+
}
58+
return success;
59+
}
60+
61+
private static File calculatePolicyFile(Installer.PrivilegeLevel scope, AppInfo appInfo) {
62+
Path prefix;
63+
switch(scope) {
64+
case SYSTEM:
65+
prefix = Paths.get("/");
66+
switch(appInfo.getName(true)) {
67+
case "chromium":
68+
// OS-provided are stored in /etc/<name>
69+
prefix = prefix.resolve("etc");
70+
break;
71+
default:
72+
// 3rd-party provided are stored in /etc/opt/<name>
73+
prefix = prefix.resolve("etc").resolve("opt");
6074
}
75+
break;
76+
case USER:
77+
// ~/.config
78+
prefix = Paths.get(System.getProperty("user.home")).resolve(".config");
79+
break;
80+
default:
81+
throw new UnsupportedOperationException(String.format("Scope %s is not yet supported", scope));
82+
}
83+
prefix = prefix.resolve(appInfo.getName(true).toLowerCase(Locale.ENGLISH));
84+
String policyFile = String.format(MANAGED_POLICY_PATH_PATTERN, prefix, Constants.PROPS_FILE);
85+
return new File(policyFile);
86+
}
87+
88+
private static boolean writeJson(File location, String policyName, String ... values) {
89+
// Chromium policy, e.g. /etc/chromium/policies/managed/qz-tray.json
90+
///File location = Paths.get(String.format(pattern, Constants.PROPS_FILE)).toFile();
91+
log.info("Installing Chromium policy {} {}...", policyName, location);
6192

62-
value:
63-
for(String value : values) {
64-
for(int i = 0; i < jsonArray.length(); i++) {
65-
if (jsonArray.optString(i, "").equals(value)) {
66-
log.info("Chromium policy {} '{}' already exists at location {}, skipping", policyName, value, location);
67-
continue value;
68-
}
93+
94+
// Build JSON array (e.g. { "URLAllowlist": [ "qz://*"] } )
95+
JSONObject jsonPolicy = new JSONObject();
96+
JSONArray jsonArray = new JSONArray();
97+
98+
try {
99+
// Ensure parent is writable
100+
FileUtilities.setPermissionsParentally(Files.createDirectories(location.getParentFile().toPath()), false);
101+
102+
// Populate object
103+
if (location.exists()) {
104+
jsonPolicy = new JSONObject(FileUtils.readFileToString(location, StandardCharsets.UTF_8));
105+
JSONArray found = jsonPolicy.optJSONArray(policyName);
106+
if(found == null) {
107+
log.info("Chromium policy found {} but without entry for {}, we'll add it", location, policyName);
108+
} else {
109+
jsonArray = found;
110+
}
111+
}
112+
113+
value:
114+
for(String value : values) {
115+
for(int i = 0; i < jsonArray.length(); i++) {
116+
if (jsonArray.optString(i, "").equals(value)) {
117+
log.info("Chromium policy {} '{}' already exists at location {}, skipping", policyName, value, location);
118+
continue value;
69119
}
70-
jsonArray.put(value);
71120
}
121+
jsonArray.put(value);
122+
}
72123

73-
// Insert array into object
74-
jsonPolicy.put(policyName, jsonArray);
124+
// Insert array into object
125+
jsonPolicy.put(policyName, jsonArray);
75126

76-
// Write contents, ensuring policy file is world readable
77-
try(BufferedWriter writer = new BufferedWriter(new FileWriter(location))) {
78-
writer.write(jsonPolicy.toString());
79-
if (!location.setReadable(true, false)) {
80-
throw new IOException("Unable to set readable: " + location);
81-
}
127+
// Write contents, ensuring policy file is world readable
128+
try(BufferedWriter writer = new BufferedWriter(new FileWriter(location))) {
129+
writer.write(jsonPolicy.toString());
130+
if (!location.setReadable(true, false)) {
131+
throw new IOException("Unable to set readable: " + location);
82132
}
83-
} catch(IOException | JSONException e) {
84-
log.warn("An error occurred while writing the new policy file {}", location, e);
85133
}
134+
} catch(IOException | JSONException e) {
135+
log.warn("An error occurred while writing the new policy file {}", location, e);
136+
return false;
86137
}
87138
return true;
88139
}
@@ -93,9 +144,9 @@ public boolean uninstall(Installer.PrivilegeLevel scope, String policyName, Stri
93144
log.info("Skipping removal of Chromium policy {}, not supported as PrivilegeLevel {}", policyName, scope);
94145
return false;
95146
}
96-
for(String pattern : MANAGED_POLICY_PATH_PATTERNS) {
147+
for(AppInfo appInfo : AppLocator.getInstance().locate(AppAlias.CHROMIUM)) {
97148
// Chromium policy, e.g. /etc/chromium/policies/managed/qz-tray.json
98-
File location = Paths.get(String.format(pattern, Constants.PROPS_FILE)).toFile();
149+
File location = calculatePolicyFile(scope, appInfo);
99150
log.info("Removing Chromium policy {} {}...", policyName, location);
100151

101152
if(location.exists()) {

0 commit comments

Comments
 (0)