Merge remote-tracking branch 'upstream/master'
commit
8688af97b7
|
@ -6,6 +6,8 @@ linters-settings:
|
||||||
funlen:
|
funlen:
|
||||||
lines: 100
|
lines: 100
|
||||||
statements: 50
|
statements: 50
|
||||||
|
gci:
|
||||||
|
local-prefixes: github.com/filebrowser/filebrowser
|
||||||
goconst:
|
goconst:
|
||||||
min-len: 2
|
min-len: 2
|
||||||
min-occurrences: 2
|
min-occurrences: 2
|
||||||
|
@ -26,8 +28,6 @@ linters-settings:
|
||||||
min-complexity: 15
|
min-complexity: 15
|
||||||
goimports:
|
goimports:
|
||||||
local-prefixes: github.com/filebrowser/filebrowser
|
local-prefixes: github.com/filebrowser/filebrowser
|
||||||
golint:
|
|
||||||
min-confidence: 0
|
|
||||||
gomnd:
|
gomnd:
|
||||||
settings:
|
settings:
|
||||||
mnd:
|
mnd:
|
||||||
|
@ -58,26 +58,25 @@ linters:
|
||||||
- dogsled
|
- dogsled
|
||||||
- dupl
|
- dupl
|
||||||
- errcheck
|
- errcheck
|
||||||
|
- exportloopref
|
||||||
|
- exhaustive
|
||||||
- funlen
|
- funlen
|
||||||
- gochecknoinits
|
- gochecknoinits
|
||||||
- goconst
|
- goconst
|
||||||
- gocritic
|
- gocritic
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- goimports
|
- goimports
|
||||||
- golint
|
|
||||||
- gomnd
|
- gomnd
|
||||||
- goprintffuncname
|
- goprintffuncname
|
||||||
- gosec
|
- gosec
|
||||||
- gosimple
|
- gosimple
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- interfacer
|
|
||||||
- lll
|
- lll
|
||||||
- misspell
|
- misspell
|
||||||
- nakedret
|
- nakedret
|
||||||
- nolintlint
|
- nolintlint
|
||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- scopelint
|
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
- structcheck
|
||||||
- stylecheck
|
- stylecheck
|
||||||
|
@ -89,19 +88,6 @@ linters:
|
||||||
- whitespace
|
- whitespace
|
||||||
- prealloc
|
- prealloc
|
||||||
|
|
||||||
# don't enable:
|
|
||||||
# - asciicheck
|
|
||||||
# - exhaustive (TODO: enable after next release; current release at time of writing is v1.27)
|
|
||||||
# - gochecknoglobals
|
|
||||||
# - gocognit
|
|
||||||
# - godot
|
|
||||||
# - godox
|
|
||||||
# - goerr113
|
|
||||||
# - maligned
|
|
||||||
# - nestif
|
|
||||||
# - testpackage
|
|
||||||
# - wsl
|
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
- path: cmd/.*.go
|
- path: cmd/.*.go
|
||||||
|
@ -118,6 +104,9 @@ issues:
|
||||||
- text: "Auther"
|
- text: "Auther"
|
||||||
linters:
|
linters:
|
||||||
- misspell
|
- misspell
|
||||||
|
- text: "strconv.Parse"
|
||||||
|
linters:
|
||||||
|
- gomnd
|
||||||
|
|
||||||
run:
|
run:
|
||||||
skip-dirs:
|
skip-dirs:
|
||||||
|
|
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -2,6 +2,35 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.16.0](https://github.com/filebrowser/filebrowser/compare/v2.15.0...v2.16.0) (2021-07-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* browser cache directives ([190cb99](https://github.com/filebrowser/filebrowser/commit/190cb99a79a0d438eca2da13539f8c6449ad73ac))
|
||||||
|
* display error messages on settings ([6032038](https://github.com/filebrowser/filebrowser/commit/603203848a8b2221158088b6d849609db4c0c46c))
|
||||||
|
* file name on page title ([16a34de](https://github.com/filebrowser/filebrowser/commit/16a34defc02554a77c6ac47b9e17e69d098a09fe))
|
||||||
|
* gzip encoding for static js files ([aa172b8](https://github.com/filebrowser/filebrowser/commit/aa172b8bb5f17d5f5cb9666bfb5ee650d8091fb5))
|
||||||
|
* loading spinner on views navigation ([976eb55](https://github.com/filebrowser/filebrowser/commit/976eb5583dae474125fd7ddec5dc19b6c291f98f))
|
||||||
|
* message for connection error ([5e6f14b](https://github.com/filebrowser/filebrowser/commit/5e6f14b5dcb9c5efdf526f1346e09c2d0b2f6974))
|
||||||
|
* mod time title on file info ([7d1e030](https://github.com/filebrowser/filebrowser/commit/7d1e03075d2c27148f60813defa0f68403d1d3c2))
|
||||||
|
* open file option on share ([1c25f6e](https://github.com/filebrowser/filebrowser/commit/1c25f6ee69bd71eed82af7020006d0e27537a967))
|
||||||
|
* show more button on share ([ba8c09f](https://github.com/filebrowser/filebrowser/commit/ba8c09f454feeadf4a1e97547a34151a81b389d5))
|
||||||
|
* support for IE11 browser ([7ec24d9](https://github.com/filebrowser/filebrowser/commit/7ec24d9d7794fa37825f64ca2d1575f568fb1362))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* break resource create/update handlers on error (closes [#1464](https://github.com/filebrowser/filebrowser/issues/1464)) ([5072bbb](https://github.com/filebrowser/filebrowser/commit/5072bbb2cbf5b29d041629faa8367f15e4d145a2))
|
||||||
|
* copying files with special characters ([20ebbf6](https://github.com/filebrowser/filebrowser/commit/20ebbf6611b734371426fb1b9cb5e388be90bf7e))
|
||||||
|
* delete image cache when moving ([8973c45](https://github.com/filebrowser/filebrowser/commit/8973c4598ff817647f1f1ad6ee36480054cd2776))
|
||||||
|
* don't remove files on unsuccessful updates (closes [#1456](https://github.com/filebrowser/filebrowser/issues/1456)) ([6b19ab6](https://github.com/filebrowser/filebrowser/commit/6b19ab6613b12be7f075299cd98f4b41d43827c7))
|
||||||
|
* failure on broken symlink deletion ([8650d2f](https://github.com/filebrowser/filebrowser/commit/8650d2ffe7a29cbafa800efcecbf6a61598a9f0c))
|
||||||
|
* inconsistent double click on listing item ([ba7e71a](https://github.com/filebrowser/filebrowser/commit/ba7e71a7c3b0cc71012e5adf94b1c642e554972e))
|
||||||
|
* no items displayed on file listing ([18889ad](https://github.com/filebrowser/filebrowser/commit/18889ad725f7f7e5a7e3f7abcf156487556dbeaf))
|
||||||
|
* omit file content ([209f9fa](https://github.com/filebrowser/filebrowser/commit/209f9fa77f751054512355f2b74b9b7258465d0b))
|
||||||
|
* short commit sha and typo fix in Makefile ([#1411](https://github.com/filebrowser/filebrowser/issues/1411)) ([46ee595](https://github.com/filebrowser/filebrowser/commit/46ee59538914dc2859f0da6b32e2d062d0a01b10))
|
||||||
|
|
||||||
## [2.15.0](https://github.com/filebrowser/filebrowser/compare/v2.14.1...v2.15.0) (2021-04-06)
|
## [2.15.0](https://github.com/filebrowser/filebrowser/compare/v2.14.1...v2.15.0) (2021-04-06)
|
||||||
|
|
||||||
|
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -29,10 +29,10 @@ $(BIN)/%: | $(BIN) ; $(info $(M) installing $(PACKAGE)…)
|
||||||
$Q env GOBIN=$(BIN) $(GO) install $(PACKAGE)
|
$Q env GOBIN=$(BIN) $(GO) install $(PACKAGE)
|
||||||
|
|
||||||
GOLANGCI_LINT = $(BIN)/golangci-lint
|
GOLANGCI_LINT = $(BIN)/golangci-lint
|
||||||
$(BIN)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint@v1.37.1
|
$(BIN)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint@v1.41.1
|
||||||
|
|
||||||
GOIMPORTS = $(BIN)/goimports
|
GOIMPORTS = $(BIN)/goimports
|
||||||
$(BIN)/goimports: PACKAGE=golang.org/x/tools/cmd/goimports@v0.1.0
|
$(BIN)/goimports: PACKAGE=golang.org/x/tools/cmd/goimports@v0.1.5
|
||||||
|
|
||||||
## build: Build
|
## build: Build
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
|
|
|
@ -122,7 +122,7 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.
|
||||||
}
|
}
|
||||||
|
|
||||||
func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) {
|
func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) {
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) //nolint:gomnd
|
||||||
|
|
||||||
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
||||||
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
|
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
|
||||||
|
|
|
@ -61,10 +61,10 @@ func addServerFlags(flags *pflag.FlagSet) {
|
||||||
flags.StringP("key", "k", "", "tls key")
|
flags.StringP("key", "k", "", "tls key")
|
||||||
flags.StringP("root", "r", ".", "root to prepend to relative paths")
|
flags.StringP("root", "r", ".", "root to prepend to relative paths")
|
||||||
flags.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)")
|
flags.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)")
|
||||||
flags.Uint32("socket-perm", 0666, "unix socket file permissions")
|
flags.Uint32("socket-perm", 0666, "unix socket file permissions") //nolint:gomnd
|
||||||
flags.StringP("baseurl", "b", "", "base url")
|
flags.StringP("baseurl", "b", "", "base url")
|
||||||
flags.String("cache-dir", "", "file cache directory (disabled if empty)")
|
flags.String("cache-dir", "", "file cache directory (disabled if empty)")
|
||||||
flags.Int("img-processors", 4, "image processors count")
|
flags.Int("img-processors", 4, "image processors count") //nolint:gomnd
|
||||||
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")
|
flags.Bool("disable-exec", false, "disables Command Runner feature")
|
||||||
|
@ -129,7 +129,7 @@ user created with the credentials from options "username" and "password".`,
|
||||||
cacheDir, err := cmd.Flags().GetString("cache-dir")
|
cacheDir, err := cmd.Flags().GetString("cache-dir")
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
if cacheDir != "" {
|
if cacheDir != "" {
|
||||||
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet
|
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet,gomnd
|
||||||
log.Fatalf("can't make directory %s: %s", cacheDir, err)
|
log.Fatalf("can't make directory %s: %s", cacheDir, err)
|
||||||
}
|
}
|
||||||
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
||||||
|
|
|
@ -28,7 +28,7 @@ You can also specify an optional parameter (index_end) so
|
||||||
you can remove all commands from 'index' to 'index_end',
|
you can remove all commands from 'index' to 'index_end',
|
||||||
including 'index_end'.`,
|
including 'index_end'.`,
|
||||||
Args: func(cmd *cobra.Command, args []string) error {
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
if err := cobra.RangeArgs(1, 2)(cmd, args); err != nil {
|
if err := cobra.RangeArgs(1, 2)(cmd, args); err != nil { //nolint:gomnd
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ var usersCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
func printUsers(usrs []*users.User) {
|
func printUsers(usrs []*users.User) {
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) //nolint:gomnd
|
||||||
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
|
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
|
||||||
|
|
||||||
for _, u := range usrs {
|
for _, u := range usrs {
|
||||||
|
@ -53,7 +53,7 @@ func printUsers(usrs []*users.User) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUsernameOrID(arg string) (username string, id uint) {
|
func parseUsernameOrID(arg string) (username string, id uint) {
|
||||||
id64, err := strconv.ParseUint(arg, 10, 0)
|
id64, err := strconv.ParseUint(arg, 10, 64) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return arg, 0
|
return arg, 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ func dbExists(path string) (bool, error) {
|
||||||
d := filepath.Dir(path)
|
d := filepath.Dir(path)
|
||||||
_, err = os.Stat(d)
|
_, err = os.Stat(d)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
if err := os.MkdirAll(d, 0700); err != nil { //nolint:govet
|
if err := os.MkdirAll(d, 0700); err != nil { //nolint:govet,gomnd
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
|
@ -37,11 +37,11 @@ func (f *FileCache) Store(ctx context.Context, key string, value []byte) error {
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
||||||
fileName := f.getFileName(key)
|
fileName := f.getFileName(key)
|
||||||
if err := f.fs.MkdirAll(filepath.Dir(fileName), 0700); err != nil {
|
if err := f.fs.MkdirAll(filepath.Dir(fileName), 0700); err != nil { //nolint:gomnd
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := afero.WriteFile(f.fs, fileName, value, 0700); err != nil {
|
if err := afero.WriteFile(f.fs, fileName, value, 0700); err != nil { //nolint:gomnd
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,23 +65,11 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
||||||
return nil, os.ErrPermission
|
return nil, os.ErrPermission
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := opts.Fs.Stat(opts.Path)
|
file, err := stat(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
file := &FileInfo{
|
|
||||||
Fs: opts.Fs,
|
|
||||||
Path: opts.Path,
|
|
||||||
Name: info.Name(),
|
|
||||||
ModTime: info.ModTime(),
|
|
||||||
Mode: info.Mode(),
|
|
||||||
IsDir: info.IsDir(),
|
|
||||||
Size: info.Size(),
|
|
||||||
Extension: filepath.Ext(info.Name()),
|
|
||||||
Token: opts.Token,
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Expand {
|
if opts.Expand {
|
||||||
if file.IsDir {
|
if file.IsDir {
|
||||||
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
|
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
|
||||||
|
@ -99,6 +87,64 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
||||||
return file, err
|
return file, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stat(opts FileOptions) (*FileInfo, error) {
|
||||||
|
var file *FileInfo
|
||||||
|
|
||||||
|
if lstaterFs, ok := opts.Fs.(afero.Lstater); ok {
|
||||||
|
info, _, err := lstaterFs.LstatIfPossible(opts.Path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
file = &FileInfo{
|
||||||
|
Fs: opts.Fs,
|
||||||
|
Path: opts.Path,
|
||||||
|
Name: info.Name(),
|
||||||
|
ModTime: info.ModTime(),
|
||||||
|
Mode: info.Mode(),
|
||||||
|
IsDir: info.IsDir(),
|
||||||
|
IsSymlink: IsSymlink(info.Mode()),
|
||||||
|
Size: info.Size(),
|
||||||
|
Extension: filepath.Ext(info.Name()),
|
||||||
|
Token: opts.Token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// regular file
|
||||||
|
if file != nil && !file.IsSymlink {
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fs doesn't support afero.Lstater interface or the file is a symlink
|
||||||
|
info, err := opts.Fs.Stat(opts.Path)
|
||||||
|
if err != nil {
|
||||||
|
// can't follow symlink
|
||||||
|
if file != nil && file.IsSymlink {
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// set correct file size in case of symlink
|
||||||
|
if file != nil && file.IsSymlink {
|
||||||
|
file.Size = info.Size()
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file = &FileInfo{
|
||||||
|
Fs: opts.Fs,
|
||||||
|
Path: opts.Path,
|
||||||
|
Name: info.Name(),
|
||||||
|
ModTime: info.ModTime(),
|
||||||
|
Mode: info.Mode(),
|
||||||
|
IsDir: info.IsDir(),
|
||||||
|
Size: info.Size(),
|
||||||
|
Extension: filepath.Ext(info.Name()),
|
||||||
|
Token: opts.Token,
|
||||||
|
}
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Checksum checksums a given File for a given User, using a specific
|
// Checksum checksums a given File for a given User, using a specific
|
||||||
// algorithm. The checksums data is saved on File object.
|
// algorithm. The checksums data is saved on File object.
|
||||||
func (i *FileInfo) Checksum(algo string) error {
|
func (i *FileInfo) Checksum(algo string) error {
|
||||||
|
@ -208,7 +254,7 @@ func (i *FileInfo) readFirstBytes() []byte {
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
buffer := make([]byte, 512)
|
buffer := make([]byte, 512) //nolint:gomnd
|
||||||
n, err := reader.Read(buffer)
|
n, err := reader.Read(buffer)
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
@ -256,8 +302,8 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
isSymlink := IsSymlink(f.Mode())
|
|
||||||
symlink := ""
|
symlink := ""
|
||||||
|
isSymlink := IsSymlink(f.Mode())
|
||||||
if isSymlink {
|
if isSymlink {
|
||||||
// It's a symbolic link. We try to follow it. If it doesn't work,
|
// It's a symbolic link. We try to follow it. If it doesn't work,
|
||||||
// we stay with the link information instead of the target's.
|
// we stay with the link information instead of the target's.
|
||||||
|
|
|
@ -40,13 +40,13 @@ func CopyFile(fs afero.Fs, source, dest string) error {
|
||||||
|
|
||||||
// Makes the directory needed to create the dst
|
// Makes the directory needed to create the dst
|
||||||
// file.
|
// file.
|
||||||
err = fs.MkdirAll(filepath.Dir(dest), 0666)
|
err = fs.MkdirAll(filepath.Dir(dest), 0666) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the destination file.
|
// Create the destination file.
|
||||||
dst, err := fs.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
|
dst, err := fs.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,12 @@ func NewHandler(
|
||||||
server.Clean()
|
server.Clean()
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
|
r.Use(func(next http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Security-Policy", `default-src 'self'`)
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
})
|
||||||
index, static := getStaticHandlers(store, server, assetsFs)
|
index, static := getStaticHandlers(store, server, assetsFs)
|
||||||
|
|
||||||
// NOTE: This fixes the issue where it would redirect if people did not put a
|
// NOTE: This fixes the issue where it would redirect if people did not put a
|
||||||
|
|
26
http/raw.go
26
http/raw.go
|
@ -1,9 +1,8 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
gopath "path"
|
gopath "path"
|
||||||
|
@ -11,7 +10,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mholt/archiver"
|
"github.com/mholt/archiver"
|
||||||
"github.com/spf13/afero"
|
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/files"
|
"github.com/filebrowser/filebrowser/v2/files"
|
||||||
"github.com/filebrowser/filebrowser/v2/fileutils"
|
"github.com/filebrowser/filebrowser/v2/fileutils"
|
||||||
|
@ -117,18 +115,15 @@ func addFile(ar archiver.Writer, d *data, path, commonPath string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
if !info.IsDir() && !info.Mode().IsRegular() {
|
||||||
file afero.File
|
return nil
|
||||||
arcReadCloser = ioutil.NopCloser(&bytes.Buffer{})
|
}
|
||||||
)
|
|
||||||
if !files.IsNamedPipe(info.Mode()) {
|
file, err := d.user.Fs.Open(path)
|
||||||
file, err = d.user.Fs.Open(path)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
arcReadCloser = file
|
|
||||||
}
|
|
||||||
|
|
||||||
if path != commonPath {
|
if path != commonPath {
|
||||||
filename := strings.TrimPrefix(path, commonPath)
|
filename := strings.TrimPrefix(path, commonPath)
|
||||||
|
@ -138,7 +133,7 @@ func addFile(ar archiver.Writer, d *data, path, commonPath string) error {
|
||||||
FileInfo: info,
|
FileInfo: info,
|
||||||
CustomName: filename,
|
CustomName: filename,
|
||||||
},
|
},
|
||||||
ReadCloser: arcReadCloser,
|
ReadCloser: file,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -152,9 +147,10 @@ func addFile(ar archiver.Writer, d *data, path, commonPath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
err = addFile(ar, d, filepath.Join(path, name), commonPath)
|
fPath := filepath.Join(path, name)
|
||||||
|
err = addFile(ar, d, fPath, commonPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
log.Printf("Failed to archive %s: %v", fPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +192,7 @@ func rawDirHandler(w http.ResponseWriter, r *http.Request, d *data, file *files.
|
||||||
for _, fname := range filenames {
|
for _, fname := range filenames {
|
||||||
err = addFile(ar, d, fname, commonDir)
|
err = addFile(ar, d, fname, commonDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
log.Printf("Failed to archive %s: %v", fname, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -161,13 +160,9 @@ func resourcePostHandler(fileCache FileCache) handleFunc {
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
|
||||||
_, _ = io.Copy(ioutil.Discard, r.Body)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Directories creation on POST.
|
// Directories creation on POST.
|
||||||
if strings.HasSuffix(r.URL.Path, "/") {
|
if strings.HasSuffix(r.URL.Path, "/") {
|
||||||
err := d.user.Fs.MkdirAll(r.URL.Path, 0775)
|
err := d.user.Fs.MkdirAll(r.URL.Path, 0775) //nolint:gomnd
|
||||||
return errToStatus(err), err
|
return errToStatus(err), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,16 +223,20 @@ var resourcePutHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
|
||||||
return http.StatusForbidden, nil
|
return http.StatusForbidden, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
|
||||||
_, _ = io.Copy(ioutil.Discard, r.Body)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Only allow PUT for files.
|
// Only allow PUT for files.
|
||||||
if strings.HasSuffix(r.URL.Path, "/") {
|
if strings.HasSuffix(r.URL.Path, "/") {
|
||||||
return http.StatusMethodNotAllowed, nil
|
return http.StatusMethodNotAllowed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := d.RunHook(func() error {
|
exists, err := afero.Exists(d.user.Fs, r.URL.Path)
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
return http.StatusNotFound, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.RunHook(func() error {
|
||||||
info, writeErr := writeFile(d.user.Fs, r.URL.Path, r.Body)
|
info, writeErr := writeFile(d.user.Fs, r.URL.Path, r.Body)
|
||||||
if writeErr != nil {
|
if writeErr != nil {
|
||||||
return writeErr
|
return writeErr
|
||||||
|
@ -248,10 +247,6 @@ var resourcePutHandler = withUser(func(w http.ResponseWriter, r *http.Request, d
|
||||||
return nil
|
return nil
|
||||||
}, "save", r.URL.Path, "", d.user)
|
}, "save", r.URL.Path, "", d.user)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
_ = d.user.Fs.RemoveAll(r.URL.Path)
|
|
||||||
}
|
|
||||||
|
|
||||||
return errToStatus(err), err
|
return errToStatus(err), err
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -378,12 +373,12 @@ func addVersionSuffix(source string, fs afero.Fs) string {
|
||||||
|
|
||||||
func writeFile(fs afero.Fs, dst string, in io.Reader) (os.FileInfo, error) {
|
func writeFile(fs afero.Fs, dst string, in io.Reader) (os.FileInfo, error) {
|
||||||
dir, _ := path.Split(dst)
|
dir, _ := path.Split(dst)
|
||||||
err := fs.MkdirAll(dir, 0775)
|
err := fs.MkdirAll(dir, 0775) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := fs.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775)
|
file, err := fs.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0775) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ var sharePostHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes := make([]byte, 6)
|
bytes := make([]byte, 6) //nolint:gomnd
|
||||||
_, err := rand.Read(bytes)
|
_, err := rand.Read(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
|
@ -129,7 +129,7 @@ var sharePostHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
|
||||||
|
|
||||||
var token string
|
var token string
|
||||||
if len(hash) > 0 {
|
if len(hash) > 0 {
|
||||||
tokenBuffer := make([]byte, 96)
|
tokenBuffer := make([]byte, 96) //nolint:gomnd
|
||||||
if _, err := rand.Read(tokenBuffer); err != nil {
|
if _, err := rand.Read(tokenBuffer); err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ type modifyUserRequest struct {
|
||||||
|
|
||||||
func getUserID(r *http.Request) (uint, error) {
|
func getUserID(r *http.Request) (uint, error) {
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
i, err := strconv.ParseUint(vars["id"], 10, 0)
|
i, err := strconv.ParseUint(vars["id"], 10, 0) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Location", "/settings/users/"+strconv.FormatUint(uint64(req.Data.ID), 10))
|
w.Header().Set("Location", "/settings/users/"+strconv.FormatUint(uint64(req.Data.ID), 10)) //nolint:gomnd
|
||||||
return http.StatusCreated, nil
|
return http.StatusCreated, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,8 @@ func (s *Service) Resize(ctx context.Context, in io.Reader, width, height int, o
|
||||||
switch config.resizeMode {
|
switch config.resizeMode {
|
||||||
case ResizeModeFill:
|
case ResizeModeFill:
|
||||||
img = imaging.Fill(img, width, height, imaging.Center, config.quality.resampleFilter())
|
img = imaging.Fill(img, width, height, imaging.Center, config.quality.resampleFilter())
|
||||||
|
case ResizeModeFit:
|
||||||
|
fallthrough //nolint:gocritic
|
||||||
default:
|
default:
|
||||||
img = imaging.Fit(img, width, height, config.quality.resampleFilter())
|
img = imaging.Fit(img, width, height, config.quality.resampleFilter())
|
||||||
}
|
}
|
||||||
|
@ -205,7 +207,7 @@ func getEmbeddedThumbnail(in io.Reader) ([]byte, io.Reader, error) {
|
||||||
|
|
||||||
offset := 0
|
offset := 0
|
||||||
offsets := []int{12, 30}
|
offsets := []int{12, 30}
|
||||||
head := make([]byte, 0xffff)
|
head := make([]byte, 0xffff) //nolint:gomnd
|
||||||
|
|
||||||
_, err := r.Read(head)
|
_, err := r.Read(head)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -51,9 +51,9 @@ func (s *Server) Clean() {
|
||||||
s.BaseURL = strings.TrimSuffix(s.BaseURL, "/")
|
s.BaseURL = strings.TrimSuffix(s.BaseURL, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateKey generates a key of 256 bits.
|
// GenerateKey generates a key of 512 bits.
|
||||||
func GenerateKey() ([]byte, error) {
|
func GenerateKey() ([]byte, error) {
|
||||||
b := make([]byte, 64)
|
b := make([]byte, 64) //nolint:gomnd
|
||||||
_, err := rand.Read(b)
|
_, err := rand.Read(b)
|
||||||
// Note that err == nil only if we read len(b) bytes.
|
// Note that err == nil only if we read len(b) bytes.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -17,7 +17,7 @@ func NewStorage(db *storm.DB) (*storage.Storage, error) {
|
||||||
settingsStore := settings.NewStorage(settingsBackend{db: db})
|
settingsStore := settings.NewStorage(settingsBackend{db: db})
|
||||||
authStore := auth.NewStorage(authBackend{db: db}, userStore)
|
authStore := auth.NewStorage(authBackend{db: db}, userStore)
|
||||||
|
|
||||||
err := save(db, "version", 2)
|
err := save(db, "version", 2) //nolint:gomnd
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue