From 58835b7e535cc96e1c8a5d85821c1545743ca757 Mon Sep 17 00:00:00 2001 From: Oleg Lobanov Date: Thu, 24 Dec 2020 17:50:27 +0100 Subject: [PATCH 01/18] fix: move files between different volumes (closes #1177) --- fileutils/file.go | 31 +++++++++++++++++++++++++------ http/resource.go | 2 +- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/fileutils/file.go b/fileutils/file.go index 5c0248df..6e6cd2af 100644 --- a/fileutils/file.go +++ b/fileutils/file.go @@ -9,6 +9,25 @@ import ( "github.com/spf13/afero" ) +// MoveFile moves file from src to dst. +// By default the rename filesystem system call is used. If src and dst point to different volumes +// the file copy is used as a fallback +func MoveFile(fs afero.Fs, src, dst string) error { + if fs.Rename(src, dst) == nil { + return nil + } + // fallback + err := CopyFile(fs, src, dst) + if err != nil { + _ = fs.Remove(dst) + return err + } + if err := fs.Remove(src); err != nil { + return err + } + return nil +} + // CopyFile copies a file from source to dest and returns // an error if any. func CopyFile(fs afero.Fs, source, dest string) error { @@ -39,14 +58,14 @@ func CopyFile(fs afero.Fs, source, dest string) error { return err } - // Copy the mode if the user can't - // open the file. + // Copy the mode info, err := fs.Stat(source) if err != nil { - err = fs.Chmod(dest, info.Mode()) - if err != nil { - return err - } + return err + } + err = fs.Chmod(dest, info.Mode()) + if err != nil { + return err } return nil diff --git a/http/resource.go b/http/resource.go index daeb344b..08e885f8 100644 --- a/http/resource.go +++ b/http/resource.go @@ -200,7 +200,7 @@ var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request, src = path.Clean("/" + src) dst = path.Clean("/" + dst) - return d.user.Fs.Rename(src, dst) + return fileutils.MoveFile(d.user.Fs, src, dst) default: return fmt.Errorf("unsupported action %s: %w", action, errors.ErrInvalidRequestParams) } From f62806f6c9e9c7f392d1b747d65b8fe40b313e89 Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Fri, 25 Dec 2020 01:22:48 +0800 Subject: [PATCH 02/18] fix: check user input to prevent permission elevation (#1196) (closes #1195) --- http/users.go | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/http/users.go b/http/users.go index ee05ef1c..b03c9e09 100644 --- a/http/users.go +++ b/http/users.go @@ -14,6 +14,10 @@ import ( "github.com/filebrowser/filebrowser/v2/users" ) +var ( + NonModifiableFieldsForNonAdmin = []string{"Username", "Scope", "LockPassword", "Perm", "Commands", "Rules"} +) + type modifyUserRequest struct { modifyRequest Data *users.User `json:"data"` @@ -148,9 +152,9 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request return http.StatusBadRequest, nil } - if len(req.Which) == 1 && req.Which[0] == "all" { + if len(req.Which) == 0 || (len(req.Which) == 1 && req.Which[0] == "all") { if !d.user.Perm.Admin { - return http.StatusForbidden, err + return http.StatusForbidden, nil } if req.Data.Password != "" { @@ -169,7 +173,10 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request } for k, v := range req.Which { - if v == "password" { + v = strings.Title(v) + req.Which[k] = v + + if v == "Password" { if !d.user.Perm.Admin && d.user.LockPassword { return http.StatusForbidden, nil } @@ -180,11 +187,11 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request } } - if !d.user.Perm.Admin && (v == "scope" || v == "perm" || v == "username") { - return http.StatusForbidden, nil + for _, f := range NonModifiableFieldsForNonAdmin { + if !d.user.Perm.Admin && v == f { + return http.StatusForbidden, nil + } } - - req.Which[k] = strings.Title(v) } err = d.store.Users.Update(req.Data, req.Which...) From 8faa96f5e647ced7b52e86d251d340421a3c9f7c Mon Sep 17 00:00:00 2001 From: Alexis Lefebvre Date: Thu, 24 Dec 2020 18:24:15 +0100 Subject: [PATCH 03/18] chore: fix typo costumize -> costumize (#1194) --- frontend/src/i18n/ar.json | 4 ++-- frontend/src/i18n/en.json | 2 +- frontend/src/i18n/fr.json | 4 ++-- frontend/src/i18n/it.json | 4 ++-- frontend/src/i18n/ja.json | 4 ++-- frontend/src/i18n/pl.json | 4 ++-- frontend/src/i18n/pt-br.json | 4 ++-- frontend/src/i18n/ru.json | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/frontend/src/i18n/ar.json b/frontend/src/i18n/ar.json index 5a0e552d..be7a6459 100644 --- a/frontend/src/i18n/ar.json +++ b/frontend/src/i18n/ar.json @@ -124,7 +124,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Admin", "administrator": "Administrator", "allowCommands": "تنفيذ الأوامر", @@ -233,4 +233,4 @@ "downloadFile": "Download File", "downloadFolder": "Download Folder" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index a925c0c4..e4e9cae8 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -132,7 +132,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Admin", "administrator": "Administrator", "allowCommands": "Execute commands", diff --git a/frontend/src/i18n/fr.json b/frontend/src/i18n/fr.json index d6cd9c28..bbea4d29 100644 --- a/frontend/src/i18n/fr.json +++ b/frontend/src/i18n/fr.json @@ -124,7 +124,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Admin", "administrator": "Administrateur", "allowCommands": "Exécuter des commandes", @@ -233,4 +233,4 @@ "downloadFile": "Download File", "downloadFolder": "Download Folder" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/it.json b/frontend/src/i18n/it.json index bf171048..d3e2088b 100644 --- a/frontend/src/i18n/it.json +++ b/frontend/src/i18n/it.json @@ -124,7 +124,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Admin", "administrator": "Amministratore", "allowCommands": "Esegui comandi", @@ -233,4 +233,4 @@ "downloadFile": "Download File", "downloadFolder": "Download Folder" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/ja.json b/frontend/src/i18n/ja.json index 263a262f..e0265176 100644 --- a/frontend/src/i18n/ja.json +++ b/frontend/src/i18n/ja.json @@ -124,7 +124,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "管理者", "administrator": "管理者", "allowCommands": "コマンドの実行", @@ -233,4 +233,4 @@ "downloadFile": "Download File", "downloadFolder": "Download Folder" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/pl.json b/frontend/src/i18n/pl.json index 3efbbd52..b1d0064f 100644 --- a/frontend/src/i18n/pl.json +++ b/frontend/src/i18n/pl.json @@ -124,7 +124,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Admin", "administrator": "Administrator", "allowCommands": "Wykonaj polecenie", @@ -233,4 +233,4 @@ "downloadFile": "Download File", "downloadFolder": "Download Folder" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/pt-br.json b/frontend/src/i18n/pt-br.json index f8f8576a..f7e569f3 100644 --- a/frontend/src/i18n/pt-br.json +++ b/frontend/src/i18n/pt-br.json @@ -124,7 +124,7 @@ "documentation": "documentação", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Admin", "administrator": "Administrador", "allowCommands": "Executar comandos", @@ -233,4 +233,4 @@ "downloadFile": "Baixar arquivo", "downloadFolder": "Baixar pasta" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/ru.json b/frontend/src/i18n/ru.json index c544bcea..c86d9e78 100644 --- a/frontend/src/i18n/ru.json +++ b/frontend/src/i18n/ru.json @@ -124,7 +124,7 @@ "documentation": "documentation", "branding": "Branding", "disableExternalLinks": "Disable external links (except documentation)", - "brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", + "brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.", "admin": "Админ", "administrator": "Администратор", "allowCommands": "Запуск команд", @@ -233,4 +233,4 @@ "downloadFile": "Download File", "downloadFolder": "Download Folder" } -} \ No newline at end of file +} From 677bce376b024d9ff38f34e74243034fe5a1ec3c Mon Sep 17 00:00:00 2001 From: WeidiDeng Date: Fri, 25 Dec 2020 02:02:28 +0800 Subject: [PATCH 04/18] feat: add sharing management (#1178) (closes #1000) --- frontend/src/api/share.js | 4 ++ frontend/src/i18n/en.json | 3 + frontend/src/i18n/zh-cn.json | 3 + frontend/src/router/index.js | 6 ++ frontend/src/views/Settings.vue | 7 +- frontend/src/views/settings/Shares.vue | 98 ++++++++++++++++++++++++++ http/http.go | 1 + http/share.go | 29 ++++++++ share/storage.go | 42 +++++++++++ storage/bolt/share.go | 20 ++++++ 10 files changed, 210 insertions(+), 3 deletions(-) create mode 100644 frontend/src/views/settings/Shares.vue diff --git a/frontend/src/api/share.js b/frontend/src/api/share.js index e14c4e81..6f8a2a17 100644 --- a/frontend/src/api/share.js +++ b/frontend/src/api/share.js @@ -1,5 +1,9 @@ import { fetchURL, fetchJSON, removePrefix } from './utils' +export async function list() { + return fetchJSON('/api/shares') +} + export async function getHash(hash) { return fetchJSON(`/api/public/share/${hash}`) } diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index e4e9cae8..aaa2381f 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -157,6 +157,9 @@ "permissions": "Permissions", "permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n", "profileSettings": "Profile Settings", + "shareManagement": "Share Management", + "path": "Path", + "shareDuration": "Share Duration", "ruleExample1": "prevents the access to any dot file (such as .git, .gitignore) in every folder.\n", "ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.", "rules": "Rules", diff --git a/frontend/src/i18n/zh-cn.json b/frontend/src/i18n/zh-cn.json index 67564253..cb62494d 100644 --- a/frontend/src/i18n/zh-cn.json +++ b/frontend/src/i18n/zh-cn.json @@ -156,6 +156,9 @@ "permissions": "权限", "permissionsHelp": "您可以将该用户设置为管理员,也可以单独选择各项权限。如果选择了“管理员”,则其他的选项会被自动勾上,同时该用户可以管理其他用户。", "profileSettings": "个人设置", + "shareManagement": "分享管理", + "path": "路径", + "shareDuration": "分享期限", "ruleExample1": "阻止用户访问所有文件夹下任何以 . 开头的文件(隐藏文件, 例如: .git, .gitignore)。", "ruleExample2": "阻止用户访问其目录范围的根目录下名为 Caddyfile 的文件。", "rules": "规则", diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index 63a26b1a..07b9b124 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -9,6 +9,7 @@ import User from '@/views/settings/User' import Settings from '@/views/Settings' import GlobalSettings from '@/views/settings/Global' import ProfileSettings from '@/views/settings/Profile' +import Shares from '@/views/settings/Shares' import Error403 from '@/views/errors/403' import Error404 from '@/views/errors/404' import Error500 from '@/views/errors/500' @@ -67,6 +68,11 @@ const router = new Router({ name: 'Profile Settings', component: ProfileSettings }, + { + path: '/settings/shares', + name: 'Shares', + component: Shares + }, { path: '/settings/global', name: 'Global Settings', diff --git a/frontend/src/views/Settings.vue b/frontend/src/views/Settings.vue index 5b010243..6c563fc7 100644 --- a/frontend/src/views/Settings.vue +++ b/frontend/src/views/Settings.vue @@ -1,9 +1,10 @@