From 1881caa8cfd0230fd7224f6e97be16990616e984 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sat, 24 Jul 2021 16:39:53 +0200
Subject: [PATCH 01/27] firefox policies generator PoC.
---
internal/policies/firefox/generator.go | 90 +++++++++++++++++
internal/policies/firefox/policies.json | 129 ++++++++++++++++++++++++
2 files changed, 219 insertions(+)
create mode 100644 internal/policies/firefox/generator.go
create mode 100644 internal/policies/firefox/policies.json
diff --git a/internal/policies/firefox/generator.go b/internal/policies/firefox/generator.go
new file mode 100644
index 0000000..528f678
--- /dev/null
+++ b/internal/policies/firefox/generator.go
@@ -0,0 +1,90 @@
+package firefox
+
+import (
+ _ "embed"
+ "encoding/json"
+ "net/url"
+)
+
+type Settings struct {
+ Bookmarks []string `json:"bookmarks"`
+ Extensions map[string]string `json:"extensions"`
+ DeveloperTools bool `json:"developer_tools"`
+}
+
+//go:embed policies.json
+var policiesJson string
+
+func Generate(settings Settings) (string, error) {
+ policiesObj := struct {
+ Policies map[string]interface{} `json:"policies"`
+ }{}
+ if err := json.Unmarshal([]byte(policiesJson), &policiesObj); err != nil {
+ return "", err
+ }
+
+ //
+ // Bookmarks
+ //
+
+ // Do not append
+ //Bookmarks := policiesObj.Policies["Bookmarks"].([]interface{})
+ Bookmarks := []interface{}{}
+
+ for _, URL := range settings.Bookmarks {
+ title := URL
+
+ if u, err := url.Parse(URL); err == nil {
+ title = u.Hostname()
+ }
+
+ Bookmarks = append(Bookmarks, map[string]interface{}{
+ "Title": title,
+ "URL": URL,
+ //"Favicon": URL + "/favicon.ico",
+ "Folder": "Pages",
+ "Placement": "toolbar",
+ })
+ }
+
+ if len(settings.Bookmarks) > 0 {
+ policiesObj.Policies["Bookmarks"] = Bookmarks
+ }
+
+ //
+ // Extensions
+ //
+
+ // Do not append
+ //Extensions := policiesObj.Policies["ExtensionSettings"].(map[string]interface{})
+ Extensions := map[string]interface{}{}
+
+ // block all
+ Extensions["*"] = map[string]interface{}{
+ "installation_mode": "blocked",
+ }
+
+ for id, url := range settings.Extensions {
+ Extensions[id] = map[string]interface{}{
+ "install_url": url,
+ "installation_mode": "force_installed",
+ }
+ }
+
+ if len(settings.Extensions) > 0 {
+ policiesObj.Policies["ExtensionSettings"] = Extensions
+ }
+
+ //
+ // DeveloperTools
+ //
+
+ policiesObj.Policies["DisableDeveloperTools"] = settings.DeveloperTools
+
+ data, err := json.MarshalIndent(policiesObj, "", " ")
+ if err != nil {
+ return "", err
+ }
+
+ return string(data), nil
+}
diff --git a/internal/policies/firefox/policies.json b/internal/policies/firefox/policies.json
new file mode 100644
index 0000000..ef4bdc1
--- /dev/null
+++ b/internal/policies/firefox/policies.json
@@ -0,0 +1,129 @@
+{
+ "policies": {
+ "BlockAboutAddons": false,
+ "BlockAboutConfig": true,
+ "BlockAboutProfiles": true,
+ "BlockAboutSupport": true,
+ "Bookmarks": [
+ {
+ "Title": "IPLeak",
+ "URL": "https://ipleak.net/",
+ "Favicon": "https://ipleak.net/favicon.ico",
+ "Folder": "Pages",
+ "Placement": "toolbar"
+ },
+ {
+ "Title": "YouTube",
+ "URL": "https://www.youtube.com/",
+ "Favicon": "https://www.youtube.com/favicon.ico",
+ "Folder": "Pages",
+ "Placement": "toolbar"
+ },
+ {
+ "Title": "Google",
+ "URL": "https://www.google.com/",
+ "Favicon": "https://www.google.com/favicon.ico",
+ "Folder": "Pages",
+ "Placement": "toolbar"
+ }
+ ],
+ "CaptivePortal": false,
+ "DisableAppUpdate": true,
+ "DisableBuiltinPDFViewer": true,
+ "DisableDeveloperTools": false,
+ "DisableFeedbackCommands": true,
+ "DisableFirefoxAccounts": true,
+ "DisableFirefoxScreenshots": true,
+ "DisableFirefoxStudies": true,
+ "DisableForgetButton": true,
+ "DisableMasterPasswordCreation": true,
+ "DisablePocket": true,
+ "DisablePrivateBrowsing": true,
+ "DisableProfileImport": true,
+ "DisableProfileRefresh": true,
+ "DisableSafeMode": true,
+ "DisableSetDesktopBackground": true,
+ "DisableSystemAddonUpdate": true,
+ "DisableTelemetry": true,
+ "DisplayBookmarksToolbar": false,
+ "DontCheckDefaultBrowser": true,
+ "EnableTrackingProtection": {
+ "Cryptomining": true,
+ "Fingerprinting": true,
+ "Value": true
+ },
+ "ExtensionSettings": {
+ "*": {
+ "installation_mode": "blocked"
+ },
+ "nordvpnproxy@nordvpn.com": {
+ "install_url": "https://addons.mozilla.org/firefox/downloads/latest/nordvpn-proxy-extension/latest.xpi",
+ "installation_mode": "force_installed"
+ },
+ "uBlock0@raymondhill.net": {
+ "install_url": "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi",
+ "installation_mode": "force_installed"
+ }
+ },
+ "ExtensionUpdate": false,
+ "FirefoxHome": {
+ "Highlights": false,
+ "Pocket": false,
+ "Search": true,
+ "Snippets": false,
+ "TopSites": true
+ },
+ "FlashPlugin": {},
+ "HardwareAcceleration": false,
+ "Homepage": {
+ "Additional": [],
+ "StartPage": "home"
+ },
+ "NewTabPage": true,
+ "NoDefaultBookmarks": true,
+ "OfferToSaveLogins": false,
+ "OfferToSaveLoginsDefault": false,
+ "OverrideFirstRunPage": "",
+ "OverridePostUpdatePage": "",
+ "PasswordManagerEnabled": false,
+ "Permissions": {
+ "Camera": {
+ "BlockNewRequests": true
+ },
+ "Location": {
+ "BlockNewRequests": true
+ },
+ "Microphone": {
+ "BlockNewRequests": true
+ },
+ "Notifications": {
+ "BlockNewRequests": true
+ }
+ },
+ "Preferences": {
+ "browser.tabs.warnOnClose": false,
+ "browser.urlbar.suggest.bookmark": false,
+ "browser.urlbar.suggest.history": false,
+ "browser.urlbar.suggest.openpage": false,
+ "datareporting.policy.dataSubmissionPolicyBypassNotification": true,
+ "dom.disable_window_flip": true,
+ "dom.disable_window_move_resize": true,
+ "dom.event.contextmenu.enabled": false,
+ "extensions.getAddons.showPane": false,
+ "places.history.enabled": false,
+ "privacy.file_unique_origin": true,
+ "ui.key.menuAccessKeyFocuses": false
+ },
+ "PromptForDownloadLocation": false,
+ "SanitizeOnShutdown": {
+ "Cache": true,
+ "Cookies": true,
+ "Downloads": true,
+ "FormData": true,
+ "History": true,
+ "OfflineApps": true,
+ "Sessions": true,
+ "SiteSettings": true
+ }
+ }
+}
From eb88bfd70ee0015a57738e881ce5c6f74a519ef9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sat, 24 Jul 2021 23:25:29 +0200
Subject: [PATCH 02/27] update policies + chromium.
---
internal/policies/chromium/generator.go | 90 ++++++++++++++++++++++++
internal/policies/chromium/policies.json | 38 ++++++++++
internal/policies/firefox/generator.go | 87 ++++++++++-------------
internal/policies/firefox/policies.json | 11 +--
internal/types/policies.go | 13 ++++
5 files changed, 179 insertions(+), 60 deletions(-)
create mode 100644 internal/policies/chromium/generator.go
create mode 100644 internal/policies/chromium/policies.json
create mode 100644 internal/types/policies.go
diff --git a/internal/policies/chromium/generator.go b/internal/policies/chromium/generator.go
new file mode 100644
index 0000000..2a0f372
--- /dev/null
+++ b/internal/policies/chromium/generator.go
@@ -0,0 +1,90 @@
+package chromium
+
+// https://chromeenterprise.google/policies/
+
+import (
+ _ "embed"
+ "encoding/json"
+ "fmt"
+ "m1k1o/neko_rooms/internal/types"
+)
+
+//go:embed policies.json
+var policiesJson string
+
+func Generate(policies types.Policies) (string, error) {
+ policiesTmpl := map[string]interface{}{}
+ if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
+ return "", err
+ }
+
+ //
+ // Homepage
+ //
+
+ if policies.Homepage != "" {
+ policiesTmpl["HomepageLocation"] = policies.Homepage
+ }
+
+ //
+ // Extensions
+ //
+
+ ExtensionInstallForcelist := []interface{}{}
+ for _, e := range policies.Extensions {
+ URL := e.URL
+ if URL == "" {
+ URL = "https://clients2.google.com/service/update2/crx"
+ }
+
+ ExtensionInstallForcelist = append(
+ ExtensionInstallForcelist,
+ fmt.Sprintf("%s;%s", e.ID, URL),
+ )
+ }
+
+ ExtensionInstallWhitelist := []interface{}{}
+ for _, e := range policies.Extensions {
+ ExtensionInstallWhitelist = append(
+ ExtensionInstallWhitelist,
+ e.ID,
+ )
+ }
+
+ policiesTmpl["ExtensionInstallForcelist"] = ExtensionInstallForcelist
+ policiesTmpl["ExtensionInstallWhitelist"] = ExtensionInstallWhitelist
+ policiesTmpl["ExtensionInstallBlacklist"] = []interface{}{"*"}
+
+ //
+ // Developer Tools
+ //
+
+ if policies.DeveloperTools {
+ // Allow usage of the Developer Tools
+ policiesTmpl["DeveloperToolsAvailability"] = 1
+ } else {
+ // Disallow usage of the Developer Tools
+ policiesTmpl["DeveloperToolsAvailability"] = 2
+ }
+
+ //
+ // Persistent Data
+ //
+
+ if policies.PersistentData {
+ // Allow all sites to set local data
+ policiesTmpl["DefaultCookiesSetting"] = 1
+ // Restore the last session
+ policiesTmpl["RestoreOnStartup"] = 1
+ } else {
+ // Keep cookies for the duration of the session
+ policiesTmpl["DefaultCookiesSetting"] = 4
+ }
+
+ data, err := json.MarshalIndent(policiesTmpl, "", " ")
+ if err != nil {
+ return "", err
+ }
+
+ return string(data), nil
+}
diff --git a/internal/policies/chromium/policies.json b/internal/policies/chromium/policies.json
new file mode 100644
index 0000000..786c2b1
--- /dev/null
+++ b/internal/policies/chromium/policies.json
@@ -0,0 +1,38 @@
+{
+ "HomepageLocation": "",
+ "AutoFillEnabled": false,
+ "AutofillAddressEnabled": false,
+ "AutofillCreditCardEnabled": false,
+ "BrowserSignin": 0,
+ "DefaultNotificationsSetting": 2,
+ "DeveloperToolsAvailability": 2,
+ "EditBookmarksEnabled": false,
+ "FullscreenAllowed": true,
+ "IncognitoModeAvailability": 1,
+ "SyncDisabled": true,
+ "AutoplayAllowed": true,
+ "BrowserAddPersonEnabled": false,
+ "BrowserGuestModeEnabled": false,
+ "DefaultPopupsSetting": 2,
+ "DownloadRestrictions": 3,
+ "VideoCaptureAllowed": true,
+ "AllowFileSelectionDialogs": false,
+ "PromptForDownloadLocation": false,
+ "BookmarkBarEnabled": false,
+ "PasswordManagerEnabled": false,
+ "URLBlacklist": [
+ "file://*",
+ "chrome://policy"
+ ],
+ "ExtensionInstallForcelist": [
+ "cjpalhdlnbpafiamejdnhcphjbkeiagm;https://clients2.google.com/service/update2/crx",
+ "fjoaledfpmneenckfbpdfhkmimnjocfa;https://clients2.google.com/service/update2/crx"
+ ],
+ "ExtensionInstallWhitelist": [
+ "cjpalhdlnbpafiamejdnhcphjbkeiagm",
+ "fjoaledfpmneenckfbpdfhkmimnjocfa"
+ ],
+ "ExtensionInstallBlacklist": [
+ "*"
+ ]
+}
diff --git a/internal/policies/firefox/generator.go b/internal/policies/firefox/generator.go
index 528f678..4f1fac7 100644
--- a/internal/policies/firefox/generator.go
+++ b/internal/policies/firefox/generator.go
@@ -1,87 +1,74 @@
package firefox
+// https://github.com/mozilla/policy-templates/blob/master/README.md#homepage
+
import (
_ "embed"
"encoding/json"
- "net/url"
+ "m1k1o/neko_rooms/internal/types"
)
-type Settings struct {
- Bookmarks []string `json:"bookmarks"`
- Extensions map[string]string `json:"extensions"`
- DeveloperTools bool `json:"developer_tools"`
-}
-
//go:embed policies.json
var policiesJson string
-func Generate(settings Settings) (string, error) {
- policiesObj := struct {
+func Generate(policies types.Policies) (string, error) {
+ policiesTmpl := struct {
Policies map[string]interface{} `json:"policies"`
}{}
- if err := json.Unmarshal([]byte(policiesJson), &policiesObj); err != nil {
+ if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
return "", err
}
//
- // Bookmarks
+ // Homepage
//
- // Do not append
- //Bookmarks := policiesObj.Policies["Bookmarks"].([]interface{})
- Bookmarks := []interface{}{}
-
- for _, URL := range settings.Bookmarks {
- title := URL
-
- if u, err := url.Parse(URL); err == nil {
- title = u.Hostname()
+ if policies.Homepage != "" {
+ policiesTmpl.Policies["Homepage"] = map[string]interface{}{
+ "URL": policies.Homepage,
+ "StartPage": "homepage",
}
-
- Bookmarks = append(Bookmarks, map[string]interface{}{
- "Title": title,
- "URL": URL,
- //"Favicon": URL + "/favicon.ico",
- "Folder": "Pages",
- "Placement": "toolbar",
- })
- }
-
- if len(settings.Bookmarks) > 0 {
- policiesObj.Policies["Bookmarks"] = Bookmarks
}
//
// Extensions
//
- // Do not append
- //Extensions := policiesObj.Policies["ExtensionSettings"].(map[string]interface{})
- Extensions := map[string]interface{}{}
-
- // block all
- Extensions["*"] = map[string]interface{}{
+ ExtensionSettings := map[string]interface{}{}
+ ExtensionSettings["*"] = map[string]interface{}{
"installation_mode": "blocked",
}
- for id, url := range settings.Extensions {
- Extensions[id] = map[string]interface{}{
- "install_url": url,
+ for _, e := range policies.Extensions {
+ ExtensionSettings[e.ID] = map[string]interface{}{
+ "install_url": e.URL,
"installation_mode": "force_installed",
}
}
- if len(settings.Extensions) > 0 {
- policiesObj.Policies["ExtensionSettings"] = Extensions
+ policiesTmpl.Policies["ExtensionSettings"] = ExtensionSettings
+
+ //
+ // Developer Tools
+ //
+
+ policiesTmpl.Policies["DisableDeveloperTools"] = !policies.DeveloperTools
+
+ //
+ // Persistent Data
+ //
+
+ if policies.PersistentData {
+ Preferences := policiesTmpl.Policies["Preferences"].(map[string]interface{})
+ Preferences["browser.urlbar.suggest.history"] = true
+ Preferences["places.history.enabled"] = true
+ policiesTmpl.Policies["Preferences"] = Preferences
+ policiesTmpl.Policies["SanitizeOnShutdown"] = false
+ } else {
+ policiesTmpl.Policies["SanitizeOnShutdown"] = true
}
- //
- // DeveloperTools
- //
-
- policiesObj.Policies["DisableDeveloperTools"] = settings.DeveloperTools
-
- data, err := json.MarshalIndent(policiesObj, "", " ")
+ data, err := json.MarshalIndent(policiesTmpl, "", " ")
if err != nil {
return "", err
}
diff --git a/internal/policies/firefox/policies.json b/internal/policies/firefox/policies.json
index ef4bdc1..0a0132f 100644
--- a/internal/policies/firefox/policies.json
+++ b/internal/policies/firefox/policies.json
@@ -115,15 +115,6 @@
"ui.key.menuAccessKeyFocuses": false
},
"PromptForDownloadLocation": false,
- "SanitizeOnShutdown": {
- "Cache": true,
- "Cookies": true,
- "Downloads": true,
- "FormData": true,
- "History": true,
- "OfflineApps": true,
- "Sessions": true,
- "SiteSettings": true
- }
+ "SanitizeOnShutdown": true
}
}
diff --git a/internal/types/policies.go b/internal/types/policies.go
new file mode 100644
index 0000000..973c989
--- /dev/null
+++ b/internal/types/policies.go
@@ -0,0 +1,13 @@
+package types
+
+type Policies struct {
+ Homepage string `json:"homepage"`
+ Extensions []Extension `json:"extensions"`
+ DeveloperTools bool `json:"developer_tools"`
+ PersistentData bool `json:"persistent_data"`
+}
+
+type Extension struct {
+ ID string `json:"id"`
+ URL string `json:"url"`
+}
From b2a14c791659fa55a5c54301b73d4ffdedc5f75a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sat, 24 Jul 2021 23:47:59 +0200
Subject: [PATCH 03/27] chromium policies parse.
---
internal/policies/chromium/parser.go | 62 ++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
create mode 100644 internal/policies/chromium/parser.go
diff --git a/internal/policies/chromium/parser.go b/internal/policies/chromium/parser.go
new file mode 100644
index 0000000..ec53d46
--- /dev/null
+++ b/internal/policies/chromium/parser.go
@@ -0,0 +1,62 @@
+package chromium
+
+// https://chromeenterprise.google/policies/
+
+import (
+ "encoding/json"
+ "m1k1o/neko_rooms/internal/types"
+ "strings"
+)
+
+func Parse(policiesJson string) (*types.Policies, error) {
+ policies := types.Policies{}
+
+ policiesTmpl := map[string]interface{}{}
+ if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
+ return nil, err
+ }
+
+ //
+ // Homepage
+ //
+
+ if homepage, ok := policiesTmpl["HomepageLocation"]; ok {
+ policies.Homepage = homepage.(string)
+ }
+
+ //
+ // Extensions
+ //
+
+ if extensions, ok := policiesTmpl["ExtensionInstallForcelist"]; ok {
+ policies.Extensions = []types.Extension{}
+ for _, val := range extensions.([]interface{}) {
+ s := strings.Split(val.(string), ";")
+ policies.Extensions = append(
+ policies.Extensions,
+ types.Extension{
+ ID: s[0],
+ URL: s[1],
+ },
+ )
+ }
+ }
+
+ //
+ // Developer Tools
+ //
+
+ if val, ok := policiesTmpl["DeveloperToolsAvailability"]; ok {
+ policies.DeveloperTools = val.(float64) == 1
+ }
+
+ //
+ // Persistent Data
+ //
+
+ if val, ok := policiesTmpl["DefaultCookiesSetting"]; ok {
+ policies.PersistentData = val.(float64) == 1
+ }
+
+ return &policies, nil
+}
From f07f8b0f4dcd282696aa806ffaaa60366c35810c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sat, 24 Jul 2021 23:57:11 +0200
Subject: [PATCH 04/27] firefox policies parse.
---
internal/policies/firefox/parser.go | 77 +++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
create mode 100644 internal/policies/firefox/parser.go
diff --git a/internal/policies/firefox/parser.go b/internal/policies/firefox/parser.go
new file mode 100644
index 0000000..fe30367
--- /dev/null
+++ b/internal/policies/firefox/parser.go
@@ -0,0 +1,77 @@
+package firefox
+
+// https://github.com/mozilla/policy-templates/blob/master/README.md#homepage
+
+import (
+ _ "embed"
+ "encoding/json"
+ "m1k1o/neko_rooms/internal/types"
+)
+
+func Parse(policiesJson string) (*types.Policies, error) {
+ policies := types.Policies{}
+
+ policiesTmpl := struct {
+ Policies map[string]interface{} `json:"policies"`
+ }{}
+ if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
+ return nil, err
+ }
+
+ // empty file
+ if policiesTmpl.Policies == nil {
+ return &policies, nil
+ }
+
+ //
+ // Homepage
+ //
+
+ if homepage, ok := policiesTmpl.Policies["Homepage"].(map[string]interface{}); ok {
+ if url, ok := homepage["URL"]; ok {
+ policies.Homepage = url.(string)
+ }
+ }
+
+ //
+ // Extensions
+ //
+
+ if extensions, ok := policiesTmpl.Policies["ExtensionSettings"]; ok {
+ policies.Extensions = []types.Extension{}
+ for id, val := range extensions.(map[string]interface{}) {
+ if id == "*" {
+ continue
+ }
+
+ data := val.(map[string]interface{})
+ url, _ := data["install_url"].(string)
+
+ policies.Extensions = append(
+ policies.Extensions,
+ types.Extension{
+ ID: id,
+ URL: url,
+ },
+ )
+ }
+ }
+
+ //
+ // Developer Tools
+ //
+
+ if val, ok := policiesTmpl.Policies["DisableDeveloperTools"]; ok {
+ policies.DeveloperTools = !val.(bool)
+ }
+
+ //
+ // Persistent Data
+ //
+
+ if val, ok := policiesTmpl.Policies["SanitizeOnShutdown"]; ok {
+ policies.PersistentData = !val.(bool)
+ }
+
+ return &policies, nil
+}
From 3b363459e1d1cfd584c60a6ff757b5ac37a24436 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 00:00:23 +0200
Subject: [PATCH 05/27] policies generator explicit.
---
internal/policies/chromium/generator.go | 6 +++---
internal/policies/firefox/generator.go | 22 ++++++++--------------
2 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/internal/policies/chromium/generator.go b/internal/policies/chromium/generator.go
index 2a0f372..b06ce83 100644
--- a/internal/policies/chromium/generator.go
+++ b/internal/policies/chromium/generator.go
@@ -22,9 +22,7 @@ func Generate(policies types.Policies) (string, error) {
// Homepage
//
- if policies.Homepage != "" {
- policiesTmpl["HomepageLocation"] = policies.Homepage
- }
+ policiesTmpl["HomepageLocation"] = policies.Homepage
//
// Extensions
@@ -79,6 +77,8 @@ func Generate(policies types.Policies) (string, error) {
} else {
// Keep cookies for the duration of the session
policiesTmpl["DefaultCookiesSetting"] = 4
+ // Open New Tab Page
+ policiesTmpl["RestoreOnStartup"] = 5
}
data, err := json.MarshalIndent(policiesTmpl, "", " ")
diff --git a/internal/policies/firefox/generator.go b/internal/policies/firefox/generator.go
index 4f1fac7..b5d50cb 100644
--- a/internal/policies/firefox/generator.go
+++ b/internal/policies/firefox/generator.go
@@ -23,11 +23,9 @@ func Generate(policies types.Policies) (string, error) {
// Homepage
//
- if policies.Homepage != "" {
- policiesTmpl.Policies["Homepage"] = map[string]interface{}{
- "URL": policies.Homepage,
- "StartPage": "homepage",
- }
+ policiesTmpl.Policies["Homepage"] = map[string]interface{}{
+ "URL": policies.Homepage,
+ "StartPage": "homepage",
}
//
@@ -58,15 +56,11 @@ func Generate(policies types.Policies) (string, error) {
// Persistent Data
//
- if policies.PersistentData {
- Preferences := policiesTmpl.Policies["Preferences"].(map[string]interface{})
- Preferences["browser.urlbar.suggest.history"] = true
- Preferences["places.history.enabled"] = true
- policiesTmpl.Policies["Preferences"] = Preferences
- policiesTmpl.Policies["SanitizeOnShutdown"] = false
- } else {
- policiesTmpl.Policies["SanitizeOnShutdown"] = true
- }
+ Preferences := policiesTmpl.Policies["Preferences"].(map[string]interface{})
+ Preferences["browser.urlbar.suggest.history"] = policies.PersistentData
+ Preferences["places.history.enabled"] = policies.PersistentData
+ policiesTmpl.Policies["Preferences"] = Preferences
+ policiesTmpl.Policies["SanitizeOnShutdown"] = !policies.PersistentData
data, err := json.MarshalIndent(policiesTmpl, "", " ")
if err != nil {
From 99127861460d45908ff832cdc819f8a10539dc38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 00:48:38 +0200
Subject: [PATCH 06/27] add policies config.
---
internal/policies/config.go | 82 +++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 internal/policies/config.go
diff --git a/internal/policies/config.go b/internal/policies/config.go
new file mode 100644
index 0000000..14fcaa4
--- /dev/null
+++ b/internal/policies/config.go
@@ -0,0 +1,82 @@
+package policies
+
+import (
+ "errors"
+ "m1k1o/neko_rooms/internal/policies/chromium"
+ "m1k1o/neko_rooms/internal/policies/firefox"
+ "m1k1o/neko_rooms/internal/types"
+)
+
+type PolicyType string
+
+const (
+ Chromium PolicyType = "chromium"
+ Firefox PolicyType = "friefox"
+)
+
+type PoliciesConfig struct {
+ Type PolicyType
+ Path string
+}
+
+func GetConfig(image string) *PoliciesConfig {
+ switch image {
+ case "m1k1o/neko:latest":
+ fallthrough
+ case "m1k1o/neko:firefox":
+ return &PoliciesConfig{
+ Type: Firefox,
+ Path: "/usr/lib/firefox/distribution/policies.json",
+ }
+ case "m1k1o/neko:arm-firefox":
+ return &PoliciesConfig{
+ Type: Firefox,
+ Path: "/usr/lib/firefox-esr/distribution/policies.json",
+ }
+ case "m1k1o/neko:chromium":
+ fallthrough
+ case "m1k1o/neko:arm-chromium":
+ fallthrough
+ case "m1k1o/neko:ungoogled-chromium":
+ return &PoliciesConfig{
+ Type: Chromium,
+ Path: "/etc/chromium/policies/managed/policies.json",
+ }
+ case "m1k1o/neko:google-chrome":
+ return &PoliciesConfig{
+ Type: Chromium,
+ Path: "/etc/opt/chrome/policies/managed/policies.json",
+ }
+ case "m1k1o/neko:brave":
+ return &PoliciesConfig{
+ Type: Chromium,
+ Path: "/etc/brave/policies/managed/policies.json",
+ }
+ }
+
+ return nil
+}
+
+func Generate(policies types.Policies, policyType PolicyType) (string, error) {
+ if policyType == Chromium {
+ return chromium.Generate(policies)
+ }
+
+ if policyType == Firefox {
+ return firefox.Generate(policies)
+ }
+
+ return "", errors.New("unknown policy type")
+}
+
+func Parse(policiesJson string, policyType PolicyType) (*types.Policies, error) {
+ if policyType == Chromium {
+ return chromium.Parse(policiesJson)
+ }
+
+ if policyType == Firefox {
+ return firefox.Parse(policiesJson)
+ }
+
+ return nil, errors.New("unknown policy type")
+}
From 97445b11e41494ceffcefa936565585742b4f13c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 01:53:14 +0200
Subject: [PATCH 07/27] add policies API.
---
OpenApi.yml | 29 ++++++++++
client/src/api/.openapi-generator/VERSION | 2 +-
client/src/api/api.ts | 56 +++++++++++++++++++
internal/room/manager.go | 66 +++++++++++++++++++++++
internal/types/room.go | 2 +
5 files changed, 154 insertions(+), 1 deletion(-)
diff --git a/OpenApi.yml b/OpenApi.yml
index 9fca958..5ce7ac1 100644
--- a/OpenApi.yml
+++ b/OpenApi.yml
@@ -330,6 +330,8 @@ components:
type: array
items:
$ref: '#/components/schemas/RoomMount'
+ policies:
+ $ref: '#/components/schemas/Policies'
RoomStats:
type: object
@@ -360,3 +362,30 @@ components:
muted:
type: boolean
example: false
+
+ Policies:
+ type: object
+ properties:
+ homepage:
+ type: string
+ example: https://google.com
+ extensions:
+ type: array
+ items:
+ $ref: '#/components/schemas/Extension'
+ developer_tools:
+ type: boolean
+ example: true
+ persistent_data:
+ type: boolean
+ example: false
+
+ Extension:
+ type: object
+ properties:
+ id:
+ type: string
+ example: uBlock0@raymondhill.net
+ url:
+ type: string
+ example: https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi
diff --git a/client/src/api/.openapi-generator/VERSION b/client/src/api/.openapi-generator/VERSION
index 6555596..862529f 100644
--- a/client/src/api/.openapi-generator/VERSION
+++ b/client/src/api/.openapi-generator/VERSION
@@ -1 +1 @@
-5.2.0-SNAPSHOT
\ No newline at end of file
+5.2.1-SNAPSHOT
\ No newline at end of file
diff --git a/client/src/api/api.ts b/client/src/api/api.ts
index bce8ee1..6d87e92 100644
--- a/client/src/api/api.ts
+++ b/client/src/api/api.ts
@@ -21,6 +21,56 @@ import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObj
// @ts-ignore
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base';
+/**
+ *
+ * @export
+ * @interface Extension
+ */
+export interface Extension {
+ /**
+ *
+ * @type {string}
+ * @memberof Extension
+ */
+ id?: string;
+ /**
+ *
+ * @type {string}
+ * @memberof Extension
+ */
+ url?: string;
+}
+/**
+ *
+ * @export
+ * @interface Policies
+ */
+export interface Policies {
+ /**
+ *
+ * @type {string}
+ * @memberof Policies
+ */
+ homepage?: string;
+ /**
+ *
+ * @type {Array}
+ * @memberof Policies
+ */
+ extensions?: Array;
+ /**
+ *
+ * @type {boolean}
+ * @memberof Policies
+ */
+ developer_tools?: boolean;
+ /**
+ *
+ * @type {boolean}
+ * @memberof Policies
+ */
+ persistent_data?: boolean;
+}
/**
*
* @export
@@ -245,6 +295,12 @@ export interface RoomSettings {
* @memberof RoomSettings
*/
mounts?: Array;
+ /**
+ *
+ * @type {Policies}
+ * @memberof RoomSettings
+ */
+ policies?: Policies;
}
/**
*
diff --git a/internal/room/manager.go b/internal/room/manager.go
index e1d8ab7..33b9d85 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -21,6 +21,7 @@ import (
"github.com/rs/zerolog/log"
"m1k1o/neko_rooms/internal/config"
+ "m1k1o/neko_rooms/internal/policies"
"m1k1o/neko_rooms/internal/types"
"m1k1o/neko_rooms/internal/utils"
)
@@ -194,6 +195,47 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
env = append(env, fmt.Sprintf("NEKO_NAT1TO1=%s", strings.Join(manager.config.NAT1To1IPs, ",")))
}
+ // browser policies
+ if settings.Policies != nil {
+ if !manager.config.StorageEnabled {
+ return "", fmt.Errorf("policies cannot be specified, because storage is disabled or unavailable")
+ }
+
+ policyConfig := policies.GetConfig(settings.NekoImage)
+ if policyConfig == nil {
+ return "", fmt.Errorf("policy config for this image does not exist")
+ }
+
+ policyJson, err := policies.Generate(*settings.Policies, policyConfig.Type)
+ if err != nil {
+ return "", err
+ }
+
+ // create policy path (+ also get host path)
+ policyPath := fmt.Sprintf("/%s-%s-policy.json", roomName, policyConfig.Type)
+ templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath)
+ policyInternalPath := path.Join(templateInternalPath, policyPath)
+
+ // create dir if does not exist
+ if _, err := os.Stat(templateInternalPath); os.IsNotExist(err) {
+ if err := os.MkdirAll(templateInternalPath, os.ModePerm); err != nil {
+ return "", err
+ }
+ }
+
+ // write policy to file
+ if err := os.WriteFile(policyInternalPath, []byte(policyJson), 0644); err != nil {
+ return "", err
+ }
+
+ // mount policy file
+ settings.Mounts = append(settings.Mounts, types.RoomMount{
+ Type: types.MountTemplate,
+ HostPath: policyPath,
+ ContainerPath: policyConfig.Path,
+ })
+ }
+
mounts := []dockerMount.Mount{}
for _, mount := range settings.Mounts {
readOnly := false
@@ -396,11 +438,35 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
})
}
+ var policiesData *types.Policies
+ policyConfig := policies.GetConfig(nekoImage)
+ if policyConfig != nil {
+ var policyMount *types.RoomMount
+ for _, mount := range mounts {
+ if mount.ContainerPath == policyConfig.Path {
+ policyMount = &mount
+ break
+ }
+ }
+
+ // TODO: Refactor.
+ if policyMount != nil {
+ if _, err := os.Stat(policyMount.HostPath); !os.IsNotExist(err) {
+ if data, err := os.ReadFile(policyMount.HostPath); err == nil {
+ if pData, err := policies.Parse(string(data), policyConfig.Type); err == nil {
+ policiesData = pData
+ }
+ }
+ }
+ }
+ }
+
settings := types.RoomSettings{
Name: roomName,
NekoImage: nekoImage,
MaxConnections: epr.Max - epr.Min + 1,
Mounts: mounts,
+ Policies: policiesData,
}
err = settings.FromEnv(container.Config.Env)
diff --git a/internal/types/room.go b/internal/types/room.go
index f6808af..f06c323 100644
--- a/internal/types/room.go
+++ b/internal/types/room.go
@@ -75,6 +75,8 @@ type RoomSettings struct {
Envs map[string]string `json:"envs"`
Mounts []RoomMount `json:"mounts"`
+
+ Policies *Policies `json:"policies,omitempty"`
}
func (settings *RoomSettings) ToEnv() []string {
From a37c0ec134e77948ba9601fb9e04a1e47e8b8ad2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 01:55:04 +0200
Subject: [PATCH 08/27] add policies to create and settings.
---
client/src/components/RoomInfo.vue | 13 ++++++
client/src/components/RoomsCreate.vue | 57 ++++++++++++++++++++++++++-
client/src/store/state.ts | 9 +++++
3 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/client/src/components/RoomInfo.vue b/client/src/components/RoomInfo.vue
index 9d582ba..3e78d87 100644
--- a/client/src/components/RoomInfo.vue
+++ b/client/src/components/RoomInfo.vue
@@ -154,6 +154,19 @@
+
+ Policies
+
+
+
+ | Homepage | {{ settings.policies.homepage }} |
+ | Extensions | {{ settings.policies.extensions }} |
+ | Developer tools | {{ settings.policies.developer_tools }} |
+ | Persistent data | {{ settings.policies.persistent_data }} |
+
+
+
+ none
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index f94e18b..be7844d 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -208,7 +208,7 @@
mdi-close
-
+
Mounts
mdi-plus
@@ -252,6 +252,59 @@
+
+
+
+
+
+ Browser policies (experimental)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -305,6 +358,7 @@ export default class RoomsCreate extends Vue {
private videoPipelineEnabled = false
private audioPipelineEnabled = false
private broadcastPipelineEnabled = false
+ private policiesEnabled = false
private loading = false
private data: RoomSettings = { ...this.$store.state.defaultRoomSettings }
@@ -407,6 +461,7 @@ export default class RoomsCreate extends Vue {
// eslint-disable-next-line
broadcast_pipeline: this.broadcastPipelineEnabled ? this.data.broadcast_pipeline : '',
envs,
+ policies: this.policiesEnabled ? this.data.policies : undefined,
})
this.Clear()
this.$emit('finished', true)
diff --git a/client/src/store/state.ts b/client/src/store/state.ts
index d10cd89..c2a1b90 100644
--- a/client/src/store/state.ts
+++ b/client/src/store/state.ts
@@ -42,6 +42,15 @@ export const state = {
envs: {},
// eslint-disable-next-line
mounts: [],
+
+ policies: {
+ homepage: "https://google.com/?hl=en",
+ extensions: [],
+ // eslint-disable-next-line
+ developer_tools: false,
+ // eslint-disable-next-line
+ persistent_data: false,
+ }
} as RoomSettings,
videoCodecs: [
"VP8",
From 77e204f1cd690f3b7477b9d380c378a9303df23e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 02:01:32 +0200
Subject: [PATCH 09/27] update policy read to internal path.
---
internal/room/manager.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/internal/room/manager.go b/internal/room/manager.go
index 33b9d85..855360a 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -450,9 +450,10 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
}
// TODO: Refactor.
- if policyMount != nil {
- if _, err := os.Stat(policyMount.HostPath); !os.IsNotExist(err) {
- if data, err := os.ReadFile(policyMount.HostPath); err == nil {
+ if policyMount != nil && policyMount.Type == types.MountTemplate {
+ templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath, policyMount.HostPath)
+ if _, err := os.Stat(templateInternalPath); !os.IsNotExist(err) {
+ if data, err := os.ReadFile(templateInternalPath); err == nil {
if pData, err := policies.Parse(string(data), policyConfig.Type); err == nil {
policiesData = pData
}
From 36d3f146118ad6c8294733be93a54648f5d85778 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 12:38:09 +0200
Subject: [PATCH 10/27] client: split policies.
---
client/src/components/RoomsCreate.vue | 15 ++++++++++-----
client/src/store/state.ts | 18 +++++++++---------
2 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index be7844d..bba6a94 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -269,14 +269,14 @@
({ key, val, }))
}
diff --git a/client/src/store/state.ts b/client/src/store/state.ts
index c2a1b90..c55786d 100644
--- a/client/src/store/state.ts
+++ b/client/src/store/state.ts
@@ -2,6 +2,7 @@ import {
RoomsConfig,
RoomEntry,
RoomSettings,
+ Policies,
} from '@/api/index'
export const state = {
@@ -42,16 +43,15 @@ export const state = {
envs: {},
// eslint-disable-next-line
mounts: [],
-
- policies: {
- homepage: "https://google.com/?hl=en",
- extensions: [],
- // eslint-disable-next-line
- developer_tools: false,
- // eslint-disable-next-line
- persistent_data: false,
- }
} as RoomSettings,
+ defaultPolicies: {
+ homepage: "https://google.com/?hl=en",
+ extensions: [],
+ // eslint-disable-next-line
+ developer_tools: false,
+ // eslint-disable-next-line
+ persistent_data: false,
+ } as Policies,
videoCodecs: [
"VP8",
"VP9",
From a215f184ddf4eb3ad2e8fa5fe74cea8c04e1636b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 12:38:57 +0200
Subject: [PATCH 11/27] mount profile on persistent data.
---
internal/policies/config.go | 30 ++++++++++++++++++------------
internal/room/manager.go | 9 +++++++++
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/internal/policies/config.go b/internal/policies/config.go
index 14fcaa4..5f17ddd 100644
--- a/internal/policies/config.go
+++ b/internal/policies/config.go
@@ -15,8 +15,9 @@ const (
)
type PoliciesConfig struct {
- Type PolicyType
- Path string
+ Type PolicyType
+ Path string
+ Profile string
}
func GetConfig(image string) *PoliciesConfig {
@@ -25,13 +26,15 @@ func GetConfig(image string) *PoliciesConfig {
fallthrough
case "m1k1o/neko:firefox":
return &PoliciesConfig{
- Type: Firefox,
- Path: "/usr/lib/firefox/distribution/policies.json",
+ Type: Firefox,
+ Path: "/usr/lib/firefox/distribution/policies.json",
+ Profile: "/home/neko/.mozilla/firefox/profile.default",
}
case "m1k1o/neko:arm-firefox":
return &PoliciesConfig{
- Type: Firefox,
- Path: "/usr/lib/firefox-esr/distribution/policies.json",
+ Type: Firefox,
+ Path: "/usr/lib/firefox-esr/distribution/policies.json",
+ Profile: "/home/neko/.mozilla/firefox/profile.default",
}
case "m1k1o/neko:chromium":
fallthrough
@@ -39,18 +42,21 @@ func GetConfig(image string) *PoliciesConfig {
fallthrough
case "m1k1o/neko:ungoogled-chromium":
return &PoliciesConfig{
- Type: Chromium,
- Path: "/etc/chromium/policies/managed/policies.json",
+ Type: Chromium,
+ Path: "/etc/chromium/policies/managed/policies.json",
+ Profile: "/home/neko/.config/chromium",
}
case "m1k1o/neko:google-chrome":
return &PoliciesConfig{
- Type: Chromium,
- Path: "/etc/opt/chrome/policies/managed/policies.json",
+ Type: Chromium,
+ Path: "/etc/opt/chrome/policies/managed/policies.json",
+ Profile: "/home/neko/.config/google-chrome",
}
case "m1k1o/neko:brave":
return &PoliciesConfig{
- Type: Chromium,
- Path: "/etc/brave/policies/managed/policies.json",
+ Type: Chromium,
+ Path: "/etc/brave/policies/managed/policies.json",
+ Profile: "/home/neko/.config/brave",
}
}
diff --git a/internal/room/manager.go b/internal/room/manager.go
index 855360a..b2d22e1 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -234,6 +234,15 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
HostPath: policyPath,
ContainerPath: policyConfig.Path,
})
+
+ // mount persistent folder
+ if settings.Policies.PersistentData && policyConfig.Profile != "" {
+ settings.Mounts = append(settings.Mounts, types.RoomMount{
+ Type: types.MountPrivate,
+ HostPath: "/profile",
+ ContainerPath: policyConfig.Profile,
+ })
+ }
}
mounts := []dockerMount.Mount{}
From bc2a5bef6ce9a347fe764bd2fca4cbbe8ad81529 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 12:39:13 +0200
Subject: [PATCH 12/27] do not mount duplicate mounts.
---
internal/room/manager.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/internal/room/manager.go b/internal/room/manager.go
index b2d22e1..fd19d8e 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -245,8 +245,14 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
}
}
+ paths := map[string]bool{}
mounts := []dockerMount.Mount{}
for _, mount := range settings.Mounts {
+ // ignore duplicates
+ if _, ok := paths[mount.ContainerPath]; ok {
+ continue
+ }
+
readOnly := false
hostPath := filepath.Clean(mount.HostPath)
@@ -309,6 +315,8 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
},
},
)
+
+ paths[mount.ContainerPath] = true
}
config := &container.Config{
From e56594fb4ccb70d2efa6235b87954de26e14097a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 13:29:45 +0200
Subject: [PATCH 13/27] remove homepage from policies.
---
internal/policies/chromium/generator.go | 6 ------
internal/policies/chromium/parser.go | 8 --------
internal/policies/firefox/generator.go | 19 ++++++++++---------
internal/policies/firefox/parser.go | 10 ----------
internal/types/policies.go | 1 -
5 files changed, 10 insertions(+), 34 deletions(-)
diff --git a/internal/policies/chromium/generator.go b/internal/policies/chromium/generator.go
index b06ce83..72d36ef 100644
--- a/internal/policies/chromium/generator.go
+++ b/internal/policies/chromium/generator.go
@@ -18,12 +18,6 @@ func Generate(policies types.Policies) (string, error) {
return "", err
}
- //
- // Homepage
- //
-
- policiesTmpl["HomepageLocation"] = policies.Homepage
-
//
// Extensions
//
diff --git a/internal/policies/chromium/parser.go b/internal/policies/chromium/parser.go
index ec53d46..c873f1e 100644
--- a/internal/policies/chromium/parser.go
+++ b/internal/policies/chromium/parser.go
@@ -16,14 +16,6 @@ func Parse(policiesJson string) (*types.Policies, error) {
return nil, err
}
- //
- // Homepage
- //
-
- if homepage, ok := policiesTmpl["HomepageLocation"]; ok {
- policies.Homepage = homepage.(string)
- }
-
//
// Extensions
//
diff --git a/internal/policies/firefox/generator.go b/internal/policies/firefox/generator.go
index b5d50cb..a956c0f 100644
--- a/internal/policies/firefox/generator.go
+++ b/internal/policies/firefox/generator.go
@@ -19,15 +19,6 @@ func Generate(policies types.Policies) (string, error) {
return "", err
}
- //
- // Homepage
- //
-
- policiesTmpl.Policies["Homepage"] = map[string]interface{}{
- "URL": policies.Homepage,
- "StartPage": "homepage",
- }
-
//
// Extensions
//
@@ -62,6 +53,16 @@ func Generate(policies types.Policies) (string, error) {
policiesTmpl.Policies["Preferences"] = Preferences
policiesTmpl.Policies["SanitizeOnShutdown"] = !policies.PersistentData
+ if policies.PersistentData {
+ policiesTmpl.Policies["Homepage"] = map[string]interface{}{
+ "StartPage": "previous-session",
+ }
+ } else {
+ policiesTmpl.Policies["Homepage"] = map[string]interface{}{
+ "StartPage": "homepage",
+ }
+ }
+
data, err := json.MarshalIndent(policiesTmpl, "", " ")
if err != nil {
return "", err
diff --git a/internal/policies/firefox/parser.go b/internal/policies/firefox/parser.go
index fe30367..9594794 100644
--- a/internal/policies/firefox/parser.go
+++ b/internal/policies/firefox/parser.go
@@ -23,16 +23,6 @@ func Parse(policiesJson string) (*types.Policies, error) {
return &policies, nil
}
- //
- // Homepage
- //
-
- if homepage, ok := policiesTmpl.Policies["Homepage"].(map[string]interface{}); ok {
- if url, ok := homepage["URL"]; ok {
- policies.Homepage = url.(string)
- }
- }
-
//
// Extensions
//
diff --git a/internal/types/policies.go b/internal/types/policies.go
index 973c989..49e602c 100644
--- a/internal/types/policies.go
+++ b/internal/types/policies.go
@@ -1,7 +1,6 @@
package types
type Policies struct {
- Homepage string `json:"homepage"`
Extensions []Extension `json:"extensions"`
DeveloperTools bool `json:"developer_tools"`
PersistentData bool `json:"persistent_data"`
From 4815e2aa6270c67b4f14d7b4fbbc708a2c6feb56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 14:37:39 +0200
Subject: [PATCH 14/27] profile dir name with browser.
---
internal/room/manager.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/internal/room/manager.go b/internal/room/manager.go
index fd19d8e..930c418 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -239,7 +239,7 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
if settings.Policies.PersistentData && policyConfig.Profile != "" {
settings.Mounts = append(settings.Mounts, types.RoomMount{
Type: types.MountPrivate,
- HostPath: "/profile",
+ HostPath: fmt.Sprintf("/%s-profile", policyConfig.Type),
ContainerPath: policyConfig.Profile,
})
}
From 63f1c40cab89008a154387f51c774209ae3a8030 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 25 Jul 2021 14:52:21 +0200
Subject: [PATCH 15/27] policies: remove homepage from API.
---
OpenApi.yml | 3 ---
client/src/api/api.ts | 6 ------
client/src/components/RoomInfo.vue | 1 -
client/src/components/RoomsCreate.vue | 11 ++---------
4 files changed, 2 insertions(+), 19 deletions(-)
diff --git a/OpenApi.yml b/OpenApi.yml
index 5ce7ac1..2d73cb7 100644
--- a/OpenApi.yml
+++ b/OpenApi.yml
@@ -366,9 +366,6 @@ components:
Policies:
type: object
properties:
- homepage:
- type: string
- example: https://google.com
extensions:
type: array
items:
diff --git a/client/src/api/api.ts b/client/src/api/api.ts
index 6d87e92..fc546f6 100644
--- a/client/src/api/api.ts
+++ b/client/src/api/api.ts
@@ -46,12 +46,6 @@ export interface Extension {
* @interface Policies
*/
export interface Policies {
- /**
- *
- * @type {string}
- * @memberof Policies
- */
- homepage?: string;
/**
*
* @type {Array}
diff --git a/client/src/components/RoomInfo.vue b/client/src/components/RoomInfo.vue
index 3e78d87..e6735be 100644
--- a/client/src/components/RoomInfo.vue
+++ b/client/src/components/RoomInfo.vue
@@ -159,7 +159,6 @@
- | Homepage | {{ settings.policies.homepage }} |
| Extensions | {{ settings.policies.extensions }} |
| Developer tools | {{ settings.policies.developer_tools }} |
| Persistent data | {{ settings.policies.persistent_data }} |
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index bba6a94..3f56f03 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -255,7 +255,7 @@
-
+
Browser policies (experimental)
@@ -266,14 +266,7 @@
>
-
-
-
-
+
Date: Sun, 25 Jul 2021 15:41:28 +0200
Subject: [PATCH 16/27] add chromium extensions.
---
client/src/components/RoomsCreate.vue | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index 3f56f03..a647443 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -270,8 +270,21 @@
From 06e3c52e05cf772c90fddfcf0905ac9c2b44607c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 20:17:17 +0200
Subject: [PATCH 17/27] browser policy store type & path in labels.
---
internal/policies/chromium/generator.go | 2 +-
internal/policies/chromium/parser.go | 8 +--
internal/policies/config.go | 68 +++----------------------
internal/policies/firefox/generator.go | 2 +-
internal/policies/firefox/parser.go | 8 +--
internal/room/labels.go | 38 +++++++++++++-
internal/room/manager.go | 53 +++++++++----------
internal/types/policies.go | 23 +++++++--
internal/types/room.go | 2 +-
9 files changed, 99 insertions(+), 105 deletions(-)
diff --git a/internal/policies/chromium/generator.go b/internal/policies/chromium/generator.go
index 72d36ef..b86b948 100644
--- a/internal/policies/chromium/generator.go
+++ b/internal/policies/chromium/generator.go
@@ -12,7 +12,7 @@ import (
//go:embed policies.json
var policiesJson string
-func Generate(policies types.Policies) (string, error) {
+func Generate(policies types.BrowserPolicyContent) (string, error) {
policiesTmpl := map[string]interface{}{}
if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
return "", err
diff --git a/internal/policies/chromium/parser.go b/internal/policies/chromium/parser.go
index c873f1e..2d18f14 100644
--- a/internal/policies/chromium/parser.go
+++ b/internal/policies/chromium/parser.go
@@ -8,8 +8,8 @@ import (
"strings"
)
-func Parse(policiesJson string) (*types.Policies, error) {
- policies := types.Policies{}
+func Parse(policiesJson string) (*types.BrowserPolicyContent, error) {
+ policies := types.BrowserPolicyContent{}
policiesTmpl := map[string]interface{}{}
if err := json.Unmarshal([]byte(policiesJson), &policiesTmpl); err != nil {
@@ -21,12 +21,12 @@ func Parse(policiesJson string) (*types.Policies, error) {
//
if extensions, ok := policiesTmpl["ExtensionInstallForcelist"]; ok {
- policies.Extensions = []types.Extension{}
+ policies.Extensions = []types.BrowserPolicyExtension{}
for _, val := range extensions.([]interface{}) {
s := strings.Split(val.(string), ";")
policies.Extensions = append(
policies.Extensions,
- types.Extension{
+ types.BrowserPolicyExtension{
ID: s[0],
URL: s[1],
},
diff --git a/internal/policies/config.go b/internal/policies/config.go
index 5f17ddd..e00436a 100644
--- a/internal/policies/config.go
+++ b/internal/policies/config.go
@@ -7,80 +7,24 @@ import (
"m1k1o/neko_rooms/internal/types"
)
-type PolicyType string
-
-const (
- Chromium PolicyType = "chromium"
- Firefox PolicyType = "friefox"
-)
-
-type PoliciesConfig struct {
- Type PolicyType
- Path string
- Profile string
-}
-
-func GetConfig(image string) *PoliciesConfig {
- switch image {
- case "m1k1o/neko:latest":
- fallthrough
- case "m1k1o/neko:firefox":
- return &PoliciesConfig{
- Type: Firefox,
- Path: "/usr/lib/firefox/distribution/policies.json",
- Profile: "/home/neko/.mozilla/firefox/profile.default",
- }
- case "m1k1o/neko:arm-firefox":
- return &PoliciesConfig{
- Type: Firefox,
- Path: "/usr/lib/firefox-esr/distribution/policies.json",
- Profile: "/home/neko/.mozilla/firefox/profile.default",
- }
- case "m1k1o/neko:chromium":
- fallthrough
- case "m1k1o/neko:arm-chromium":
- fallthrough
- case "m1k1o/neko:ungoogled-chromium":
- return &PoliciesConfig{
- Type: Chromium,
- Path: "/etc/chromium/policies/managed/policies.json",
- Profile: "/home/neko/.config/chromium",
- }
- case "m1k1o/neko:google-chrome":
- return &PoliciesConfig{
- Type: Chromium,
- Path: "/etc/opt/chrome/policies/managed/policies.json",
- Profile: "/home/neko/.config/google-chrome",
- }
- case "m1k1o/neko:brave":
- return &PoliciesConfig{
- Type: Chromium,
- Path: "/etc/brave/policies/managed/policies.json",
- Profile: "/home/neko/.config/brave",
- }
- }
-
- return nil
-}
-
-func Generate(policies types.Policies, policyType PolicyType) (string, error) {
- if policyType == Chromium {
+func Generate(policies types.BrowserPolicyContent, policyType types.BrowserPolicyType) (string, error) {
+ if policyType == types.ChromiumBrowserPolicy {
return chromium.Generate(policies)
}
- if policyType == Firefox {
+ if policyType == types.FirefoxBrowserPolicy {
return firefox.Generate(policies)
}
return "", errors.New("unknown policy type")
}
-func Parse(policiesJson string, policyType PolicyType) (*types.Policies, error) {
- if policyType == Chromium {
+func Parse(policiesJson string, policyType types.BrowserPolicyType) (*types.BrowserPolicyContent, error) {
+ if policyType == types.ChromiumBrowserPolicy {
return chromium.Parse(policiesJson)
}
- if policyType == Firefox {
+ if policyType == types.FirefoxBrowserPolicy {
return firefox.Parse(policiesJson)
}
diff --git a/internal/policies/firefox/generator.go b/internal/policies/firefox/generator.go
index a956c0f..1946353 100644
--- a/internal/policies/firefox/generator.go
+++ b/internal/policies/firefox/generator.go
@@ -11,7 +11,7 @@ import (
//go:embed policies.json
var policiesJson string
-func Generate(policies types.Policies) (string, error) {
+func Generate(policies types.BrowserPolicyContent) (string, error) {
policiesTmpl := struct {
Policies map[string]interface{} `json:"policies"`
}{}
diff --git a/internal/policies/firefox/parser.go b/internal/policies/firefox/parser.go
index 9594794..8727352 100644
--- a/internal/policies/firefox/parser.go
+++ b/internal/policies/firefox/parser.go
@@ -8,8 +8,8 @@ import (
"m1k1o/neko_rooms/internal/types"
)
-func Parse(policiesJson string) (*types.Policies, error) {
- policies := types.Policies{}
+func Parse(policiesJson string) (*types.BrowserPolicyContent, error) {
+ policies := types.BrowserPolicyContent{}
policiesTmpl := struct {
Policies map[string]interface{} `json:"policies"`
@@ -28,7 +28,7 @@ func Parse(policiesJson string) (*types.Policies, error) {
//
if extensions, ok := policiesTmpl.Policies["ExtensionSettings"]; ok {
- policies.Extensions = []types.Extension{}
+ policies.Extensions = []types.BrowserPolicyExtension{}
for id, val := range extensions.(map[string]interface{}) {
if id == "*" {
continue
@@ -39,7 +39,7 @@ func Parse(policiesJson string) (*types.Policies, error) {
policies.Extensions = append(
policies.Extensions,
- types.Extension{
+ types.BrowserPolicyExtension{
ID: id,
URL: url,
},
diff --git a/internal/room/labels.go b/internal/room/labels.go
index 7065413..c384bc1 100644
--- a/internal/room/labels.go
+++ b/internal/room/labels.go
@@ -3,6 +3,8 @@ package room
import (
"fmt"
"strconv"
+
+ "m1k1o/neko_rooms/internal/types"
)
type RoomLabels struct {
@@ -10,6 +12,13 @@ type RoomLabels struct {
URL string
Epr EprPorts
NekoImage string
+
+ BrowserPolicy *BrowserPolicyLabels
+}
+
+type BrowserPolicyLabels struct {
+ Type types.BrowserPolicyType
+ Path string
}
func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLabels, error) {
@@ -48,6 +57,24 @@ func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLab
return nil, err
}
+ var browserPolicy *BrowserPolicyLabels
+ if val, ok := labels["m1k1o.neko_rooms.browser_policy"]; ok && val == "true" {
+ policyType, ok := labels["m1k1o.neko_rooms.browser_policy.type"]
+ if !ok {
+ return nil, fmt.Errorf("damaged container labels: browser_policy.type not found")
+ }
+
+ policyPath, ok := labels["m1k1o.neko_rooms.browser_policy.path"]
+ if !ok {
+ return nil, fmt.Errorf("damaged container labels: browser_policy.path not found")
+ }
+
+ browserPolicy = &BrowserPolicyLabels{
+ Type: types.BrowserPolicyType(policyType),
+ Path: policyPath,
+ }
+ }
+
return &RoomLabels{
Name: name,
URL: url,
@@ -56,11 +83,12 @@ func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLab
Min: uint16(eprMin),
Max: uint16(eprMax),
},
+ BrowserPolicy: browserPolicy,
}, nil
}
func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]string {
- return map[string]string{
+ labelsMap := map[string]string{
"m1k1o.neko_rooms.name": labels.Name,
"m1k1o.neko_rooms.url": labels.URL,
"m1k1o.neko_rooms.instance": manager.config.InstanceName,
@@ -68,4 +96,12 @@ func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]str
"m1k1o.neko_rooms.epr.max": fmt.Sprintf("%d", labels.Epr.Max),
"m1k1o.neko_rooms.neko_image": labels.NekoImage,
}
+
+ if labels.BrowserPolicy != nil {
+ labelsMap["m1k1o.neko_rooms.browser_policy"] = "true"
+ labelsMap["m1k1o.neko_rooms.browser_policy.type"] = string(labels.BrowserPolicy.Type)
+ labelsMap["m1k1o.neko_rooms.browser_policy.path"] = labels.BrowserPolicy.Path
+ }
+
+ return labelsMap
}
diff --git a/internal/room/manager.go b/internal/room/manager.go
index c013a0f..c853776 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -187,11 +187,21 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
instanceUrl = instanceUrl + "/"
}
+ var browserPolicyLabels *BrowserPolicyLabels
+ if settings.BrowserPolicy != nil {
+ browserPolicyLabels = &BrowserPolicyLabels{
+ Type: settings.BrowserPolicy.Type,
+ Path: settings.BrowserPolicy.Path,
+ }
+ }
+
labels := manager.serializeLabels(RoomLabels{
Name: roomName,
URL: instanceUrl + roomName + "/",
Epr: epr,
NekoImage: settings.NekoImage,
+
+ BrowserPolicy: browserPolicyLabels,
})
for k, v := range traefikLabels {
@@ -213,24 +223,22 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
env = append(env, fmt.Sprintf("NEKO_NAT1TO1=%s", strings.Join(manager.config.NAT1To1IPs, ",")))
}
- // browser policies
- if settings.Policies != nil {
+ //
+ // Set browser policies
+ //
+
+ if settings.BrowserPolicy != nil {
if !manager.config.StorageEnabled {
return "", fmt.Errorf("policies cannot be specified, because storage is disabled or unavailable")
}
- policyConfig := policies.GetConfig(settings.NekoImage)
- if policyConfig == nil {
- return "", fmt.Errorf("policy config for this image does not exist")
- }
-
- policyJson, err := policies.Generate(*settings.Policies, policyConfig.Type)
+ policyJson, err := policies.Generate(settings.BrowserPolicy.Content, settings.BrowserPolicy.Type)
if err != nil {
return "", err
}
// create policy path (+ also get host path)
- policyPath := fmt.Sprintf("/%s-%s-policy.json", roomName, policyConfig.Type)
+ policyPath := fmt.Sprintf("/%s-%s-policy.json", roomName, settings.BrowserPolicy.Type)
templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath)
policyInternalPath := path.Join(templateInternalPath, policyPath)
@@ -250,17 +258,8 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
settings.Mounts = append(settings.Mounts, types.RoomMount{
Type: types.MountTemplate,
HostPath: policyPath,
- ContainerPath: policyConfig.Path,
+ ContainerPath: settings.BrowserPolicy.Path,
})
-
- // mount persistent folder
- if settings.Policies.PersistentData && policyConfig.Profile != "" {
- settings.Mounts = append(settings.Mounts, types.RoomMount{
- Type: types.MountPrivate,
- HostPath: fmt.Sprintf("/%s-profile", policyConfig.Type),
- ContainerPath: policyConfig.Profile,
- })
- }
}
//
@@ -471,12 +470,14 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
})
}
- var policiesData *types.Policies
- policyConfig := policies.GetConfig(labels.NekoImage)
- if policyConfig != nil {
+ var browserPolicy *types.BrowserPolicy
+ if labels.BrowserPolicy != nil {
+ browserPolicy.Type = labels.BrowserPolicy.Type
+ browserPolicy.Path = labels.BrowserPolicy.Path
+
var policyMount *types.RoomMount
for _, mount := range mounts {
- if mount.ContainerPath == policyConfig.Path {
+ if mount.ContainerPath == labels.BrowserPolicy.Path {
policyMount = &mount
break
}
@@ -487,8 +488,8 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
templateInternalPath := path.Join(manager.config.StorageInternal, templateStoragePath, policyMount.HostPath)
if _, err := os.Stat(templateInternalPath); !os.IsNotExist(err) {
if data, err := os.ReadFile(templateInternalPath); err == nil {
- if pData, err := policies.Parse(string(data), policyConfig.Type); err == nil {
- policiesData = pData
+ if content, err := policies.Parse(string(data), labels.BrowserPolicy.Type); err == nil {
+ browserPolicy.Content = *content
}
}
}
@@ -500,7 +501,7 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
NekoImage: labels.NekoImage,
MaxConnections: labels.Epr.Max - labels.Epr.Min + 1,
Mounts: mounts,
- Policies: policiesData,
+ BrowserPolicy: browserPolicy,
}
err = settings.FromEnv(container.Config.Env)
diff --git a/internal/types/policies.go b/internal/types/policies.go
index 49e602c..86f7f88 100644
--- a/internal/types/policies.go
+++ b/internal/types/policies.go
@@ -1,12 +1,25 @@
package types
-type Policies struct {
- Extensions []Extension `json:"extensions"`
- DeveloperTools bool `json:"developer_tools"`
- PersistentData bool `json:"persistent_data"`
+type BrowserPolicyType string
+
+const (
+ ChromiumBrowserPolicy BrowserPolicyType = "chromium"
+ FirefoxBrowserPolicy BrowserPolicyType = "friefox"
+)
+
+type BrowserPolicy struct {
+ Type BrowserPolicyType `json:"type"`
+ Path string `json:"path"`
+ Content BrowserPolicyContent `json:"content"`
}
-type Extension struct {
+type BrowserPolicyContent struct {
+ Extensions []BrowserPolicyExtension `json:"extensions"`
+ DeveloperTools bool `json:"developer_tools"`
+ PersistentData bool `json:"persistent_data"`
+}
+
+type BrowserPolicyExtension struct {
ID string `json:"id"`
URL string `json:"url"`
}
diff --git a/internal/types/room.go b/internal/types/room.go
index f06c323..38f29ce 100644
--- a/internal/types/room.go
+++ b/internal/types/room.go
@@ -76,7 +76,7 @@ type RoomSettings struct {
Envs map[string]string `json:"envs"`
Mounts []RoomMount `json:"mounts"`
- Policies *Policies `json:"policies,omitempty"`
+ BrowserPolicy *BrowserPolicy `json:"browser_policy,omitempty"`
}
func (settings *RoomSettings) ToEnv() []string {
From 5f02c51b3d85e00b312b10c38aa3d09edfdf035a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 20:20:59 +0200
Subject: [PATCH 18/27] update API.
---
OpenApi.yml | 22 +++++++++++----
client/src/api/api.ts | 65 +++++++++++++++++++++++++++++++++----------
2 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/OpenApi.yml b/OpenApi.yml
index 2d73cb7..e51f31f 100644
--- a/OpenApi.yml
+++ b/OpenApi.yml
@@ -330,8 +330,8 @@ components:
type: array
items:
$ref: '#/components/schemas/RoomMount'
- policies:
- $ref: '#/components/schemas/Policies'
+ browser_policy:
+ $ref: '#/components/schemas/BrowserPolicy'
RoomStats:
type: object
@@ -363,13 +363,25 @@ components:
type: boolean
example: false
- Policies:
+ BrowserPolicy:
+ type: object
+ properties:
+ type:
+ type: string
+ enum: [ firefox, chromium ]
+ path:
+ type: string
+ example: /home/neko/.mozilla/firefox/profile.default
+ content:
+ $ref: '#/components/schemas/BrowserPolicyContent'
+
+ BrowserPolicyContent:
type: object
properties:
extensions:
type: array
items:
- $ref: '#/components/schemas/Extension'
+ $ref: '#/components/schemas/BrowserPolicyExtension'
developer_tools:
type: boolean
example: true
@@ -377,7 +389,7 @@ components:
type: boolean
example: false
- Extension:
+ BrowserPolicyExtension:
type: object
properties:
id:
diff --git a/client/src/api/api.ts b/client/src/api/api.ts
index fc546f6..4c55f24 100644
--- a/client/src/api/api.ts
+++ b/client/src/api/api.ts
@@ -24,47 +24,82 @@ import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } fr
/**
*
* @export
- * @interface Extension
+ * @interface BrowserPolicy
*/
-export interface Extension {
+export interface BrowserPolicy {
/**
*
* @type {string}
- * @memberof Extension
+ * @memberof BrowserPolicy
*/
- id?: string;
+ type?: BrowserPolicyTypeEnum;
/**
*
* @type {string}
- * @memberof Extension
+ * @memberof BrowserPolicy
*/
- url?: string;
+ path?: string;
+ /**
+ *
+ * @type {BrowserPolicyContent}
+ * @memberof BrowserPolicy
+ */
+ content?: BrowserPolicyContent;
}
+
+/**
+ * @export
+ * @enum {string}
+ */
+export enum BrowserPolicyTypeEnum {
+ firefox = 'firefox',
+ chromium = 'chromium'
+}
+
/**
*
* @export
- * @interface Policies
+ * @interface BrowserPolicyContent
*/
-export interface Policies {
+export interface BrowserPolicyContent {
/**
*
- * @type {Array}
- * @memberof Policies
+ * @type {Array}
+ * @memberof BrowserPolicyContent
*/
- extensions?: Array;
+ extensions?: Array;
/**
*
* @type {boolean}
- * @memberof Policies
+ * @memberof BrowserPolicyContent
*/
developer_tools?: boolean;
/**
*
* @type {boolean}
- * @memberof Policies
+ * @memberof BrowserPolicyContent
*/
persistent_data?: boolean;
}
+/**
+ *
+ * @export
+ * @interface BrowserPolicyExtension
+ */
+export interface BrowserPolicyExtension {
+ /**
+ *
+ * @type {string}
+ * @memberof BrowserPolicyExtension
+ */
+ id?: string;
+ /**
+ *
+ * @type {string}
+ * @memberof BrowserPolicyExtension
+ */
+ url?: string;
+}
/**
*
* @export
@@ -291,10 +326,10 @@ export interface RoomSettings {
mounts?: Array;
/**
*
- * @type {Policies}
+ * @type {BrowserPolicy}
* @memberof RoomSettings
*/
- policies?: Policies;
+ browser_policy?: BrowserPolicy;
}
/**
*
From 28a5c4e164faae94c437626d8d706d5d35027798 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 20:26:30 +0200
Subject: [PATCH 19/27] client settings show browser policy.
---
client/src/components/RoomInfo.vue | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/client/src/components/RoomInfo.vue b/client/src/components/RoomInfo.vue
index e6735be..0bdd56e 100644
--- a/client/src/components/RoomInfo.vue
+++ b/client/src/components/RoomInfo.vue
@@ -155,13 +155,23 @@
- Policies
-
+ Browser policy
+
- | Extensions | {{ settings.policies.extensions }} |
- | Developer tools | {{ settings.policies.developer_tools }} |
- | Persistent data | {{ settings.policies.persistent_data }} |
+ | Type | {{ settings.browser_policy.type }} |
+ | Path | {{ settings.browser_policy.path }} |
+ | Content |
+
+
+
+ | Extensions | {{ settings.browser_policy.content.extensions }} |
+ | Developer tools | {{ settings.browser_policy.content.developer_tools }} |
+ | Persistent data | {{ settings.browser_policy.content.persistent_data }} |
+
+
+
+ |
From fe29e2c221222d821dd4c1401c6e438597a62df1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 20:40:36 +0200
Subject: [PATCH 20/27] fix typos.
---
OpenApi.yml | 2 +-
internal/types/policies.go | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/OpenApi.yml b/OpenApi.yml
index e51f31f..0c0151e 100644
--- a/OpenApi.yml
+++ b/OpenApi.yml
@@ -371,7 +371,7 @@ components:
enum: [ firefox, chromium ]
path:
type: string
- example: /home/neko/.mozilla/firefox/profile.default
+ example: /usr/lib/firefox/distribution/policies.json
content:
$ref: '#/components/schemas/BrowserPolicyContent'
diff --git a/internal/types/policies.go b/internal/types/policies.go
index 86f7f88..b39aa0e 100644
--- a/internal/types/policies.go
+++ b/internal/types/policies.go
@@ -4,7 +4,7 @@ type BrowserPolicyType string
const (
ChromiumBrowserPolicy BrowserPolicyType = "chromium"
- FirefoxBrowserPolicy BrowserPolicyType = "friefox"
+ FirefoxBrowserPolicy BrowserPolicyType = "firefox"
)
type BrowserPolicy struct {
From 767566d40d017d39f8d4cbf0ddcec5a7cbff4d31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 21:14:49 +0200
Subject: [PATCH 21/27] policies create from state.
---
client/src/components/RoomsCreate.vue | 131 +++++++++++++++-----------
client/src/store/state.ts | 113 ++++++++++++++++++++--
2 files changed, 182 insertions(+), 62 deletions(-)
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index a647443..fff9ae6 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -257,60 +257,58 @@
- Browser policies (experimental)
+ Browser policy
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ Not available!
+ Browser policy is not available for this image.
+
@@ -339,7 +337,9 @@ import { Vue, Component, Ref } from 'vue-property-decorator'
import {
RoomSettings,
- Policies,
+ BrowserPolicyContent,
+ BrowserPolicyExtension,
+ BrowserPolicyTypeEnum,
} from '@/api/index'
export type VForm = Vue & {
@@ -365,11 +365,11 @@ export default class RoomsCreate extends Vue {
private videoPipelineEnabled = false
private audioPipelineEnabled = false
private broadcastPipelineEnabled = false
- private policiesEnabled = false
+ private browserPolicyEnabled = false
private loading = false
private data: RoomSettings = { ...this.$store.state.defaultRoomSettings }
- private policies: Policies = { ...this.$store.state.defaultPolicies }
+ private browserPolicyContent: BrowserPolicyContent = { ...this.$store.state.defaultBrowserPolicyContent }
private envList: { key: string; val: string }[] = []
// eslint-disable-next-line
@@ -431,6 +431,28 @@ export default class RoomsCreate extends Vue {
]
}
+ get browserPolicyConfig() {
+ const nekoImage = this.data.neko_image
+ if (!nekoImage) return undefined
+
+ return this.$store.state.browserPolicyConfig.find(({ images }: { images: string[] }): boolean => images.includes(nekoImage))
+ }
+
+ get browserPolicyExtensions() {
+ const config = this.browserPolicyConfig
+ if (!config) return []
+
+ return this.$store.state.browserPolicyExtensions.map(({ text, value }: {
+ text: string;
+ value: Record;
+ }) => {
+ return {
+ text,
+ value: value[config.type as BrowserPolicyTypeEnum],
+ }
+ })
+ }
+
addEnv() {
Vue.set(this, 'envList', [ ...this.envList, { key: '', val: '' } ])
}
@@ -469,7 +491,12 @@ export default class RoomsCreate extends Vue {
// eslint-disable-next-line
broadcast_pipeline: this.broadcastPipelineEnabled ? this.data.broadcast_pipeline : '',
envs,
- policies: this.policiesEnabled ? this.policies : undefined,
+ // eslint-disable-next-line
+ browser_policy: this.browserPolicyEnabled && this.browserPolicyConfig ? {
+ type: this.browserPolicyConfig.type,
+ path: this.browserPolicyConfig.path,
+ content: this.browserPolicyContent
+ } : undefined,
})
this.Clear()
this.$emit('finished', true)
@@ -499,9 +526,7 @@ export default class RoomsCreate extends Vue {
// eslint-disable-next-line
neko_image: this.nekoImages[0],
}
- this.policies = {
- ...this.$store.state.defaultPolicies,
- }
+ this.browserPolicyContent = { ...this.$store.state.defaultBrowserPolicyContent }
this.envList = Object.entries({...this.data.envs}).map(([ key, val ]) => ({ key, val, }))
}
diff --git a/client/src/store/state.ts b/client/src/store/state.ts
index c55786d..8094975 100644
--- a/client/src/store/state.ts
+++ b/client/src/store/state.ts
@@ -2,10 +2,30 @@ import {
RoomsConfig,
RoomEntry,
RoomSettings,
- Policies,
+ BrowserPolicyContent,
+ BrowserPolicyTypeEnum,
+ BrowserPolicyExtension,
} from '@/api/index'
+export interface BrowserPolicyConfig {
+ type: BrowserPolicyTypeEnum;
+ path: string;
+ profile: string;
+ images: string[];
+}
+
+export interface BrowserPolicyExtensions {
+ type: BrowserPolicyTypeEnum;
+ path: string;
+ profile: string;
+ images: string[];
+}
+
export const state = {
+ //
+ // rooms
+ //
+
roomsConfig: {} as RoomsConfig,
rooms: [] as RoomEntry[],
defaultRoomSettings: {
@@ -44,14 +64,6 @@ export const state = {
// eslint-disable-next-line
mounts: [],
} as RoomSettings,
- defaultPolicies: {
- homepage: "https://google.com/?hl=en",
- extensions: [],
- // eslint-disable-next-line
- developer_tools: false,
- // eslint-disable-next-line
- persistent_data: false,
- } as Policies,
videoCodecs: [
"VP8",
"VP9",
@@ -104,6 +116,89 @@ export const state = {
"640x400@60",
"640x360@60"
] as string[],
+
+ //
+ // browser policy
+ //
+
+ browserPolicyConfig: [
+ {
+ type: BrowserPolicyTypeEnum.firefox,
+ path: '/usr/lib/firefox/distribution/policies.json',
+ profile: '/home/neko/.mozilla/firefox/profile.default',
+ images: [ 'm1k1o/neko:latest', 'm1k1o/neko:firefox' ],
+ },
+ {
+ type: BrowserPolicyTypeEnum.firefox,
+ path: '/usr/lib/firefox-esr/distribution/policies.json',
+ profile: '/home/neko/.mozilla/firefox/profile.default',
+ images: [ 'm1k1o/neko:arm-firefox' ],
+ },
+ {
+ type: BrowserPolicyTypeEnum.chromium,
+ path: '/etc/chromium/policies/managed/policies.json',
+ profile: '/home/neko/.config/chromium',
+ images: [ 'm1k1o/neko:chromium', 'm1k1o/neko:arm-chromium', 'm1k1o/neko:ungoogled-chromium' ],
+ },
+ {
+ type: BrowserPolicyTypeEnum.chromium,
+ path: '/etc/opt/chrome/policies/managed/policies.json',
+ profile: '/home/neko/.config/google-chrome',
+ images: [ 'm1k1o/neko:google-chrome' ],
+ },
+ {
+ type: BrowserPolicyTypeEnum.chromium,
+ path: '/etc/brave/policies/managed/policies.json',
+ profile: '/home/neko/.config/brave',
+ images: [ 'm1k1o/neko:brave' ],
+ },
+ ] as BrowserPolicyConfig[],
+ browserPolicyExtensions: [
+ {
+ text: 'uBlock Origin',
+ value: {
+ [BrowserPolicyTypeEnum.firefox]: {
+ id: 'uBlock0@raymondhill.net',
+ url: 'https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi',
+ } as BrowserPolicyExtension,
+ [BrowserPolicyTypeEnum.chromium]: {
+ id: 'cjpalhdlnbpafiamejdnhcphjbkeiagm',
+ } as BrowserPolicyExtension,
+ },
+ },
+ {
+ text: 'NordVPN',
+ value: {
+ [BrowserPolicyTypeEnum.firefox]: {
+ id: 'nordvpnproxy@nordvpn.com',
+ url: 'https://addons.mozilla.org/firefox/downloads/latest/nordvpn-proxy-extension/latest.xpi',
+ } as BrowserPolicyExtension,
+ [BrowserPolicyTypeEnum.chromium]: {
+ id: 'fjoaledfpmneenckfbpdfhkmimnjocfa',
+ } as BrowserPolicyExtension,
+ },
+ },
+ {
+ text: 'SponsorBlock for YouTube',
+ value: {
+ [BrowserPolicyTypeEnum.firefox]: {
+ id: 'sponsorBlocker@ajay.app',
+ url: 'https://addons.mozilla.org/firefox/downloads/latest/sponsorblock/latest.xpi',
+ } as BrowserPolicyExtension,
+ [BrowserPolicyTypeEnum.chromium]: {
+ id: 'mnjggcdmjocbbbhaepdhchncahnbgone',
+ } as BrowserPolicyExtension,
+ },
+ },
+ ],
+ defaultBrowserPolicyContent: {
+ homepage: "https://google.com/?hl=en",
+ extensions: [],
+ // eslint-disable-next-line
+ developer_tools: false,
+ // eslint-disable-next-line
+ persistent_data: false,
+ } as BrowserPolicyContent,
}
export type State = typeof state
From 6b8e77d20aeec6f81490935938da0f147565eba4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 21:17:03 +0200
Subject: [PATCH 22/27] fix memory error.
---
internal/room/manager.go | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/internal/room/manager.go b/internal/room/manager.go
index c853776..f7a041d 100644
--- a/internal/room/manager.go
+++ b/internal/room/manager.go
@@ -472,8 +472,10 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
var browserPolicy *types.BrowserPolicy
if labels.BrowserPolicy != nil {
- browserPolicy.Type = labels.BrowserPolicy.Type
- browserPolicy.Path = labels.BrowserPolicy.Path
+ browserPolicy = &types.BrowserPolicy{
+ Type: labels.BrowserPolicy.Type,
+ Path: labels.BrowserPolicy.Path,
+ }
var policyMount *types.RoomMount
for _, mount := range mounts {
From 0a44aceda0572bd6f6e3984bd63154a05f42c766 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Tue, 27 Jul 2021 21:31:54 +0200
Subject: [PATCH 23/27] extensions for settings show.
---
client/src/components/RoomInfo.vue | 32 ++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/client/src/components/RoomInfo.vue b/client/src/components/RoomInfo.vue
index 0bdd56e..4d59c0a 100644
--- a/client/src/components/RoomInfo.vue
+++ b/client/src/components/RoomInfo.vue
@@ -165,7 +165,7 @@
- | Extensions | {{ settings.browser_policy.content.extensions }} |
+ | Extensions | {{ BrowserExtensions(settings.browser_policy.content.extensions).join(', ') }} |
| Developer tools | {{ settings.browser_policy.content.developer_tools }} |
| Persistent data | {{ settings.browser_policy.content.persistent_data }} |
@@ -182,7 +182,13 @@
From e7815511032f0af5a7bc6705721b553df4b1c0a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?=
Date: Sun, 15 Aug 2021 14:12:26 +0200
Subject: [PATCH 24/27] mount path on persistent data.
---
client/src/components/RoomsCreate.vue | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/client/src/components/RoomsCreate.vue b/client/src/components/RoomsCreate.vue
index fff9ae6..0733f24 100644
--- a/client/src/components/RoomsCreate.vue
+++ b/client/src/components/RoomsCreate.vue
@@ -333,13 +333,14 @@