feat: add disable exec flag (#1090)
parent
1529e796df
commit
97693cc611
|
@ -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, "\tAddress:\t%s\n", ser.Address)
|
||||||
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
|
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
|
||||||
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
|
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.Fprintln(w, "\nDefaults:")
|
||||||
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
|
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
|
||||||
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
||||||
|
|
|
@ -64,6 +64,7 @@ func addServerFlags(flags *pflag.FlagSet) {
|
||||||
flags.Int("img-processors", 4, "image processors count")
|
flags.Int("img-processors", 4, "image processors count")
|
||||||
flags.Bool("disable-thumbnails", false, "disable image thumbnails")
|
flags.Bool("disable-thumbnails", false, "disable image thumbnails")
|
||||||
flags.Bool("disable-preview-resize", false, "disable resize of image previews")
|
flags.Bool("disable-preview-resize", false, "disable resize of image previews")
|
||||||
|
flags.Bool("disable-exec", false, "disables Command Runner feature")
|
||||||
}
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
|
@ -241,6 +242,9 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
|
||||||
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
|
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
|
||||||
server.ResizePreview = !disablePreviewResize
|
server.ResizePreview = !disablePreviewResize
|
||||||
|
|
||||||
|
_, disableExec := getParamB(flags, "disable-exec")
|
||||||
|
server.EnableExec = !disableExec
|
||||||
|
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<delete-button v-show="showDeleteButton"></delete-button>
|
<delete-button v-show="showDeleteButton"></delete-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<shell-button v-show="user.perm.execute" />
|
<shell-button v-if="isExecEnabled && user.perm.execute" />
|
||||||
<switch-button v-show="isListing"></switch-button>
|
<switch-button v-show="isListing"></switch-button>
|
||||||
<download-button v-show="showDownloadButton"></download-button>
|
<download-button v-show="showDownloadButton"></download-button>
|
||||||
<upload-button v-show="showUpload"></upload-button>
|
<upload-button v-show="showUpload"></upload-button>
|
||||||
|
@ -68,7 +68,7 @@ import CopyButton from './buttons/Copy'
|
||||||
import ShareButton from './buttons/Share'
|
import ShareButton from './buttons/Share'
|
||||||
import ShellButton from './buttons/Shell'
|
import ShellButton from './buttons/Shell'
|
||||||
import {mapGetters, mapState} from 'vuex'
|
import {mapGetters, mapState} from 'vuex'
|
||||||
import { logoURL } from '@/utils/constants'
|
import { logoURL, enableExec } from '@/utils/constants'
|
||||||
import * as api from '@/api'
|
import * as api from '@/api'
|
||||||
import buttons from '@/utils/buttons'
|
import buttons from '@/utils/buttons'
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ export default {
|
||||||
'multiple'
|
'multiple'
|
||||||
]),
|
]),
|
||||||
logoURL: () => logoURL,
|
logoURL: () => logoURL,
|
||||||
|
isExecEnabled: () => enableExec,
|
||||||
isMobile () {
|
isMobile () {
|
||||||
return this.width <= 736
|
return this.width <= 736
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,13 +9,14 @@
|
||||||
<p><input type="checkbox" :disabled="admin" v-model="perm.delete"> {{ $t('settings.perm.delete') }}</p>
|
<p><input type="checkbox" :disabled="admin" v-model="perm.delete"> {{ $t('settings.perm.delete') }}</p>
|
||||||
<p><input type="checkbox" :disabled="admin" v-model="perm.download"> {{ $t('settings.perm.download') }}</p>
|
<p><input type="checkbox" :disabled="admin" v-model="perm.download"> {{ $t('settings.perm.download') }}</p>
|
||||||
<p><input type="checkbox" :disabled="admin" v-model="perm.modify"> {{ $t('settings.perm.modify') }}</p>
|
<p><input type="checkbox" :disabled="admin" v-model="perm.modify"> {{ $t('settings.perm.modify') }}</p>
|
||||||
<p><input type="checkbox" :disabled="admin" v-model="perm.execute"> {{ $t('settings.perm.execute') }}</p>
|
<p v-if="isExecEnabled"><input type="checkbox" :disabled="admin" v-model="perm.execute"> {{ $t('settings.perm.execute') }}</p>
|
||||||
<p><input type="checkbox" :disabled="admin" v-model="perm.rename"> {{ $t('settings.perm.rename') }}</p>
|
<p><input type="checkbox" :disabled="admin" v-model="perm.rename"> {{ $t('settings.perm.rename') }}</p>
|
||||||
<p><input type="checkbox" :disabled="admin" v-model="perm.share"> {{ $t('settings.perm.share') }}</p>
|
<p><input type="checkbox" :disabled="admin" v-model="perm.share"> {{ $t('settings.perm.share') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { enableExec } from '@/utils/constants'
|
||||||
export default {
|
export default {
|
||||||
name: 'permissions',
|
name: 'permissions',
|
||||||
props: ['perm'],
|
props: ['perm'],
|
||||||
|
@ -33,7 +34,8 @@ export default {
|
||||||
|
|
||||||
this.perm.admin = value
|
this.perm.admin = value
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
isExecEnabled: () => enableExec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<permissions :perm.sync="user.perm" />
|
<permissions :perm.sync="user.perm" />
|
||||||
<commands :commands.sync="user.commands" />
|
<commands v-if="isExecEnabled" :commands.sync="user.commands" />
|
||||||
|
|
||||||
<div v-if="!isDefault">
|
<div v-if="!isDefault">
|
||||||
<h3>{{ $t('settings.rules') }}</h3>
|
<h3>{{ $t('settings.rules') }}</h3>
|
||||||
|
@ -40,6 +40,7 @@ import Languages from './Languages'
|
||||||
import Rules from './Rules'
|
import Rules from './Rules'
|
||||||
import Permissions from './Permissions'
|
import Permissions from './Permissions'
|
||||||
import Commands from './Commands'
|
import Commands from './Commands'
|
||||||
|
import { enableExec } from '@/utils/constants'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'user',
|
name: 'user',
|
||||||
|
@ -53,7 +54,8 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
passwordPlaceholder () {
|
passwordPlaceholder () {
|
||||||
return this.isNew ? '' : this.$t('settings.avoidChanges')
|
return this.isNew ? '' : this.$t('settings.avoidChanges')
|
||||||
}
|
},
|
||||||
|
isExecEnabled: () => enableExec
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'user.perm.admin': function () {
|
'user.perm.admin': function () {
|
||||||
|
|
|
@ -13,6 +13,7 @@ const loginPage = window.FileBrowser.LoginPage
|
||||||
const theme = window.FileBrowser.Theme
|
const theme = window.FileBrowser.Theme
|
||||||
const enableThumbs = window.FileBrowser.EnableThumbs
|
const enableThumbs = window.FileBrowser.EnableThumbs
|
||||||
const resizePreview = window.FileBrowser.ResizePreview
|
const resizePreview = window.FileBrowser.ResizePreview
|
||||||
|
const enableExec = window.FileBrowser.EnableExec
|
||||||
|
|
||||||
export {
|
export {
|
||||||
name,
|
name,
|
||||||
|
@ -28,5 +29,6 @@ export {
|
||||||
loginPage,
|
loginPage,
|
||||||
theme,
|
theme,
|
||||||
enableThumbs,
|
enableThumbs,
|
||||||
resizePreview
|
resizePreview,
|
||||||
|
enableExec
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<sidebar></sidebar>
|
<sidebar></sidebar>
|
||||||
<main>
|
<main>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
<shell v-if="isLogged && user.perm.execute" />
|
<shell v-if="isExecEnabled && isLogged && user.perm.execute" />
|
||||||
</main>
|
</main>
|
||||||
<prompts></prompts>
|
<prompts></prompts>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,6 +19,7 @@ import Sidebar from '@/components/Sidebar'
|
||||||
import Prompts from '@/components/prompts/Prompts'
|
import Prompts from '@/components/prompts/Prompts'
|
||||||
import SiteHeader from '@/components/Header'
|
import SiteHeader from '@/components/Header'
|
||||||
import Shell from '@/components/Shell'
|
import Shell from '@/components/Shell'
|
||||||
|
import { enableExec } from '@/utils/constants'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'layout',
|
name: 'layout',
|
||||||
|
@ -30,7 +31,8 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([ 'isLogged', 'progress' ]),
|
...mapGetters([ 'isLogged', 'progress' ]),
|
||||||
...mapState([ 'user' ])
|
...mapState([ 'user' ]),
|
||||||
|
isExecEnabled: () => enableExec
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'$route': function () {
|
'$route': function () {
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
<p class="small">{{ $t('settings.globalRules') }}</p>
|
<p class="small">{{ $t('settings.globalRules') }}</p>
|
||||||
<rules :rules.sync="settings.rules" />
|
<rules :rules.sync="settings.rules" />
|
||||||
|
|
||||||
<h3>{{ $t('settings.executeOnShell') }}</h3>
|
<div v-if="isExecEnabled">
|
||||||
<p class="small">{{ $t('settings.executeOnShellDescription') }}</p>
|
<h3>{{ $t('settings.executeOnShell') }}</h3>
|
||||||
<input class="input input--block" type="text" placeholder="bash -c, cmd /c, ..." v-model="settings.shell" />
|
<p class="small">{{ $t('settings.executeOnShellDescription') }}</p>
|
||||||
|
<input class="input input--block" type="text" placeholder="bash -c, cmd /c, ..." v-model="settings.shell" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>{{ $t('settings.branding') }}</h3>
|
<h3>{{ $t('settings.branding') }}</h3>
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form class="card" @submit.prevent="save">
|
<form v-if="isExecEnabled" class="card" @submit.prevent="save">
|
||||||
<div class="card-title">
|
<div class="card-title">
|
||||||
<h2>{{ $t('settings.commandRunner') }}</h2>
|
<h2>{{ $t('settings.commandRunner') }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,6 +106,7 @@ import { settings as api } from '@/api'
|
||||||
import UserForm from '@/components/settings/UserForm'
|
import UserForm from '@/components/settings/UserForm'
|
||||||
import Rules from '@/components/settings/Rules'
|
import Rules from '@/components/settings/Rules'
|
||||||
import Themes from '@/components/settings/Themes'
|
import Themes from '@/components/settings/Themes'
|
||||||
|
import { enableExec } from '@/utils/constants'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
|
@ -119,7 +122,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState([ 'user' ])
|
...mapState([ 'user' ]),
|
||||||
|
isExecEnabled: () => enableExec
|
||||||
},
|
},
|
||||||
async created () {
|
async created () {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -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
|
if err := conn.WriteMessage(websocket.TextMessage, cmdNotAllowed); err != nil { //nolint:shadow
|
||||||
wsErr(conn, r, http.StatusInternalServerError, err)
|
wsErr(conn, r, http.StatusInternalServerError, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ func handle(fn handleFunc, prefix string, store *storage.Storage, server *settin
|
||||||
}
|
}
|
||||||
|
|
||||||
status, err := fn(w, r, &data{
|
status, err := fn(w, r, &data{
|
||||||
Runner: &runner.Runner{Settings: settings},
|
Runner: &runner.Runner{Enabled: server.EnableExec, Settings: settings},
|
||||||
store: store,
|
store: store,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
server: server,
|
server: server,
|
||||||
|
|
|
@ -41,6 +41,7 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, box *
|
||||||
"Theme": d.settings.Branding.Theme,
|
"Theme": d.settings.Branding.Theme,
|
||||||
"EnableThumbs": d.server.EnableThumbnails,
|
"EnableThumbs": d.server.EnableThumbnails,
|
||||||
"ResizePreview": d.server.ResizePreview,
|
"ResizePreview": d.server.ResizePreview,
|
||||||
|
"EnableExec": d.server.EnableExec,
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.settings.Branding.Files != "" {
|
if d.settings.Branding.Files != "" {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
|
|
||||||
// Runner is a commands runner.
|
// Runner is a commands runner.
|
||||||
type Runner struct {
|
type Runner struct {
|
||||||
|
Enabled bool
|
||||||
*settings.Settings
|
*settings.Settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,11 +22,13 @@ func (r *Runner) RunHook(fn func() error, evt, path, dst string, user *users.Use
|
||||||
path = user.FullPath(path)
|
path = user.FullPath(path)
|
||||||
dst = user.FullPath(dst)
|
dst = user.FullPath(dst)
|
||||||
|
|
||||||
if val, ok := r.Commands["before_"+evt]; ok {
|
if r.Enabled {
|
||||||
for _, command := range val {
|
if val, ok := r.Commands["before_"+evt]; ok {
|
||||||
err := r.exec(command, "before_"+evt, path, dst, user)
|
for _, command := range val {
|
||||||
if err != nil {
|
err := r.exec(command, "before_"+evt, path, dst, user)
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, ok := r.Commands["after_"+evt]; ok {
|
if r.Enabled {
|
||||||
for _, command := range val {
|
if val, ok := r.Commands["after_"+evt]; ok {
|
||||||
err := r.exec(command, "after_"+evt, path, dst, user)
|
for _, command := range val {
|
||||||
if err != nil {
|
err := r.exec(command, "after_"+evt, path, dst, user)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ type Server struct {
|
||||||
Log string `json:"log"`
|
Log string `json:"log"`
|
||||||
EnableThumbnails bool `json:"enableThumbnails"`
|
EnableThumbnails bool `json:"enableThumbnails"`
|
||||||
ResizePreview bool `json:"resizePreview"`
|
ResizePreview bool `json:"resizePreview"`
|
||||||
|
EnableExec bool `json:"enableExec"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean cleans any variables that might need cleaning.
|
// Clean cleans any variables that might need cleaning.
|
||||||
|
|
Loading…
Reference in New Issue