feat: add disable exec flag (#1090)

This commit is contained in:
Keagan McClelland 2020-10-01 08:45:24 -06:00 committed by GitHub
parent 1529e796df
commit 97693cc611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 53 additions and 28 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -13,7 +13,7 @@
<link rel="icon" type="image/png" sizes="32x32" href="[{[ .StaticURL ]}]/img/icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="[{[ .StaticURL ]}]/img/icons/favicon-16x16.png">
<!-- Add to home screen for Android and modern mobile browsers -->
<link rel="manifest" id="manifestPlaceholder" crossorigin="use-credentials">
<meta name="theme-color" content="#2979ff">
@ -31,7 +31,7 @@
<!-- Inject Some Variables and generate the manifest json -->
<script>
window.FileBrowser = JSON.parse(`[{[ .Json ]}]`);
var fullStaticURL = window.location.origin + window.FileBrowser.StaticURL;
var dynamicManifest = {
"name": window.FileBrowser.Name || 'File Browser',

View File

@ -37,7 +37,7 @@
<delete-button v-show="showDeleteButton"></delete-button>
</div>
<shell-button v-show="user.perm.execute" />
<shell-button v-if="isExecEnabled && user.perm.execute" />
<switch-button v-show="isListing"></switch-button>
<download-button v-show="showDownloadButton"></download-button>
<upload-button v-show="showUpload"></upload-button>
@ -68,7 +68,7 @@ import CopyButton from './buttons/Copy'
import ShareButton from './buttons/Share'
import ShellButton from './buttons/Shell'
import {mapGetters, mapState} from 'vuex'
import { logoURL } from '@/utils/constants'
import { logoURL, enableExec } from '@/utils/constants'
import * as api from '@/api'
import buttons from '@/utils/buttons'
@ -120,6 +120,7 @@ export default {
'multiple'
]),
logoURL: () => logoURL,
isExecEnabled: () => enableExec,
isMobile () {
return this.width <= 736
},

View File

@ -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.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.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.share"> {{ $t('settings.perm.share') }}</p>
</div>
</template>
<script>
import { enableExec } from '@/utils/constants'
export default {
name: 'permissions',
props: ['perm'],
@ -33,7 +34,8 @@ export default {
this.perm.admin = value
}
}
},
isExecEnabled: () => enableExec
}
}
</script>

View File

@ -25,7 +25,7 @@
</p>
<permissions :perm.sync="user.perm" />
<commands :commands.sync="user.commands" />
<commands v-if="isExecEnabled" :commands.sync="user.commands" />
<div v-if="!isDefault">
<h3>{{ $t('settings.rules') }}</h3>
@ -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 () {

View File

@ -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
}

View File

@ -7,7 +7,7 @@
<sidebar></sidebar>
<main>
<router-view></router-view>
<shell v-if="isLogged && user.perm.execute" />
<shell v-if="isExecEnabled && isLogged && user.perm.execute" />
</main>
<prompts></prompts>
</div>
@ -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 () {

View File

@ -14,9 +14,11 @@
<p class="small">{{ $t('settings.globalRules') }}</p>
<rules :rules.sync="settings.rules" />
<h3>{{ $t('settings.executeOnShell') }}</h3>
<p class="small">{{ $t('settings.executeOnShellDescription') }}</p>
<input class="input input--block" type="text" placeholder="bash -c, cmd /c, ..." v-model="settings.shell" />
<div v-if="isExecEnabled">
<h3>{{ $t('settings.executeOnShell') }}</h3>
<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>
@ -67,7 +69,7 @@
</div>
</form>
<form class="card" @submit.prevent="save">
<form v-if="isExecEnabled" class="card" @submit.prevent="save">
<div class="card-title">
<h2>{{ $t('settings.commandRunner') }}</h2>
</div>
@ -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 {

View File

@ -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)
}

View File

@ -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,

View File

@ -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 != "" {

View File

@ -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
}
}
}
}

View File

@ -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.