diff --git a/cmd/config.go b/cmd/config.go index 8b69e7b7..4cdd3ee2 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -140,6 +140,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address) fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert) fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey) + fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec) fmt.Fprintln(w, "\nDefaults:") fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope) fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale) diff --git a/cmd/root.go b/cmd/root.go index b096a7c0..8fe0393a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -64,6 +64,7 @@ func addServerFlags(flags *pflag.FlagSet) { flags.Int("img-processors", 4, "image processors count") flags.Bool("disable-thumbnails", false, "disable image thumbnails") flags.Bool("disable-preview-resize", false, "disable resize of image previews") + flags.Bool("disable-exec", false, "disables Command Runner feature") } var rootCmd = &cobra.Command{ @@ -241,6 +242,9 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server { _, disablePreviewResize := getParamB(flags, "disable-preview-resize") server.ResizePreview = !disablePreviewResize + _, disableExec := getParamB(flags, "disable-exec") + server.EnableExec = !disableExec + return server } diff --git a/frontend/public/index.html b/frontend/public/index.html index 7625aae3..6dd9d32a 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -13,7 +13,7 @@ - + @@ -31,7 +31,7 @@ diff --git a/frontend/src/components/settings/UserForm.vue b/frontend/src/components/settings/UserForm.vue index 35a872f8..8082d5e1 100644 --- a/frontend/src/components/settings/UserForm.vue +++ b/frontend/src/components/settings/UserForm.vue @@ -25,7 +25,7 @@

- +

{{ $t('settings.rules') }}

@@ -40,6 +40,7 @@ import Languages from './Languages' import Rules from './Rules' import Permissions from './Permissions' import Commands from './Commands' +import { enableExec } from '@/utils/constants' export default { name: 'user', @@ -53,7 +54,8 @@ export default { computed: { passwordPlaceholder () { return this.isNew ? '' : this.$t('settings.avoidChanges') - } + }, + isExecEnabled: () => enableExec }, watch: { 'user.perm.admin': function () { diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index e4689dae..d4a8fd79 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -13,6 +13,7 @@ const loginPage = window.FileBrowser.LoginPage const theme = window.FileBrowser.Theme const enableThumbs = window.FileBrowser.EnableThumbs const resizePreview = window.FileBrowser.ResizePreview +const enableExec = window.FileBrowser.EnableExec export { name, @@ -28,5 +29,6 @@ export { loginPage, theme, enableThumbs, - resizePreview + resizePreview, + enableExec } diff --git a/frontend/src/views/Layout.vue b/frontend/src/views/Layout.vue index c5e6c2ef..85991d48 100644 --- a/frontend/src/views/Layout.vue +++ b/frontend/src/views/Layout.vue @@ -7,7 +7,7 @@
- +
@@ -19,6 +19,7 @@ import Sidebar from '@/components/Sidebar' import Prompts from '@/components/prompts/Prompts' import SiteHeader from '@/components/Header' import Shell from '@/components/Shell' +import { enableExec } from '@/utils/constants' export default { name: 'layout', @@ -30,7 +31,8 @@ export default { }, computed: { ...mapGetters([ 'isLogged', 'progress' ]), - ...mapState([ 'user' ]) + ...mapState([ 'user' ]), + isExecEnabled: () => enableExec }, watch: { '$route': function () { diff --git a/frontend/src/views/settings/Global.vue b/frontend/src/views/settings/Global.vue index a0fbfa8a..fd72ae5d 100644 --- a/frontend/src/views/settings/Global.vue +++ b/frontend/src/views/settings/Global.vue @@ -14,9 +14,11 @@

{{ $t('settings.globalRules') }}

-

{{ $t('settings.executeOnShell') }}

-

{{ $t('settings.executeOnShellDescription') }}

- +
+

{{ $t('settings.executeOnShell') }}

+

{{ $t('settings.executeOnShellDescription') }}

+ +

{{ $t('settings.branding') }}

@@ -67,7 +69,7 @@ -
+

{{ $t('settings.commandRunner') }}

@@ -104,6 +106,7 @@ import { settings as api } from '@/api' import UserForm from '@/components/settings/UserForm' import Rules from '@/components/settings/Rules' import Themes from '@/components/settings/Themes' +import { enableExec } from '@/utils/constants' export default { name: 'settings', @@ -119,7 +122,8 @@ export default { } }, computed: { - ...mapState([ 'user' ]) + ...mapState([ 'user' ]), + isExecEnabled: () => enableExec }, async created () { try { diff --git a/http/commands.go b/http/commands.go index cdb5ea1e..6c37adc2 100644 --- a/http/commands.go +++ b/http/commands.go @@ -59,7 +59,7 @@ var commandsHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *d } } - if !d.user.CanExecute(strings.Split(raw, " ")[0]) { + if !d.server.EnableExec || !d.user.CanExecute(strings.Split(raw, " ")[0]) { if err := conn.WriteMessage(websocket.TextMessage, cmdNotAllowed); err != nil { //nolint:shadow wsErr(conn, r, http.StatusInternalServerError, err) } diff --git a/http/data.go b/http/data.go index 8fdff7be..2106d4c5 100644 --- a/http/data.go +++ b/http/data.go @@ -51,7 +51,7 @@ func handle(fn handleFunc, prefix string, store *storage.Storage, server *settin } status, err := fn(w, r, &data{ - Runner: &runner.Runner{Settings: settings}, + Runner: &runner.Runner{Enabled: server.EnableExec, Settings: settings}, store: store, settings: settings, server: server, diff --git a/http/static.go b/http/static.go index 32ed3fa1..ab203b8c 100644 --- a/http/static.go +++ b/http/static.go @@ -41,6 +41,7 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, box * "Theme": d.settings.Branding.Theme, "EnableThumbs": d.server.EnableThumbnails, "ResizePreview": d.server.ResizePreview, + "EnableExec": d.server.EnableExec, } if d.settings.Branding.Files != "" { diff --git a/runner/runner.go b/runner/runner.go index b281ec28..9d8cc70c 100644 --- a/runner/runner.go +++ b/runner/runner.go @@ -13,6 +13,7 @@ import ( // Runner is a commands runner. type Runner struct { + Enabled bool *settings.Settings } @@ -21,11 +22,13 @@ func (r *Runner) RunHook(fn func() error, evt, path, dst string, user *users.Use path = user.FullPath(path) dst = user.FullPath(dst) - if val, ok := r.Commands["before_"+evt]; ok { - for _, command := range val { - err := r.exec(command, "before_"+evt, path, dst, user) - if err != nil { - return err + if r.Enabled { + if val, ok := r.Commands["before_"+evt]; ok { + for _, command := range val { + err := r.exec(command, "before_"+evt, path, dst, user) + if err != nil { + return err + } } } } @@ -35,11 +38,13 @@ func (r *Runner) RunHook(fn func() error, evt, path, dst string, user *users.Use return err } - if val, ok := r.Commands["after_"+evt]; ok { - for _, command := range val { - err := r.exec(command, "after_"+evt, path, dst, user) - if err != nil { - return err + if r.Enabled { + if val, ok := r.Commands["after_"+evt]; ok { + for _, command := range val { + err := r.exec(command, "after_"+evt, path, dst, user) + if err != nil { + return err + } } } } diff --git a/settings/settings.go b/settings/settings.go index c6dbb0f9..6bf4c4db 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -40,6 +40,7 @@ type Server struct { Log string `json:"log"` EnableThumbnails bool `json:"enableThumbnails"` ResizePreview bool `json:"resizePreview"` + EnableExec bool `json:"enableExec"` } // Clean cleans any variables that might need cleaning.