Removed not that useful config options

This commit is contained in:
emeric
2026-07-14 23:51:40 +02:00
parent 340711daad
commit cb6863fe1e
11 changed files with 22 additions and 92 deletions
+3 -9
View File
@@ -60,7 +60,7 @@ namespace lms::api::subsonic::utils
}
} // namespace
AuthenticationRequest parseAndValidateAuthenticationRequest(const Wt::Http::ParameterMap& parameters, const SubsonicResourceConfig& config)
AuthenticationRequest parseAndValidateAuthenticationRequest(const Wt::Http::ParameterMap& parameters)
{
const std::optional<std::string> user{ getParameterAs<std::string>(parameters, "u") };
const std::optional<std::string> password{ getParameterAs<std::string>(parameters, "p") };
@@ -70,12 +70,6 @@ namespace lms::api::subsonic::utils
const bool passwordAuthRequested{ password.has_value() };
const bool tokenAuthRequested{ token.has_value() || salt.has_value() };
const bool passwordAuthAttempted{ passwordAuthRequested || (user.has_value() && !tokenAuthRequested) };
if (!config.supportPasswordAuthentication && passwordAuthAttempted)
throw ProvidedAuthenticationMechanismNotSupportedError{};
if (!config.supportTokenAuthentication && tokenAuthRequested)
throw ProvidedAuthenticationMechanismNotSupportedError{};
if (passwordAuthRequested && tokenAuthRequested)
throw MultipleConflictingAuthenticationMechanismsProvidedError{};
@@ -130,9 +124,9 @@ namespace lms::api::subsonic::utils
throw UserNotAuthorizedError{};
}
db::UserId authenticateUser(const Wt::Http::Request& request, db::Session& session, const SubsonicResourceConfig& config)
db::UserId authenticateUser(const Wt::Http::Request& request, db::Session& session)
{
const AuthenticationRequest authRequest{ parseAndValidateAuthenticationRequest(request.getParameterMap(), config) };
const AuthenticationRequest authRequest{ parseAndValidateAuthenticationRequest(request.getParameterMap()) };
const auto clientAddress{ boost::asio::ip::make_address(request.clientAddress()) };
auto& authTokenService{ *core::Service<auth::IAuthTokenService>::get() };
+2 -4
View File
@@ -28,8 +28,6 @@
#include "database/objects/User.hpp"
#include "database/objects/UserId.hpp"
#include "SubsonicResourceConfig.hpp"
namespace lms::db
{
class Session;
@@ -58,7 +56,7 @@ namespace lms::api::subsonic::utils
using AuthenticationRequest = std::variant<PasswordAuthentication, TokenAuthentication, ApiKeyAuthentication>;
// Throws on error
AuthenticationRequest parseAndValidateAuthenticationRequest(const Wt::Http::ParameterMap& parameters, const SubsonicResourceConfig& config);
AuthenticationRequest parseAndValidateAuthenticationRequest(const Wt::Http::ParameterMap& parameters);
// Checks token == hex(md5(apiKey + salt)), case insensitive
bool checkAuthToken(std::string_view apiKey, std::string_view salt, std::string_view token);
@@ -67,5 +65,5 @@ namespace lms::api::subsonic::utils
db::User::pointer getUserFromUserId(db::Session& session, db::UserId userId);
// Throws on error
db::UserId authenticateUser(const Wt::Http::Request& request, db::Session& session, const SubsonicResourceConfig& config);
db::UserId authenticateUser(const Wt::Http::Request& request, db::Session& session);
} // namespace lms::api::subsonic::utils
+1 -1
View File
@@ -415,6 +415,6 @@ namespace lms::api::subsonic
db::UserId SubsonicResource::authenticateUser(const Wt::Http::Request& request)
{
return utils::authenticateUser(request, _db.getTLSSession(), _config);
return utils::authenticateUser(request, _db.getTLSSession());
}
} // namespace lms::api::subsonic
@@ -43,8 +43,6 @@ namespace lms::api::subsonic
{
return SubsonicResourceConfig{
.openSubsonicDisabledClients = readOpenSubsonicDisabledClients(config),
.supportPasswordAuthentication = config.getBool("api-subsonic-support-password-auth", true),
.supportTokenAuthentication = config.getBool("api-subsonic-support-token-auth", true)
};
}
} // namespace lms::api::subsonic
@@ -32,8 +32,6 @@ namespace lms::api::subsonic
struct SubsonicResourceConfig
{
std::unordered_set<std::string> openSubsonicDisabledClients;
bool supportPasswordAuthentication;
bool supportTokenAuthentication;
};
SubsonicResourceConfig readSubsonicResourceConfig(core::IConfig& _config);
@@ -47,7 +47,6 @@ namespace lms::api::subsonic
ServerMustUpgrade = 30,
WrongUsernameOrPassword = 40,
TokenAuthenticationNotSupportedForLDAPUsers = 41,
ProvidedAuthenticationMechanismNotSupported = 42,
MultipleConflictingAuthenticationMechanismsProvided = 43,
InvalidAPIkey = 44,
UserNotAuthorized = 50,
@@ -131,19 +130,6 @@ namespace lms::api::subsonic
std::string getMessage() const override { return "Token authentication not supported for LDAP users."; }
};
class ProvidedAuthenticationMechanismNotSupportedError : public Error
{
public:
ProvidedAuthenticationMechanismNotSupportedError()
: Error{ Code::ProvidedAuthenticationMechanismNotSupported } {}
private:
std::string getMessage() const override
{
return "Provided authentication mechanism not supported.";
}
};
class MultipleConflictingAuthenticationMechanismsProvidedError : public Error
{
public:
+16 -44
View File
@@ -24,27 +24,6 @@
namespace lms::api::subsonic::utils::tests
{
namespace
{
const SubsonicResourceConfig bothMechanismsSupported{
.openSubsonicDisabledClients = {},
.supportPasswordAuthentication = true,
.supportTokenAuthentication = true,
};
const SubsonicResourceConfig noneSupported{
.openSubsonicDisabledClients = {},
.supportPasswordAuthentication = false,
.supportTokenAuthentication = false,
};
const SubsonicResourceConfig passwordUnsupported{
.openSubsonicDisabledClients = {},
.supportPasswordAuthentication = false,
.supportTokenAuthentication = true,
};
} // namespace
// Reference values from the Subsonic API documentation (apiKey = "sesame", salt = "c19b2d")
TEST(AuthUtils, checkAuthToken_ValidToken)
{
@@ -73,66 +52,59 @@ namespace lms::api::subsonic::utils::tests
TEST(AuthUtils, parseAndValidateAuthenticationRequest_apiKeyOnly)
{
const auto request{ parseAndValidateAuthenticationRequest({ { "apiKey", { "apiKey" } } }, bothMechanismsSupported) };
const auto request{ parseAndValidateAuthenticationRequest({ { "apiKey", { "apiKey" } } }) };
ASSERT_TRUE(std::holds_alternative<ApiKeyAuthentication>(request));
EXPECT_EQ(std::get<ApiKeyAuthentication>(request).apiKey, "apiKey");
EXPECT_THROW(parseAndValidateAuthenticationRequest({}, bothMechanismsSupported), RequiredParameterMissingError);
EXPECT_THROW(parseAndValidateAuthenticationRequest({}), RequiredParameterMissingError);
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_password)
{
const auto request{ parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } } }, bothMechanismsSupported) };
const auto request{ parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } } }) };
ASSERT_TRUE(std::holds_alternative<PasswordAuthentication>(request));
EXPECT_EQ(std::get<PasswordAuthentication>(request).user, "user");
EXPECT_EQ(std::get<PasswordAuthentication>(request).password, "password");
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "p", { "password" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing u
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing p
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "p", { "password" } } }), RequiredParameterMissingError); // missing u
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } } }), RequiredParameterMissingError); // missing p
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_token)
{
const auto request{ parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } }, { "s", { "salt" } } }, bothMechanismsSupported) };
const auto request{ parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } }, { "s", { "salt" } } }) };
ASSERT_TRUE(std::holds_alternative<TokenAuthentication>(request));
EXPECT_EQ(std::get<TokenAuthentication>(request).user, "user");
EXPECT_EQ(std::get<TokenAuthentication>(request).token, "token");
EXPECT_EQ(std::get<TokenAuthentication>(request).salt, "salt");
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "t", { "token" } }, { "s", { "salt" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing u
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "s", { "salt" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing t
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing s
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "t", { "token" } }, { "s", { "salt" } } }), RequiredParameterMissingError); // missing u
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "s", { "salt" } } }), RequiredParameterMissingError); // missing t
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } } }), RequiredParameterMissingError); // missing s
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_conflicts)
{
// password + token
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } }, { "t", { "token" } }, { "s", { "salt" } } }, bothMechanismsSupported), MultipleConflictingAuthenticationMechanismsProvidedError);
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } }, { "t", { "token" } }, { "s", { "salt" } } }), MultipleConflictingAuthenticationMechanismsProvidedError);
// apiKey + password
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } }, { "apiKey", { "apiKey" } } }, bothMechanismsSupported), MultipleConflictingAuthenticationMechanismsProvidedError);
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } }, { "apiKey", { "apiKey" } } }), MultipleConflictingAuthenticationMechanismsProvidedError);
// apiKey + token
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } }, { "s", { "salt" } }, { "apiKey", { "apiKey" } } }, bothMechanismsSupported), MultipleConflictingAuthenticationMechanismsProvidedError);
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } }, { "s", { "salt" } }, { "apiKey", { "apiKey" } } }), MultipleConflictingAuthenticationMechanismsProvidedError);
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_mechanismNotSupported)
TEST(AuthUtils, parseAndValidateAuthenticationRequest_usernameOnlyRequiresPassword)
{
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "p", { "password" } } }, noneSupported), ProvidedAuthenticationMechanismNotSupportedError);
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } }, { "t", { "token" } }, { "s", { "salt" } } }, noneSupported), ProvidedAuthenticationMechanismNotSupportedError);
EXPECT_NO_THROW(parseAndValidateAuthenticationRequest({ { "apiKey", { "apiKey" } } }, noneSupported)); // apiKey is unaffected by these two flags
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_usernameOnlyTreatedAsPasswordAttempt)
{
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } } }, passwordUnsupported), ProvidedAuthenticationMechanismNotSupportedError);
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "u", { "user" } } }), RequiredParameterMissingError); // missing p
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_apiKeyWithPartialPassword)
{
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "p", { "password" } }, { "apiKey", { "apiKey" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing u
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "p", { "password" } }, { "apiKey", { "apiKey" } } }), RequiredParameterMissingError); // missing u
}
TEST(AuthUtils, parseAndValidateAuthenticationRequest_apiKeyWithPartialToken)
{
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "s", { "salt" } }, { "apiKey", { "apiKey" } } }, bothMechanismsSupported), RequiredParameterMissingError); // missing u
EXPECT_THROW(parseAndValidateAuthenticationRequest({ { "s", { "salt" } }, { "apiKey", { "apiKey" } } }), RequiredParameterMissingError); // missing u
}
} // namespace lms::api::subsonic::utils::tests
@@ -27,7 +27,6 @@
#include <Wt/WString.h>
#include <Wt/WTemplateFormView.h>
#include "core/IConfig.hpp"
#include "core/Service.hpp"
#include "core/UUID.hpp"
@@ -185,11 +184,6 @@ namespace lms::ui
auto* t{ addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Settings.subsonic.template.key")) };
t->addFunction("tr", &Wt::WTemplate::Functions::tr);
{
core::IConfig& config{ *core::Service<core::IConfig>::get() };
t->setCondition("if-has-subsonic-token-usage", config.getBool("api-subsonic-support-password-auth", true) || config.getBool("api-subsonic-support-token-auth", true));
}
std::string currentToken;
{
auto transaction{ LmsApp->getDbSession().createReadTransaction() };