mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-01 19:47:37 +03:00
Make server unix socket file permission configurable via flag UnixSocketPerm (#2763)
* feat(any): Add flag unixsocketperm with default 0017 - #2625 Signed-off-by: johannesengl <hello@johannesengl.com> * feat(server): Update unix socket file perm based on config - #2625 Signed-off-by: johannesengl <hello@johannesengl.com> * Fix default value of socket. * Refactor unix socket file creation. * Remove misplaced comment --------- Signed-off-by: johannesengl <hello@johannesengl.com> Co-authored-by: Caio Cotts <caio@cotts.com.br> Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
8570773b90
commit
8f03454312
4 changed files with 78 additions and 6 deletions
|
@ -183,6 +183,7 @@ func init() {
|
|||
rootCmd.Flags().IntP("port", "p", viper.GetInt("port"), "HTTP port Navidrome will listen to")
|
||||
rootCmd.Flags().String("baseurl", viper.GetString("baseurl"), "base URL to configure Navidrome behind a proxy (ex: /music or http://my.server.com)")
|
||||
rootCmd.Flags().String("tlscert", viper.GetString("tlscert"), "optional path to a TLS cert file (enables HTTPS listening)")
|
||||
rootCmd.Flags().String("unixsocketperm", viper.GetString("unixsocketperm"), "optional file permission for the unix socket")
|
||||
rootCmd.Flags().String("tlskey", viper.GetString("tlskey"), "optional path to a TLS key file (enables HTTPS listening)")
|
||||
|
||||
rootCmd.Flags().Duration("sessiontimeout", viper.GetDuration("sessiontimeout"), "how long Navidrome will wait before closing web ui idle sessions")
|
||||
|
@ -199,6 +200,7 @@ func init() {
|
|||
_ = viper.BindPFlag("address", rootCmd.Flags().Lookup("address"))
|
||||
_ = viper.BindPFlag("port", rootCmd.Flags().Lookup("port"))
|
||||
_ = viper.BindPFlag("tlscert", rootCmd.Flags().Lookup("tlscert"))
|
||||
_ = viper.BindPFlag("unixsocketperm", rootCmd.Flags().Lookup("unixsocketperm"))
|
||||
_ = viper.BindPFlag("tlskey", rootCmd.Flags().Lookup("tlskey"))
|
||||
_ = viper.BindPFlag("baseurl", rootCmd.Flags().Lookup("baseurl"))
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ type configOptions struct {
|
|||
ConfigFile string
|
||||
Address string
|
||||
Port int
|
||||
UnixSocketPerm string
|
||||
MusicFolder string
|
||||
DataFolder string
|
||||
CacheFolder string
|
||||
|
@ -275,6 +276,7 @@ func init() {
|
|||
viper.SetDefault("loglevel", "info")
|
||||
viper.SetDefault("address", "0.0.0.0")
|
||||
viper.SetDefault("port", 4533)
|
||||
viper.SetDefault("unixsocketperm", "0660")
|
||||
viper.SetDefault("sessiontimeout", consts.DefaultSessionTimeout)
|
||||
viper.SetDefault("scaninterval", -1)
|
||||
viper.SetDefault("scanschedule", "@every 1m")
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -71,13 +72,9 @@ func (s *Server) Run(ctx context.Context, addr string, port int, tlsCert string,
|
|||
var err error
|
||||
if strings.HasPrefix(addr, "unix:") {
|
||||
socketPath := strings.TrimPrefix(addr, "unix:")
|
||||
// Remove the socket file if it already exists
|
||||
if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) {
|
||||
return fmt.Errorf("error removing previous unix socket file: %w", err)
|
||||
}
|
||||
listener, err = net.Listen("unix", socketPath)
|
||||
listener, err = createUnixSocketFile(socketPath, conf.Server.UnixSocketPerm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating unix socket listener: %w", err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
addr = fmt.Sprintf("%s:%d", addr, port)
|
||||
|
@ -136,6 +133,28 @@ func (s *Server) Run(ctx context.Context, addr string, port int, tlsCert string,
|
|||
return nil
|
||||
}
|
||||
|
||||
func createUnixSocketFile(socketPath string, socketPerm string) (net.Listener, error) {
|
||||
// Remove the socket file if it already exists
|
||||
if err := os.Remove(socketPath); err != nil && !os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("error removing previous unix socket file: %w", err)
|
||||
}
|
||||
// Create listener
|
||||
listener, err := net.Listen("unix", socketPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating unix socket listener: %w", err)
|
||||
}
|
||||
// Converts the socketPerm to uint and updates the permission of the unix socket file
|
||||
perm, err := strconv.ParseUint(socketPerm, 8, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing unix socket file permissions: %w", err)
|
||||
}
|
||||
err = os.Chmod(socketPath, os.FileMode(perm))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error updating permission of unix socket file: %w", err)
|
||||
}
|
||||
return listener, nil
|
||||
}
|
||||
|
||||
func (s *Server) initRoutes() {
|
||||
s.appRoot = path.Join(conf.Server.BasePath, consts.URLPathUI)
|
||||
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/navidrome/navidrome/conf"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
|
@ -58,3 +61,49 @@ var _ = Describe("AbsoluteURL", func() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("createUnixSocketFile", func() {
|
||||
var socketPath string
|
||||
|
||||
BeforeEach(func() {
|
||||
tempDir, _ := os.MkdirTemp("", "create_unix_socket_file_test")
|
||||
socketPath = filepath.Join(tempDir, "test.sock")
|
||||
DeferCleanup(func() {
|
||||
_ = os.RemoveAll(tempDir)
|
||||
})
|
||||
})
|
||||
|
||||
When("unixSocketPerm is valid", func() {
|
||||
It("updates the permission of the unix socket file and returns nil", func() {
|
||||
_, err := createUnixSocketFile(socketPath, "0777")
|
||||
fileInfo, _ := os.Stat(socketPath)
|
||||
actualPermission := fileInfo.Mode().Perm()
|
||||
|
||||
Expect(actualPermission).To(Equal(os.FileMode(0777)))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
When("unixSocketPerm is invalid", func() {
|
||||
It("returns an error", func() {
|
||||
_, err := createUnixSocketFile(socketPath, "invalid")
|
||||
Expect(err).To(HaveOccurred())
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
When("file already exists", func() {
|
||||
It("recreates the file as a socket with the right permissions", func() {
|
||||
_, err := os.Create(socketPath)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(os.Chmod(socketPath, os.FileMode(0777))).To(Succeed())
|
||||
|
||||
_, err = createUnixSocketFile(socketPath, "0600")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
fileInfo, _ := os.Stat(socketPath)
|
||||
Expect(fileInfo.Mode().Perm()).To(Equal(os.FileMode(0600)))
|
||||
Expect(fileInfo.Mode().Type()).To(Equal(fs.ModeSocket))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue