mirror of
https://github.com/m1k1o/neko.git
synced 2026-11-03 00:11:48 -06:00
fix(filetransfer): allow non-admin file uploads and downloads (#679)
* fix(filetransfer): remove auth.AdminsOnly middleware wrapper from routes * fix(filetransfer): add config option to allow non-admin users to download and upload files. * fix(filetransfer): implement user permissions for file download and upload in client. --------- Co-authored-by: Miroslav Šedivý <sedivy.miro@gmail.com>
This commit is contained in:
committed by
GitHub
parent
e843961c37
commit
613647c72c
@@ -109,9 +109,11 @@ type EmoteSend struct {
|
||||
}
|
||||
|
||||
type FileTransferList struct {
|
||||
Event string `json:"event"`
|
||||
Cwd string `json:"cwd"`
|
||||
Files []types.FileListItem `json:"files"`
|
||||
Event string `json:"event"`
|
||||
Cwd string `json:"cwd"`
|
||||
UserDownload bool `json:"user_download"`
|
||||
UserUpload bool `json:"user_upload"`
|
||||
Files []types.FileListItem `json:"files"`
|
||||
}
|
||||
|
||||
type Admin struct {
|
||||
|
||||
@@ -607,9 +607,11 @@ func (s *session) wsToClient(msg []byte) error {
|
||||
}
|
||||
|
||||
return s.toClient(&oldMessage.FileTransferList{
|
||||
Event: oldEvent.FILETRANSFER_LIST,
|
||||
Cwd: request.RootDir,
|
||||
Files: files,
|
||||
Event: oldEvent.FILETRANSFER_LIST,
|
||||
Cwd: request.RootDir,
|
||||
UserDownload: request.UserDownload,
|
||||
UserUpload: request.UserUpload,
|
||||
Files: files,
|
||||
})
|
||||
|
||||
// Screen Events
|
||||
|
||||
@@ -12,6 +12,8 @@ type Config struct {
|
||||
Enabled bool
|
||||
RootDir string
|
||||
RefreshInterval time.Duration
|
||||
UserDownload bool
|
||||
UserUpload bool
|
||||
}
|
||||
|
||||
func (Config) Init(cmd *cobra.Command) error {
|
||||
@@ -30,6 +32,16 @@ func (Config) Init(cmd *cobra.Command) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("filetransfer.user_download", false, "allow non-admin users to download files")
|
||||
if err := viper.BindPFlag("filetransfer.user_download", cmd.PersistentFlags().Lookup("filetransfer.user_download")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PersistentFlags().Bool("filetransfer.user_upload", false, "allow non-admin users to upload files")
|
||||
if err := viper.BindPFlag("filetransfer.user_upload", cmd.PersistentFlags().Lookup("filetransfer.user_upload")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// v2 config
|
||||
|
||||
cmd.PersistentFlags().Bool("file_transfer_enabled", false, "enable file transfer feature")
|
||||
@@ -50,6 +62,8 @@ func (s *Config) Set() {
|
||||
rootDir := viper.GetString("filetransfer.dir")
|
||||
s.RootDir = filepath.Clean(rootDir)
|
||||
s.RefreshInterval = viper.GetDuration("filetransfer.refresh_interval")
|
||||
s.UserDownload = viper.GetBool("filetransfer.user_download")
|
||||
s.UserUpload = viper.GetBool("filetransfer.user_upload")
|
||||
|
||||
// v2 config
|
||||
|
||||
|
||||
@@ -103,9 +103,11 @@ func (m *Manager) broadcastUpdate() {
|
||||
m.mu.RUnlock()
|
||||
|
||||
m.sessions.Broadcast(FILETRANSFER_UPDATE, Message{
|
||||
Enabled: m.config.Enabled,
|
||||
RootDir: m.config.RootDir,
|
||||
Files: fileList,
|
||||
Enabled: m.config.Enabled,
|
||||
RootDir: m.config.RootDir,
|
||||
UserDownload: m.config.UserDownload,
|
||||
UserUpload: m.config.UserUpload,
|
||||
Files: fileList,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -115,9 +117,11 @@ func (m *Manager) sendUpdate(session types.Session) {
|
||||
m.mu.RUnlock()
|
||||
|
||||
session.Send(FILETRANSFER_UPDATE, Message{
|
||||
Enabled: m.config.Enabled,
|
||||
RootDir: m.config.RootDir,
|
||||
Files: fileList,
|
||||
Enabled: m.config.Enabled,
|
||||
RootDir: m.config.RootDir,
|
||||
UserDownload: m.config.UserDownload,
|
||||
UserUpload: m.config.UserUpload,
|
||||
Files: fileList,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -208,8 +212,8 @@ func (m *Manager) Shutdown() error {
|
||||
}
|
||||
|
||||
func (m *Manager) Route(r types.Router) {
|
||||
r.With(auth.AdminsOnly).Get("/", m.downloadFileHandler)
|
||||
r.With(auth.AdminsOnly).Post("/", m.uploadFileHandler)
|
||||
r.Get("/", m.downloadFileHandler)
|
||||
r.Post("/", m.uploadFileHandler)
|
||||
}
|
||||
|
||||
func (m *Manager) WebSocketHandler(session types.Session, msg types.WebSocketMessage) bool {
|
||||
@@ -251,6 +255,10 @@ func (m *Manager) downloadFileHandler(w http.ResponseWriter, r *http.Request) er
|
||||
return utils.HttpForbidden("file transfer is disabled")
|
||||
}
|
||||
|
||||
if !session.Profile().IsAdmin && !m.config.UserDownload {
|
||||
return utils.HttpForbidden("file download is not allowed for non-admin users")
|
||||
}
|
||||
|
||||
filename := r.URL.Query().Get("filename")
|
||||
badChars, err := regexp.MatchString(`(?m)\.\.(?:\/|$)`, filename)
|
||||
if filename == "" || badChars || err != nil {
|
||||
@@ -285,6 +293,10 @@ func (m *Manager) uploadFileHandler(w http.ResponseWriter, r *http.Request) erro
|
||||
return utils.HttpForbidden("file transfer is disabled")
|
||||
}
|
||||
|
||||
if !session.Profile().IsAdmin && !m.config.UserUpload {
|
||||
return utils.HttpForbidden("file upload is not allowed for non-admin users")
|
||||
}
|
||||
|
||||
err = r.ParseMultipartForm(multipartFormMaxMemory)
|
||||
if err != nil || r.MultipartForm == nil {
|
||||
return utils.HttpBadRequest().
|
||||
|
||||
@@ -11,9 +11,11 @@ const (
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
RootDir string `json:"root_dir"`
|
||||
Files []Item `json:"files"`
|
||||
Enabled bool `json:"enabled"`
|
||||
RootDir string `json:"root_dir"`
|
||||
UserDownload bool `json:"user_download"`
|
||||
UserUpload bool `json:"user_upload"`
|
||||
Files []Item `json:"files"`
|
||||
}
|
||||
|
||||
type ItemType string
|
||||
|
||||
Reference in New Issue
Block a user