From 617139c2f4d28eb252790d321b016980edf0033b Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 3 Oct 2021 14:35:25 +0200 Subject: [PATCH] Removed session parameters from auth services --- src/libs/auth/impl/AuthServiceBase.cpp | 32 ++++++++++++++----- src/libs/auth/impl/AuthServiceBase.hpp | 12 +++++-- src/libs/auth/impl/AuthTokenService.cpp | 27 +++++++++------- src/libs/auth/impl/AuthTokenService.hpp | 10 +++--- src/libs/auth/impl/EnvService.cpp | 4 +-- src/libs/auth/impl/PasswordServiceBase.cpp | 22 ++++++------- src/libs/auth/impl/PasswordServiceBase.hpp | 14 ++++---- .../http-headers/HttpHeadersEnvService.cpp | 17 +++++----- .../http-headers/HttpHeadersEnvService.hpp | 6 ++-- .../impl/internal/InternalPasswordService.cpp | 14 ++++---- .../impl/internal/InternalPasswordService.hpp | 8 ++--- src/libs/auth/impl/pam/PAMPasswordService.cpp | 4 +-- src/libs/auth/impl/pam/PAMPasswordService.hpp | 9 ++---- .../auth/include/auth/IAuthTokenService.hpp | 10 +++--- src/libs/auth/include/auth/IEnvService.hpp | 7 ++-- .../auth/include/auth/IPasswordService.hpp | 13 ++++---- src/libs/subsonic/impl/SubsonicResource.cpp | 23 ++++++------- src/libs/subsonic/impl/SubsonicResource.hpp | 2 +- src/lms/main.cpp | 6 ++-- src/lms/ui/Auth.cpp | 5 ++- src/lms/ui/LmsApplication.cpp | 2 +- src/lms/ui/SettingsView.cpp | 2 +- src/lms/ui/admin/InitWizardView.cpp | 2 +- src/lms/ui/admin/UserView.cpp | 4 +-- src/lms/ui/common/PasswordValidator.cpp | 1 - 25 files changed, 135 insertions(+), 121 deletions(-) diff --git a/src/libs/auth/impl/AuthServiceBase.cpp b/src/libs/auth/impl/AuthServiceBase.cpp index b4ab450a..6e0d0589 100644 --- a/src/libs/auth/impl/AuthServiceBase.cpp +++ b/src/libs/auth/impl/AuthServiceBase.cpp @@ -19,25 +19,33 @@ #include "AuthServiceBase.hpp" +#include "database/Db.hpp" #include "database/Session.hpp" #include "database/User.hpp" #include "utils/Logger.hpp" namespace Auth { - Database::UserId - AuthServiceBase::getOrCreateUser(Database::Session& session, std::string_view loginName) + using namespace Database; + + AuthServiceBase::AuthServiceBase(Db& db) + : _db {db} + {} + + UserId + AuthServiceBase::getOrCreateUser(std::string_view loginName) { + Session& session {getDbSession()}; auto transaction {session.createUniqueTransaction()}; - Database::User::pointer user {Database::User::getByLoginName(session, loginName)}; + User::pointer user {User::getByLoginName(session, loginName)}; if (!user) { - const Database::UserType type {Database::User::getCount(session) == 0 ? Database::UserType::ADMIN : Database::UserType::REGULAR}; + const UserType type {User::getCount(session) == 0 ? UserType::ADMIN : UserType::REGULAR}; - LMS_LOG(AUTH, DEBUG) << "Creating user '" << loginName << "', admin = " << (type == Database::UserType::ADMIN); + LMS_LOG(AUTH, DEBUG) << "Creating user '" << loginName << "', admin = " << (type == UserType::ADMIN); - user = Database::User::create(session, loginName); + user = User::create(session, loginName); user.modify()->setType(type); } @@ -45,11 +53,19 @@ namespace Auth } void - AuthServiceBase::onUserAuthenticated(Database::Session& session, Database::UserId userId) + AuthServiceBase::onUserAuthenticated(UserId userId) { + Session& session {getDbSession()}; auto transaction {session.createUniqueTransaction()}; - Database::User::pointer user {Database::User::getById(session, userId)}; + + User::pointer user {User::getById(session, userId)}; if (user) user.modify()->setLastLogin(Wt::WDateTime::currentDateTime()); } + + Session& + AuthServiceBase::getDbSession() + { + return _db.getTLSSession(); + } } diff --git a/src/libs/auth/impl/AuthServiceBase.hpp b/src/libs/auth/impl/AuthServiceBase.hpp index 032d8f84..81acba59 100644 --- a/src/libs/auth/impl/AuthServiceBase.hpp +++ b/src/libs/auth/impl/AuthServiceBase.hpp @@ -24,6 +24,7 @@ namespace Database { + class Db; class Session; } @@ -32,7 +33,14 @@ namespace Auth class AuthServiceBase { protected: - Database::UserId getOrCreateUser(Database::Session& session, std::string_view loginName); - void onUserAuthenticated(Database::Session& session, Database::UserId userId); + AuthServiceBase(Database::Db& db); + + Database::UserId getOrCreateUser(std::string_view loginName); + void onUserAuthenticated(Database::UserId userId); + + Database::Session& getDbSession(); + + private: + Database::Db& _db; }; } diff --git a/src/libs/auth/impl/AuthTokenService.cpp b/src/libs/auth/impl/AuthTokenService.cpp index 89ad8870..f6f305b6 100644 --- a/src/libs/auth/impl/AuthTokenService.cpp +++ b/src/libs/auth/impl/AuthTokenService.cpp @@ -32,24 +32,27 @@ namespace Auth { - std::unique_ptr createAuthTokenService(std::size_t maxThrottlerEntries) + std::unique_ptr createAuthTokenService(Database::Db& db, std::size_t maxThrottlerEntries) { - return std::make_unique(maxThrottlerEntries); + return std::make_unique(db, maxThrottlerEntries); } static const Wt::Auth::SHA1HashFunction sha1Function; - AuthTokenService::AuthTokenService(std::size_t maxThrottlerEntries) - : _loginThrottler {maxThrottlerEntries} + AuthTokenService::AuthTokenService(Database::Db& db, std::size_t maxThrottlerEntries) + : AuthServiceBase {db} + , _loginThrottler {maxThrottlerEntries} { } std::string - AuthTokenService::createAuthToken(Database::Session& session, Database::UserId userId, const Wt::WDateTime& expiry) + AuthTokenService::createAuthToken(Database::UserId userId, const Wt::WDateTime& expiry) { const std::string secret {Wt::WRandom::generateId(32)}; const std::string secretHash {sha1Function.compute(secret, {})}; + Database::Session& session {getDbSession()}; + auto transaction {session.createUniqueTransaction()}; Database::User::pointer user {Database::User::getById(session, userId)}; @@ -66,12 +69,12 @@ namespace Auth return secret; } - static std::optional - processAuthToken(Database::Session& session, std::string_view secret) + AuthTokenService::processAuthToken(std::string_view secret) { const std::string secretHash {sha1Function.compute(std::string {secret}, {})}; + Database::Session& session {getDbSession()}; auto transaction {session.createUniqueTransaction()}; Database::AuthToken::pointer authToken {Database::AuthToken::getByValue(session, secretHash)}; @@ -93,7 +96,7 @@ namespace Auth } AuthTokenService::AuthTokenProcessResult - AuthTokenService::processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, std::string_view tokenValue) + AuthTokenService::processAuthToken(const boost::asio::ip::address& clientAddress, std::string_view tokenValue) { // Do not waste too much resource on brute force attacks (optim) { @@ -103,7 +106,7 @@ namespace Auth return AuthTokenProcessResult {AuthTokenProcessResult::State::Throttled}; } - auto res {Auth::processAuthToken(session, tokenValue)}; + auto res {processAuthToken(tokenValue)}; { std::unique_lock lock {_mutex}; @@ -117,14 +120,16 @@ namespace Auth } _loginThrottler.onGoodClientAttempt(clientAddress); - onUserAuthenticated(session, res->userId); + onUserAuthenticated(res->userId); return AuthTokenProcessResult {AuthTokenProcessResult::State::Granted, std::move(*res)}; } } void - AuthTokenService::clearAuthTokens(Database::Session& session, Database::UserId userId) + AuthTokenService::clearAuthTokens(Database::UserId userId) { + Database::Session& session {getDbSession()}; + auto transaction {session.createUniqueTransaction()}; Database::User::pointer user {Database::User::getById(session, userId)}; diff --git a/src/libs/auth/impl/AuthTokenService.hpp b/src/libs/auth/impl/AuthTokenService.hpp index 088f82ee..8825a3d3 100644 --- a/src/libs/auth/impl/AuthTokenService.hpp +++ b/src/libs/auth/impl/AuthTokenService.hpp @@ -35,7 +35,7 @@ namespace Auth class AuthTokenService : public IAuthTokenService, public AuthServiceBase { public: - AuthTokenService(std::size_t maxThrottlerEntries); + AuthTokenService(Database::Db& db, std::size_t maxThrottlerEntries); AuthTokenService(const AuthTokenService&) = delete; AuthTokenService& operator=(const AuthTokenService&) = delete; @@ -43,9 +43,11 @@ namespace Auth AuthTokenService& operator=(AuthTokenService&&) = delete; private: - AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, std::string_view tokenValue) override; - std::string createAuthToken(Database::Session& session, Database::UserId userId, const Wt::WDateTime& expiry) override; - void clearAuthTokens(Database::Session& session, Database::UserId userId) override; + AuthTokenProcessResult processAuthToken(const boost::asio::ip::address& clientAddress, std::string_view tokenValue) override; + std::string createAuthToken(Database::UserId userId, const Wt::WDateTime& expiry) override; + void clearAuthTokens(Database::UserId userId) override; + + std::optional processAuthToken(std::string_view secret); std::shared_mutex _mutex; LoginThrottler _loginThrottler; diff --git a/src/libs/auth/impl/EnvService.cpp b/src/libs/auth/impl/EnvService.cpp index 5ca529da..12de9858 100644 --- a/src/libs/auth/impl/EnvService.cpp +++ b/src/libs/auth/impl/EnvService.cpp @@ -25,10 +25,10 @@ namespace Auth { std::unique_ptr - createEnvService(std::string_view backendName) + createEnvService(std::string_view backendName, Database::Db& db) { if (backendName == "http-headers") - return std::make_unique(); + return std::make_unique(db); throw Exception {"Authentication backend '" + std::string {backendName} + "' is not supported!"}; } diff --git a/src/libs/auth/impl/PasswordServiceBase.cpp b/src/libs/auth/impl/PasswordServiceBase.cpp index 02a9c63d..3b230503 100644 --- a/src/libs/auth/impl/PasswordServiceBase.cpp +++ b/src/libs/auth/impl/PasswordServiceBase.cpp @@ -39,29 +39,27 @@ namespace Auth static const Wt::Auth::SHA1HashFunction sha1Function; std::unique_ptr - createPasswordService(std::string_view passwordAuthenticationBackend, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService) + createPasswordService(std::string_view passwordAuthenticationBackend, Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService) { if (passwordAuthenticationBackend == "internal") - return std::make_unique(maxThrottlerEntries, authTokenService); + return std::make_unique(db, maxThrottlerEntries, authTokenService); #ifdef LMS_SUPPORT_PAM else if (passwordAuthenticationBackend == "pam") - return std::make_unique(maxThrottlerEntries, authTokenService); + return std::make_unique(db, maxThrottlerEntries, authTokenService); #endif // LMS_SUPPORT_PAM throw Exception {"Authentication backend '" + std::string {passwordAuthenticationBackend} + "' is not supported!"}; } - PasswordServiceBase::PasswordServiceBase(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService) - : _loginThrottler {maxThrottlerEntries} + PasswordServiceBase::PasswordServiceBase(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService) + : AuthServiceBase {db} + , _loginThrottler {maxThrottlerEntries} , _authTokenService {authTokenService} { } PasswordServiceBase::CheckResult - PasswordServiceBase::checkUserPassword(Database::Session& session, - const boost::asio::ip::address& clientAddress, - std::string_view loginName, - std::string_view password) + PasswordServiceBase::checkUserPassword(const boost::asio::ip::address& clientAddress, std::string_view loginName, std::string_view password) { LMS_LOG(AUTH, DEBUG) << "Checking password for user '" << loginName << "'"; @@ -73,7 +71,7 @@ namespace Auth return {CheckResult::State::Throttled}; } - const bool match {checkUserPassword(session, loginName, password)}; + const bool match {checkUserPassword(loginName, password)}; { std::unique_lock lock {_mutex}; @@ -84,8 +82,8 @@ namespace Auth { _loginThrottler.onGoodClientAttempt(clientAddress); - const Database::UserId userId {getOrCreateUser(session, loginName)}; - onUserAuthenticated(session, userId); + const Database::UserId userId {getOrCreateUser(loginName)}; + onUserAuthenticated(userId); return {CheckResult::State::Granted, userId}; } else diff --git a/src/libs/auth/impl/PasswordServiceBase.hpp b/src/libs/auth/impl/PasswordServiceBase.hpp index 8b5bc3dd..f575e4e1 100644 --- a/src/libs/auth/impl/PasswordServiceBase.hpp +++ b/src/libs/auth/impl/PasswordServiceBase.hpp @@ -27,6 +27,7 @@ namespace Database { + class Db; class Session; } @@ -36,7 +37,7 @@ namespace Auth class PasswordServiceBase : public IPasswordService, public AuthServiceBase { public: - PasswordServiceBase(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService); + PasswordServiceBase(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService); PasswordServiceBase(const PasswordServiceBase&) = delete; PasswordServiceBase& operator=(const PasswordServiceBase&) = delete; @@ -47,14 +48,11 @@ namespace Auth IAuthTokenService& getAuthTokenService() { return _authTokenService; } private: - virtual bool checkUserPassword(Database::Session& session, - std::string_view loginName, - std::string_view password) = 0; + virtual bool checkUserPassword(std::string_view loginName, std::string_view password) = 0; - CheckResult checkUserPassword(Database::Session& session, - const boost::asio::ip::address& clientAddress, - std::string_view loginName, - std::string_view password) override; + CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress, + std::string_view loginName, + std::string_view password) override; std::shared_mutex _mutex; LoginThrottler _loginThrottler; diff --git a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp index 3db1fb4a..951925ec 100644 --- a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp +++ b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp @@ -28,14 +28,15 @@ namespace Auth { - HttpHeadersEnvService::HttpHeadersEnvService() - : _fieldName {Service::get()->getString("http-headers-login-field", "X-Forwarded-User")} + HttpHeadersEnvService::HttpHeadersEnvService(Database::Db& db) + : AuthServiceBase {db} + , _fieldName {Service::get()->getString("http-headers-login-field", "X-Forwarded-User")} { LMS_LOG(AUTH, INFO) << "Using http header field = '" << _fieldName << "'"; } HttpHeadersEnvService::CheckResult - HttpHeadersEnvService::processEnv(Database::Session& session, const Wt::WEnvironment& env) + HttpHeadersEnvService::processEnv(const Wt::WEnvironment& env) { const std::string loginName {env.headerValue(_fieldName)}; if (loginName.empty()) @@ -43,13 +44,13 @@ namespace Auth LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header"; - const Database::UserId userId {getOrCreateUser(session, loginName)}; - onUserAuthenticated(session, userId); + const Database::UserId userId {getOrCreateUser(loginName)}; + onUserAuthenticated(userId); return {CheckResult::State::Granted, userId}; } HttpHeadersEnvService::CheckResult - HttpHeadersEnvService::processRequest(Database::Session& session, const Wt::Http::Request& request) + HttpHeadersEnvService::processRequest(const Wt::Http::Request& request) { const std::string loginName {request.headerValue(_fieldName)}; if (loginName.empty()) @@ -57,8 +58,8 @@ namespace Auth LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header"; - const Database::UserId userId {getOrCreateUser(session, loginName)}; - onUserAuthenticated(session, userId); + const Database::UserId userId {getOrCreateUser(loginName)}; + onUserAuthenticated(userId); return {CheckResult::State::Granted, userId}; } diff --git a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp index 1295f182..5c44b9fb 100644 --- a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp +++ b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp @@ -27,11 +27,11 @@ namespace Auth class HttpHeadersEnvService : public IEnvService, public AuthServiceBase { public: - HttpHeadersEnvService(); + HttpHeadersEnvService(Database::Db& db); private: - CheckResult processEnv(Database::Session& session, const Wt::WEnvironment& env) override; - CheckResult processRequest(Database::Session& session, const Wt::Http::Request& request) override; + CheckResult processEnv(const Wt::WEnvironment& env) override; + CheckResult processRequest(const Wt::Http::Request& request) override; std::string _fieldName; }; diff --git a/src/libs/auth/impl/internal/InternalPasswordService.cpp b/src/libs/auth/impl/internal/InternalPasswordService.cpp index a021dd3c..96a6c34a 100644 --- a/src/libs/auth/impl/internal/InternalPasswordService.cpp +++ b/src/libs/auth/impl/internal/InternalPasswordService.cpp @@ -29,8 +29,8 @@ namespace Auth { - InternalPasswordService::InternalPasswordService(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService) - : PasswordServiceBase {maxThrottlerEntries, authTokenService} + InternalPasswordService::InternalPasswordService(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService) + : PasswordServiceBase {db, maxThrottlerEntries, authTokenService} { _validator.setMinimumLength(Wt::Auth::PasswordStrengthType::OneCharClass, 4); _validator.setMinimumLength(Wt::Auth::PasswordStrengthType::TwoCharClass, 4); @@ -42,14 +42,13 @@ namespace Auth } bool - InternalPasswordService::checkUserPassword(Database::Session& session, - std::string_view loginName, - std::string_view password) + InternalPasswordService::checkUserPassword(std::string_view loginName, std::string_view password) { LMS_LOG(AUTH, DEBUG) << "Checking internal password for user '" << loginName << "'"; Database::User::PasswordHash passwordHash; { + Database::Session& session {getDbSession()}; auto transaction {session.createSharedTransaction()}; const Database::User::pointer user {Database::User::getByLoginName(session, loginName)}; @@ -96,10 +95,11 @@ namespace Auth } void - InternalPasswordService::setPassword(Database::Session& session, Database::UserId userId, std::string_view newPassword) + InternalPasswordService::setPassword(Database::UserId userId, std::string_view newPassword) { const Database::User::PasswordHash passwordHash {hashPassword(newPassword)}; + Database::Session& session {getDbSession()}; auto transaction {session.createUniqueTransaction()}; Database::User::pointer user {Database::User::getById(session, userId)}; @@ -117,7 +117,7 @@ namespace Auth } user.modify()->setPasswordHash(passwordHash); - getAuthTokenService().clearAuthTokens(session, userId); + getAuthTokenService().clearAuthTokens(userId); } Database::User::PasswordHash diff --git a/src/libs/auth/impl/internal/InternalPasswordService.hpp b/src/libs/auth/impl/internal/InternalPasswordService.hpp index 33cdb5cd..6c241f31 100644 --- a/src/libs/auth/impl/internal/InternalPasswordService.hpp +++ b/src/libs/auth/impl/internal/InternalPasswordService.hpp @@ -33,16 +33,14 @@ namespace Auth class InternalPasswordService : public PasswordServiceBase { public: - InternalPasswordService(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService); + InternalPasswordService(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService); private: - bool checkUserPassword(Database::Session& session, - std::string_view loginName, - std::string_view password) override; + bool checkUserPassword(std::string_view loginName, std::string_view password) override; bool canSetPasswords() const override; PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view loginName, const PasswordValidationContext& context) const override; - void setPassword(Database::Session& session, Database::UserId userId, std::string_view newPassword) override; + void setPassword(Database::UserId userId, std::string_view newPassword) override; Database::User::PasswordHash hashPassword(std::string_view password) const; void hashRandomPassword() const; diff --git a/src/libs/auth/impl/pam/PAMPasswordService.cpp b/src/libs/auth/impl/pam/PAMPasswordService.cpp index 1b25f537..c5682f42 100644 --- a/src/libs/auth/impl/pam/PAMPasswordService.cpp +++ b/src/libs/auth/impl/pam/PAMPasswordService.cpp @@ -161,7 +161,7 @@ namespace Auth }; bool - PAMPasswordService::checkUserPassword(Database::Session& /*session*/, std::string_view loginName, std::string_view password) + PAMPasswordService::checkUserPassword(std::string_view loginName, std::string_view password) { try { @@ -193,7 +193,7 @@ namespace Auth } void - PAMPasswordService::setPassword(Database::Session&, Database::UserId, std::string_view) + PAMPasswordService::setPassword(Database::UserId, std::string_view) { throw NotImplementedException {}; } diff --git a/src/libs/auth/impl/pam/PAMPasswordService.hpp b/src/libs/auth/impl/pam/PAMPasswordService.hpp index 4b661b4b..2de5bc82 100644 --- a/src/libs/auth/impl/pam/PAMPasswordService.hpp +++ b/src/libs/auth/impl/pam/PAMPasswordService.hpp @@ -31,14 +31,9 @@ namespace Auth using PasswordServiceBase::PasswordServiceBase; private: - bool checkUserPassword(Database::Session& session, - std::string_view loginName, - std::string_view password) override; - + bool checkUserPassword(std::string_view loginName,std::string_view password) override; bool canSetPasswords() const override; PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view loginName, const PasswordValidationContext& context) const override; - void setPassword(Database::Session& session, - Database::UserId userId, - std::string_view newPassword) override; + void setPassword(Database::UserId userId, std::string_view newPassword) override; }; } diff --git a/src/libs/auth/include/auth/IAuthTokenService.hpp b/src/libs/auth/include/auth/IAuthTokenService.hpp index e57ee6a9..5d9dd51b 100644 --- a/src/libs/auth/include/auth/IAuthTokenService.hpp +++ b/src/libs/auth/include/auth/IAuthTokenService.hpp @@ -31,7 +31,7 @@ namespace Database { - class Session; + class Db; class User; } @@ -63,12 +63,12 @@ namespace Auth }; // Provided token is only accepted once - virtual AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, std::string_view tokenValue) = 0; + virtual AuthTokenProcessResult processAuthToken(const boost::asio::ip::address& clientAddress, std::string_view tokenValue) = 0; // Returns a one time token - virtual std::string createAuthToken(Database::Session& session, Database::UserId userid, const Wt::WDateTime& expiry) = 0; - virtual void clearAuthTokens(Database::Session& session, Database::UserId userid) = 0; + virtual std::string createAuthToken(Database::UserId userid, const Wt::WDateTime& expiry) = 0; + virtual void clearAuthTokens(Database::UserId userid) = 0; }; - std::unique_ptr createAuthTokenService(std::size_t maxThrottlerEntryCount); + std::unique_ptr createAuthTokenService(Database::Db& db, std::size_t maxThrottlerEntryCount); } diff --git a/src/libs/auth/include/auth/IEnvService.hpp b/src/libs/auth/include/auth/IEnvService.hpp index b001d602..ecb23349 100644 --- a/src/libs/auth/include/auth/IEnvService.hpp +++ b/src/libs/auth/include/auth/IEnvService.hpp @@ -26,6 +26,7 @@ namespace Database { + class Db; class Session; } @@ -60,9 +61,9 @@ namespace Auth std::optional userId {}; }; - virtual CheckResult processEnv(Database::Session& session, const Wt::WEnvironment& env) = 0; - virtual CheckResult processRequest(Database::Session& session, const Wt::Http::Request& request) = 0; + virtual CheckResult processEnv(const Wt::WEnvironment& env) = 0; + virtual CheckResult processRequest(const Wt::Http::Request& request) = 0; }; - std::unique_ptr createEnvService(std::string_view backendName); + std::unique_ptr createEnvService(std::string_view backendName, Database::Db& db); } // namespace Auth diff --git a/src/libs/auth/include/auth/IPasswordService.hpp b/src/libs/auth/include/auth/IPasswordService.hpp index 69278fc5..f197ae16 100644 --- a/src/libs/auth/include/auth/IPasswordService.hpp +++ b/src/libs/auth/include/auth/IPasswordService.hpp @@ -30,7 +30,7 @@ namespace Database { - class Session; + class Db; class User; } @@ -56,10 +56,9 @@ namespace Auth std::optional userId {}; std::optional expiry {}; }; - virtual CheckResult checkUserPassword(Database::Session& session, - const boost::asio::ip::address& clientAddress, - std::string_view loginName, - std::string_view password) = 0; + virtual CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress, + std::string_view loginName, + std::string_view password) = 0; virtual bool canSetPasswords() const = 0; @@ -70,9 +69,9 @@ namespace Auth MustMatchLoginName, }; virtual PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view password, const PasswordValidationContext& context) const = 0; - virtual void setPassword(Database::Session& session, Database::UserId userId, std::string_view newPassword) = 0; + virtual void setPassword(Database::UserId userId, std::string_view newPassword) = 0; }; - std::unique_ptr createPasswordService(std::string_view authPasswordBackend, std::size_t maxThrottlerEntryCount, IAuthTokenService& authTokenService); + std::unique_ptr createPasswordService(std::string_view authPasswordBackend, Database::Db& db, std::size_t maxThrottlerEntryCount, IAuthTokenService& authTokenService); } diff --git a/src/libs/subsonic/impl/SubsonicResource.cpp b/src/libs/subsonic/impl/SubsonicResource.cpp index 3f6e9ec8..5cc0b4e4 100644 --- a/src/libs/subsonic/impl/SubsonicResource.cpp +++ b/src/libs/subsonic/impl/SubsonicResource.cpp @@ -506,7 +506,7 @@ handleChangePassword(RequestContext& context) userId = user->getId(); } - Service::get()->setPassword(context.dbSession, userId, password); + Service::get()->setPassword(userId, password); } catch (const Auth::PasswordMustMatchLoginNameException&) { @@ -604,7 +604,7 @@ handleCreateUserRequest(RequestContext& context) try { - Service::get()->setPassword(context.dbSession, userId, password); + Service::get()->setPassword(userId, password); } catch (const Auth::PasswordMustMatchLoginNameException&) { @@ -1620,7 +1620,7 @@ handleUpdateUserRequest(RequestContext& context) try { - Service<::Auth::IPasswordService>()->setPassword(context.dbSession, userId, decodePasswordIfNeeded(*password)); + Service<::Auth::IPasswordService>()->setPassword(userId, decodePasswordIfNeeded(*password)); } catch (const Auth::PasswordMustMatchLoginNameException&) { @@ -2043,22 +2043,18 @@ RequestContext SubsonicResource::buildRequestContext(const Wt::Http::Request& request) { const Wt::Http::ParameterMap& parameters {request.getParameterMap()}; - const ClientInfo clientInfo {getClientInfo(parameters)}; + const Database::UserId userId {authenticateUser(request, clientInfo)}; - Session& dbSession {_db.getTLSSession()}; - - const Database::UserId userId {authenticateUser(request, clientInfo, dbSession)}; - - return {parameters, dbSession, userId, clientInfo, getServerProtocolVersion(clientInfo.name)}; + return {parameters, _db.getTLSSession(), userId, clientInfo, getServerProtocolVersion(clientInfo.name)}; } Database::UserId -SubsonicResource::authenticateUser(const Wt::Http::Request& request, const ClientInfo& clientInfo, Session& dbSession) +SubsonicResource::authenticateUser(const Wt::Http::Request& request, const ClientInfo& clientInfo) { if (auto *authEnvService {Service<::Auth::IEnvService>::get()}) { - const auto checkResult {authEnvService->processRequest(dbSession, request)}; + const auto checkResult {authEnvService->processRequest(request)}; if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted) throw UserNotAuthorizedError {}; @@ -2066,9 +2062,8 @@ SubsonicResource::authenticateUser(const Wt::Http::Request& request, const Clien } else if (auto *authPasswordService {Service<::Auth::IPasswordService>::get()}) { - const auto checkResult {authPasswordService->checkUserPassword(dbSession, - boost::asio::ip::address::from_string(request.clientAddress()), - clientInfo.user, clientInfo.password)}; + const auto checkResult {authPasswordService->checkUserPassword(boost::asio::ip::address::from_string(request.clientAddress()), + clientInfo.user, clientInfo.password)}; switch (checkResult.state) { diff --git a/src/libs/subsonic/impl/SubsonicResource.hpp b/src/libs/subsonic/impl/SubsonicResource.hpp index 8efa1094..2d549f41 100644 --- a/src/libs/subsonic/impl/SubsonicResource.hpp +++ b/src/libs/subsonic/impl/SubsonicResource.hpp @@ -48,7 +48,7 @@ namespace API::Subsonic static void checkProtocolVersion(ProtocolVersion client, ProtocolVersion server); ClientInfo getClientInfo(const Wt::Http::ParameterMap& parameters); RequestContext buildRequestContext(const Wt::Http::Request& request); - Database::UserId authenticateUser(const Wt::Http::Request& request, const ClientInfo& clientInfo, Database::Session& dbSession); + Database::UserId authenticateUser(const Wt::Http::Request& request, const ClientInfo& clientInfo); const std::unordered_map _serverProtocolVersionsByClient; Database::Db& _db; diff --git a/src/lms/main.cpp b/src/lms/main.cpp index 26da8ef4..40a2fc03 100644 --- a/src/lms/main.cpp +++ b/src/lms/main.cpp @@ -245,12 +245,12 @@ int main(int argc, char* argv[]) const std::string authenticationBackend {StringUtils::stringToLower(config->getString("authentication-backend", "internal"))}; if (authenticationBackend == "internal" || authenticationBackend == "pam") { - authTokenService.assign(Auth::createAuthTokenService(config->getULong("login-throttler-max-entriees", 10000))); - authPasswordService.assign(Auth::createPasswordService(authenticationBackend, config->getULong("login-throttler-max-entriees", 10000), *authTokenService.get())); + authTokenService.assign(Auth::createAuthTokenService(database, config->getULong("login-throttler-max-entriees", 10000))); + authPasswordService.assign(Auth::createPasswordService(authenticationBackend, database, config->getULong("login-throttler-max-entriees", 10000), *authTokenService.get())); } else if (authenticationBackend == "http-headers") { - authEnvService.assign(Auth::createEnvService(authenticationBackend)); + authEnvService.assign(Auth::createEnvService(authenticationBackend, database)); } else throw LmsException {"Bad value '" + authenticationBackend + "' for 'authentication-backend'"}; diff --git a/src/lms/ui/Auth.cpp b/src/lms/ui/Auth.cpp index 5e1ec8ea..29414b43 100644 --- a/src/lms/ui/Auth.cpp +++ b/src/lms/ui/Auth.cpp @@ -49,7 +49,7 @@ static void createAuthToken(Database::UserId userId, const Wt::WDateTime& expiry) { - const std::string secret {Service<::Auth::IAuthTokenService>::get()->createAuthToken(LmsApp->getDbSession(), userId, expiry)}; + const std::string secret {Service<::Auth::IAuthTokenService>::get()->createAuthToken(userId, expiry)}; LmsApp->setCookie(authCookieName, secret, @@ -67,7 +67,7 @@ processAuthToken(const Wt::WEnvironment& env) if (!authCookie) return std::nullopt; - const auto res {Service<::Auth::IAuthTokenService>::get()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)}; + const auto res {Service<::Auth::IAuthTokenService>::get()->processAuthToken(boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)}; switch (res.state) { case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::Denied: @@ -131,7 +131,6 @@ class AuthModel : public Wt::WFormModel if (field == PasswordField) { const auto checkResult {Service<::Auth::IPasswordService>::get()->checkUserPassword( - LmsApp->getDbSession(), boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()), valueText(LoginNameField).toUTF8(), valueText(PasswordField).toUTF8())}; diff --git a/src/lms/ui/LmsApplication.cpp b/src/lms/ui/LmsApplication.cpp index a2d0b4e3..e192763e 100644 --- a/src/lms/ui/LmsApplication.cpp +++ b/src/lms/ui/LmsApplication.cpp @@ -69,7 +69,7 @@ LmsApplication::create(const Wt::WEnvironment& env, Database::Db& db, LmsApplica { if (auto *authEnvService {Service<::Auth::IEnvService>::get()}) { - const auto checkResult {authEnvService->processEnv(db.getTLSSession(), env)}; + const auto checkResult {authEnvService->processEnv(env)}; if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted) { LMS_LOG(UI, ERROR) << "Cannot authenticate user from environment!"; diff --git a/src/lms/ui/SettingsView.cpp b/src/lms/ui/SettingsView.cpp index 1f25251e..66105842 100644 --- a/src/lms/ui/SettingsView.cpp +++ b/src/lms/ui/SettingsView.cpp @@ -197,7 +197,7 @@ class SettingsModel : public Wt::WFormModel if (_authPasswordService && !valueText(PasswordField).empty()) { - _authPasswordService->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8()); + _authPasswordService->setPassword(user->getId(), valueText(PasswordField).toUTF8()); } } diff --git a/src/lms/ui/admin/InitWizardView.cpp b/src/lms/ui/admin/InitWizardView.cpp index b187f472..b37645b3 100644 --- a/src/lms/ui/admin/InitWizardView.cpp +++ b/src/lms/ui/admin/InitWizardView.cpp @@ -70,7 +70,7 @@ class InitWizardModel : public Wt::WFormModel Database::User::pointer user {Database::User::create(LmsApp->getDbSession(), valueText(AdminLoginField).toUTF8())}; user.modify()->setType(Database::UserType::ADMIN); - Service<::Auth::IPasswordService>::get()->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8()); + Service<::Auth::IPasswordService>::get()->setPassword(user->getId(), valueText(PasswordField).toUTF8()); } bool validateField(Field field) diff --git a/src/lms/ui/admin/UserView.cpp b/src/lms/ui/admin/UserView.cpp index f27901b9..16374d80 100644 --- a/src/lms/ui/admin/UserView.cpp +++ b/src/lms/ui/admin/UserView.cpp @@ -87,7 +87,7 @@ class UserModel : public Wt::WFormModel throw UserNotFoundException {}; if (_authPasswordService && !valueText(PasswordField).empty()) - _authPasswordService->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8()); + _authPasswordService->setPassword(user->getId(), valueText(PasswordField).toUTF8()); } else { @@ -103,7 +103,7 @@ class UserModel : public Wt::WFormModel user.modify()->setType(Database::UserType::DEMO); if (_authPasswordService) - _authPasswordService->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8()); + _authPasswordService->setPassword(user->getId(), valueText(PasswordField).toUTF8()); } } diff --git a/src/lms/ui/common/PasswordValidator.cpp b/src/lms/ui/common/PasswordValidator.cpp index 443d556f..2df00c3f 100644 --- a/src/lms/ui/common/PasswordValidator.cpp +++ b/src/lms/ui/common/PasswordValidator.cpp @@ -80,7 +80,6 @@ namespace UserInterface return Wt::WValidator::validate(input); const auto checkResult {Service<::Auth::IPasswordService>::get()->checkUserPassword( - LmsApp->getDbSession(), boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()), LmsApp->getUserLoginName(), input.toUTF8())};