Removed not that useful config options
This commit is contained in:
@@ -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() };
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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() };
|
||||
|
||||
Reference in New Issue
Block a user