Added basic checks to ensure configured directories in lms.conf exist, fixes #828

This commit is contained in:
emeric
2026-03-08 21:30:11 +01:00
parent 3d5e2d3563
commit 4c7ad485bf
2 changed files with 47 additions and 7 deletions
+4 -4
View File
@@ -45,7 +45,7 @@ __Optional dependencies__:
__Notes__: __Notes__:
* `libstb-dev` can be replaced by `libgraphicsmagick++1-dev` (the latter will likely use more RAM) * `libstb-dev` can be replaced by `libgraphicsmagick++1-dev` (the latter will likely use more RAM)
You also need _Wt4_, which is not packaged on _Debian_. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html).</br> You also need _Wt4_, which is not packaged on _Debian_. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html).
### Build ### Build
Get the latest stable release and build it: Get the latest stable release and build it:
```sh ```sh
@@ -99,9 +99,9 @@ systemctl restart lms
# Deployment # Deployment
__Note__: don't forget to give the _lms_ user read access to the music directory you want to scan. __Note__: don't forget to give the _lms_ user read access to the music directory you want to scan.
## Configuration ## Configuration
_LMS_ uses a configuration file, installed by default in `/etc/lms.conf`. It is recommended to edit this file and change relevant settings (listen address, listen port, working directory, Subsonic API activation, deployment path, ...). _LMS_ uses a configuration file installed by default at `/etc/lms.conf`. It is recommended to edit this file and adjust the relevant settings like the working directory, Wt resources path, listen address, listen port, etc.
All other settings are set using the web interface (user management, scan settings, transcode settings, ...). All other settings are configured through the web interface (user management, scan settings, transcode settings, etc.).
If a setting is not present in the configuration file, a hardcoded default value is used (the same as in the [default configuration file](conf/lms.conf)) If a setting is not present in the configuration file, a hardcoded default value is used (the same as in the [default configuration file](conf/lms.conf)).
## Authentication backends ## Authentication backends
You can define which authentication backend to be used thanks to the `authentication-backend` option: You can define which authentication backend to be used thanks to the `authentication-backend` option:
* `internal` (default): _LMS_ uses an internal database to store users and their associated passwords (salted and hashed using [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt)). Only the admin user can create, edit or remove other users. * `internal` (default): _LMS_ uses an internal database to store users and their associated passwords (salted and hashed using [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt)). Only the admin user can create, edit or remove other users.
+43 -3
View File
@@ -17,6 +17,7 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>. * along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <filesystem>
#include <thread> #include <thread>
#include <Wt/WApplication.h> #include <Wt/WApplication.h>
@@ -110,19 +111,58 @@ namespace lms
throw core::LmsException{ "Invalid config value for 'jukebox-audio-backend'" }; throw core::LmsException{ "Invalid config value for 'jukebox-audio-backend'" };
} }
std::vector<std::string> generateWtConfig(std::string execPath) std::error_code checkDirectoryAccessible(const std::filesystem::path& dir)
{
std::error_code ec;
const std::filesystem::file_status status{ std::filesystem::status(dir, ec) };
if (ec)
return ec;
if (status.type() != std::filesystem::file_type::directory)
return std::make_error_code(std::errc::not_a_directory);
const std::filesystem::directory_iterator it{ dir, ec };
if (ec)
return ec;
if (it != std::filesystem::directory_iterator{})
{
it->status(ec);
if (ec)
return ec;
}
return {};
}
std::vector<std::string> generateWtConfig(const std::string& execPath)
{ {
core::IConfig& config{ *core::Service<core::IConfig>::get() }; core::IConfig& config{ *core::Service<core::IConfig>::get() };
std::vector<std::string> args; std::vector<std::string> args;
const std::filesystem::path wtConfigPath{ config.getPath("working-dir", "/var/lms") / "wt_config.xml" }; const std::filesystem::path workingDirectoryPath{ config.getPath("working-dir", "/var/lms") };
const std::filesystem::path wtConfigPath{ workingDirectoryPath / "wt_config.xml" };
const std::filesystem::path wtResourcesPath{ config.getPath("wt-resources", "/usr/share/Wt/resources") }; const std::filesystem::path wtResourcesPath{ config.getPath("wt-resources", "/usr/share/Wt/resources") };
const std::filesystem::path appRootPath{ config.getString("approot", "/usr/share/lms/approot") };
auto checkDirectoryExists{ [](const std::filesystem::path& directory, std::string_view settingName) {
std::string error;
const std::error_code ec{ checkDirectoryAccessible(directory) };
if (ec)
throw core::LmsException{ "Cannot access directory '" + directory.string() + "' specified in setting '" + std::string{ settingName } + "': " + ec.message() };
} };
checkDirectoryExists(workingDirectoryPath, "working-dir");
checkDirectoryExists(wtResourcesPath, "wt-resources");
checkDirectoryExists(appRootPath, "approot");
args.push_back(execPath); args.push_back(execPath);
args.push_back("--config=" + wtConfigPath.string()); args.push_back("--config=" + wtConfigPath.string());
args.push_back("--docroot=" + std::string{ config.getString("docroot", "/usr/share/lms/docroot/;/resources,/css,/images,/js,/favicon.ico") }); args.push_back("--docroot=" + std::string{ config.getString("docroot", "/usr/share/lms/docroot/;/resources,/css,/images,/js,/favicon.ico") });
args.push_back("--approot=" + std::string{ config.getString("approot", "/usr/share/lms/approot") }); args.push_back("--approot=" + appRootPath.string());
args.push_back("--deploy-path=" + std::string{ config.getString("deploy-path", "/") }); args.push_back("--deploy-path=" + std::string{ config.getString("deploy-path", "/") });
if (!wtResourcesPath.empty()) if (!wtResourcesPath.empty())
args.push_back("--resources-dir=" + wtResourcesPath.string()); args.push_back("--resources-dir=" + wtResourcesPath.string());