added missing commit
This commit is contained in:
parent
8362a2ee2d
commit
0d2b9bcabf
@ -66,6 +66,7 @@ func addServerFlags(flags *pflag.FlagSet) {
|
||||
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")
|
||||
flags.Bool("disable-type-detection-by-header", false, "disables type detection by reading file headers")
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@ -243,6 +244,9 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
|
||||
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
|
||||
server.ResizePreview = !disablePreviewResize
|
||||
|
||||
_, disableTypeDetectionByHeader := getParamB(flags, "disable-type-detection-by-header")
|
||||
server.TypeDetectionByHeader = !disableTypeDetectionByHeader
|
||||
|
||||
_, disableExec := getParamB(flags, "disable-exec")
|
||||
server.EnableExec = !disableExec
|
||||
|
||||
|
||||
@ -81,7 +81,7 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
||||
return file, nil
|
||||
}
|
||||
|
||||
err = file.detectType(opts.Modify, true)
|
||||
err = file.detectType(opts.Modify, true, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -134,7 +134,7 @@ func (i *FileInfo) Checksum(algo string) error {
|
||||
|
||||
//nolint:goconst
|
||||
//TODO: use constants
|
||||
func (i *FileInfo) detectType(modify, saveContent bool) error {
|
||||
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
||||
if IsNamedPipe(i.Mode) {
|
||||
i.Type = "blob"
|
||||
return nil
|
||||
@ -143,6 +143,51 @@ func (i *FileInfo) detectType(modify, saveContent bool) error {
|
||||
// imagine the situation where a file in a dir with thousands
|
||||
// of files couldn't be opened: we'd have immediately
|
||||
// a 500 even though it doesn't matter. So we just log it.
|
||||
|
||||
var buffer []byte
|
||||
|
||||
mimetype := mime.TypeByExtension(i.Extension)
|
||||
if mimetype == "" && readHeader {
|
||||
buffer = i.readFirstBytes()
|
||||
mimetype = http.DetectContentType(buffer)
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(mimetype, "video"):
|
||||
i.Type = "video"
|
||||
i.detectSubtitles()
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "audio"):
|
||||
i.Type = "audio"
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "image"):
|
||||
i.Type = "image"
|
||||
return nil
|
||||
case (strings.HasPrefix(mimetype, "text") || (len(buffer) > 0 && !isBinary(buffer))) && i.Size <= 10*1024*1024: // 10 MB
|
||||
i.Type = "text"
|
||||
|
||||
if !modify {
|
||||
i.Type = "textImmutable"
|
||||
}
|
||||
|
||||
if saveContent {
|
||||
afs := &afero.Afero{Fs: i.Fs}
|
||||
content, err := afs.ReadFile(i.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Content = string(content)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
i.Type = "blob"
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *FileInfo) readFirstBytes() []byte {
|
||||
reader, err := i.Fs.Open(i.Path)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
@ -159,44 +204,7 @@ func (i *FileInfo) detectType(modify, saveContent bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
mimetype := mime.TypeByExtension(i.Extension)
|
||||
if mimetype == "" {
|
||||
mimetype = http.DetectContentType(buffer[:n])
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(mimetype, "video"):
|
||||
i.Type = "video"
|
||||
i.detectSubtitles()
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "audio"):
|
||||
i.Type = "audio"
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "image"):
|
||||
i.Type = "image"
|
||||
return nil
|
||||
case isBinary(buffer[:n], n) || i.Size > 10*1024*1024: // 10 MB
|
||||
i.Type = "blob"
|
||||
return nil
|
||||
default:
|
||||
i.Type = "text"
|
||||
|
||||
if !modify {
|
||||
i.Type = "textImmutable"
|
||||
}
|
||||
|
||||
if saveContent {
|
||||
afs := &afero.Afero{Fs: i.Fs}
|
||||
content, err := afs.ReadFile(i.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Content = string(content)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return buffer[:n]
|
||||
}
|
||||
|
||||
func (i *FileInfo) detectSubtitles() {
|
||||
@ -228,7 +236,6 @@ func (i *FileInfo) readListing(checker rules.Checker) error {
|
||||
NumFiles: 0,
|
||||
}
|
||||
|
||||
detectDisabled := checker.IsTypeDetectDisabled(i.Path)
|
||||
for _, f := range dir {
|
||||
name := f.Name()
|
||||
fPath := path.Join(i.Path, name)
|
||||
@ -262,13 +269,9 @@ func (i *FileInfo) readListing(checker rules.Checker) error {
|
||||
} else {
|
||||
listing.NumFiles++
|
||||
|
||||
if detectDisabled {
|
||||
file.Type = "blob"
|
||||
} else {
|
||||
err := file.detectType(true, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err := file.detectType(true, false, checker.ReadHeader())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
<template>
|
||||
<form class="rules small">
|
||||
<div v-for="(disableTypeDetection, index) in disableTypeDetections" :key="index">
|
||||
<input type="checkbox" v-model="disableTypeDetection.regex"><label>Regex</label>
|
||||
|
||||
<input
|
||||
@keypress.enter.prevent
|
||||
type="text"
|
||||
v-if="disableTypeDetection.regex"
|
||||
v-model="disableTypeDetection.regexp.raw"
|
||||
:placeholder="$t('settings.insertRegex')" />
|
||||
<input
|
||||
@keypress.enter.prevent
|
||||
type="text"
|
||||
v-else
|
||||
v-model="disableTypeDetection.path"
|
||||
:placeholder="$t('settings.insertPath')" />
|
||||
|
||||
<button class="button button--red" @click="remove($event, index)">-</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button class="button" @click="create" default="false">{{ $t('buttons.new') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'disableTypeDetections-textarea',
|
||||
props: ['disableTypeDetections'],
|
||||
methods: {
|
||||
remove (event, index) {
|
||||
event.preventDefault()
|
||||
let disableTypeDetections = [ ...this.disableTypeDetections ]
|
||||
disableTypeDetections.splice(index, 1)
|
||||
this.$emit('update:disableTypeDetections', [ ...disableTypeDetections ])
|
||||
},
|
||||
create (event) {
|
||||
event.preventDefault()
|
||||
|
||||
this.$emit('update:disableTypeDetections', [
|
||||
...this.disableTypeDetections,
|
||||
{
|
||||
allow: true,
|
||||
path: '',
|
||||
regex: false,
|
||||
regexp: {
|
||||
raw: ''
|
||||
}
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -36,19 +36,12 @@
|
||||
<p class="small">{{ $t('settings.rulesHelp') }}</p>
|
||||
<rules :rules.sync="user.rules" />
|
||||
</div>
|
||||
|
||||
<div v-if="!isDefault">
|
||||
<h3>{{ $t('settings.disableTypeDetections') }}</h3>
|
||||
<p class="small">{{ $t('settings.disableTypeDetectionsHelp') }}</p>
|
||||
<disableTypeDetections :disableTypeDetections.sync="user.disableTypeDetections" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Languages from './Languages'
|
||||
import Rules from './Rules'
|
||||
import DisableTypeDetections from './DisableTypeDetections'
|
||||
import Permissions from './Permissions'
|
||||
import Commands from './Commands'
|
||||
import { enableExec } from '@/utils/constants'
|
||||
@ -59,7 +52,6 @@ export default {
|
||||
Permissions,
|
||||
Languages,
|
||||
Rules,
|
||||
DisableTypeDetections,
|
||||
Commands
|
||||
},
|
||||
props: [ 'user', 'isNew', 'isDefault' ],
|
||||
|
||||
@ -161,8 +161,6 @@
|
||||
"ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.",
|
||||
"rules": "Rules",
|
||||
"rulesHelp": "Here you can define a set of allow and disallow rules for this specific user. The blocked files won't show up in the listings and they wont be accessible to the user. We support regex and paths relative to the users scope.\n",
|
||||
"disableTypeDetections": "Disable File Type Detections",
|
||||
"disableTypeDetectionsHelp": "Here you can define a set of paths to disable file type detections for this specific user. Useful when the path is a network drive or has a lot of files. We support regex and paths relative to the users scope.\n",
|
||||
"scope": "Scope",
|
||||
"settingsUpdated": "Settings updated!",
|
||||
"user": "User",
|
||||
|
||||
@ -160,8 +160,6 @@
|
||||
"ruleExample2": "阻止用户访问其目录范围的根目录下名为 Caddyfile 的文件。",
|
||||
"rules": "规则",
|
||||
"rulesHelp": "您可以为该用户制定一组黑名单或白名单式的规则,被屏蔽的文件将不会显示在列表中,用户也无权限访问,支持相对于目录范围的路径。",
|
||||
"disableTypeDetections": "关闭文件类型检测",
|
||||
"disableTypeDetectionsHelp": "您可以为该用户制定一组不会检测文件类型的路径,当路径是挂载的网络磁盘或者文件较多时能加快反应速度,支持相对于目录范围的路径。",
|
||||
"scope": "目录范围",
|
||||
"settingsUpdated": "设置已更新!",
|
||||
"user": "用户",
|
||||
@ -246,4 +244,4 @@
|
||||
"downloadFile": "下载文件",
|
||||
"downloadFolder": "下载文件夹"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,6 @@ export default {
|
||||
username: '',
|
||||
passsword: '',
|
||||
rules: [],
|
||||
disableTypeDetections: [],
|
||||
lockPassword: false,
|
||||
id: 0
|
||||
}
|
||||
|
||||
@ -21,21 +21,20 @@ const (
|
||||
|
||||
// User describes a user.
|
||||
type User struct {
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
DisableTypeDetections []rules.Rule `json:"disableTypeDetections"`
|
||||
ID uint `storm:"id,increment" json:"id"`
|
||||
Username string `storm:"unique" json:"username"`
|
||||
Password string `json:"password"`
|
||||
Scope string `json:"scope"`
|
||||
Locale string `json:"locale"`
|
||||
LockPassword bool `json:"lockPassword"`
|
||||
ViewMode ViewMode `json:"viewMode"`
|
||||
SingleClick bool `json:"singleClick"`
|
||||
Perm Permissions `json:"perm"`
|
||||
Commands []string `json:"commands"`
|
||||
Sorting files.Sorting `json:"sorting"`
|
||||
Fs afero.Fs `json:"-" yaml:"-"`
|
||||
Rules []rules.Rule `json:"rules"`
|
||||
HideDotfiles bool `json:"hideDotfiles"`
|
||||
}
|
||||
|
||||
// GetRules implements rules.Provider.
|
||||
@ -51,7 +50,6 @@ var checkableFields = []string{
|
||||
"Commands",
|
||||
"Sorting",
|
||||
"Rules",
|
||||
"DisableTypeDetections",
|
||||
}
|
||||
|
||||
// Clean cleans up a user and verifies if all its fields
|
||||
@ -88,10 +86,6 @@ func (u *User) Clean(baseScope string, fields ...string) error {
|
||||
if u.Rules == nil {
|
||||
u.Rules = []rules.Rule{}
|
||||
}
|
||||
case "DisableTypeDetections":
|
||||
if u.DisableTypeDetections == nil {
|
||||
u.DisableTypeDetections = []rules.Rule{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user