From 1b49e8f6a65494895ce0976e6d1a2576b7c56142 Mon Sep 17 00:00:00 2001 From: emeric Date: Fri, 5 Mar 2021 13:23:47 +0100 Subject: [PATCH] Properly handled http headers for subsonic API. ref #119 --- INSTALL.md | 4 +- approot/messages.xml | 1 - approot/messages_fr.xml | 1 - conf/lms.conf | 2 +- .../http-headers/HttpHeadersEnvService.cpp | 18 +- .../http-headers/HttpHeadersEnvService.hpp | 1 + src/libs/auth/include/auth/IEnvService.hpp | 6 + src/libs/subsonic/impl/RequestContext.hpp | 6 +- src/libs/subsonic/impl/Stream.cpp | 2 +- src/libs/subsonic/impl/SubsonicResource.cpp | 159 +++++++++++------- src/lms/ui/LmsApplication.cpp | 42 ++--- src/lms/ui/LmsApplication.hpp | 3 +- src/lms/ui/LmsApplicationException.hpp | 6 - 13 files changed, 149 insertions(+), 102 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 5d923e06..7ff70afc 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -132,8 +132,8 @@ If a setting is not present in the configuration file, a hardcoded default value 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. -* `PAM`: the authentication request is forwarded to PAM (see the [default configuration file](conf/pam/lms)). -* `http-headers`: _LMS_ uses a configurable HTTP header field, typically set by a reverse proxy to handle [SSO](https://en.wikipedia.org/wiki/Single_sign-on), to extract the login name. You can customize the field to be used using the `http-headers-user-field` option. +* `PAM`: the user/password authentication request is forwarded to PAM (see the [default configuration file](conf/pam/lms)). +* `http-headers`: _LMS_ uses a configurable HTTP header field, typically set by a reverse proxy to handle [SSO](https://en.wikipedia.org/wiki/Single_sign-on), to extract the login name. You can customize the field to be used using the `http-headers-login-field` option. __Note__: the first created user is the admin user diff --git a/approot/messages.xml b/approot/messages.xml index 28dff4ae..ee2a721c 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -28,7 +28,6 @@ Artist not found Error occured! -Deployment error Go home Release not found You are not allowed to perform this operation diff --git a/approot/messages_fr.xml b/approot/messages_fr.xml index 641029b3..4e4c9af7 100644 --- a/approot/messages_fr.xml +++ b/approot/messages_fr.xml @@ -28,7 +28,6 @@ Cet artiste n'existe pas Une erreur est survenue! -Erreur de déploiement Retour à l'accueil Cet album n'existe pas Vous n'avez pas les droits pour effectuer cette opération diff --git a/conf/lms.conf b/conf/lms.conf index fc38a121..e4c00109 100644 --- a/conf/lms.conf +++ b/conf/lms.conf @@ -40,7 +40,7 @@ acousticbrainz-api-url = "https://acousticbrainz.org/api/v1/"; # Authentication # Available backends: "internal", "PAM", "http-headers" authentication-backend = "internal"; -http-headers-user-field = "X-Forwarded-User"; +http-headers-login-field = "X-Forwarded-User"; # Max entries in the login throttler (1 entry per IP address. For IPv6, the whole /64 block is used) login-throttler-max-entries = 10000; diff --git a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp index 4d24085a..93f0b584 100644 --- a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp +++ b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.cpp @@ -29,7 +29,7 @@ namespace Auth { HttpHeadersEnvService::HttpHeadersEnvService() - : _fieldName {Service::get()->getString("http-headers-field-name", "X-Forwarded-User")} + : _fieldName {Service::get()->getString("http-headers-login-field", "X-Forwarded-User")} { LMS_LOG(AUTH, INFO) << "Using http header field = '" << _fieldName << "'"; } @@ -37,7 +37,21 @@ namespace Auth HttpHeadersEnvService::CheckResult HttpHeadersEnvService::processEnv(Database::Session& session, const Wt::WEnvironment& env) { - const std::string loginName { env.headerValue(_fieldName)}; + const std::string loginName {env.headerValue(_fieldName)}; + if (loginName.empty()) + return {CheckResult::State::Denied}; + + LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header"; + + const Database::IdType userId {getOrCreateUser(session, loginName)}; + onUserAuthenticated(session, userId); + return {CheckResult::State::Granted, userId}; + } + + HttpHeadersEnvService::CheckResult + HttpHeadersEnvService::processRequest(Database::Session& session, const Wt::Http::Request& request) + { + const std::string loginName {request.headerValue(_fieldName)}; if (loginName.empty()) return {CheckResult::State::Denied}; diff --git a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp index 2f74d0de..1295f182 100644 --- a/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp +++ b/src/libs/auth/impl/http-headers/HttpHeadersEnvService.hpp @@ -31,6 +31,7 @@ namespace Auth private: CheckResult processEnv(Database::Session& session, const Wt::WEnvironment& env) override; + CheckResult processRequest(Database::Session& session, const Wt::Http::Request& request) override; std::string _fieldName; }; diff --git a/src/libs/auth/include/auth/IEnvService.hpp b/src/libs/auth/include/auth/IEnvService.hpp index 336432e3..02a6d4e2 100644 --- a/src/libs/auth/include/auth/IEnvService.hpp +++ b/src/libs/auth/include/auth/IEnvService.hpp @@ -34,6 +34,11 @@ namespace Wt class WEnvironment; } +namespace Wt::Http +{ + class Request; +} + namespace Auth { class IEnvService @@ -56,6 +61,7 @@ namespace Auth }; virtual CheckResult processEnv(Database::Session& session, const Wt::WEnvironment& env) = 0; + virtual CheckResult processRequest(Database::Session& session, const Wt::Http::Request& request) = 0; }; std::unique_ptr createEnvService(std::string_view backendName); diff --git a/src/libs/subsonic/impl/RequestContext.hpp b/src/libs/subsonic/impl/RequestContext.hpp index cd41100b..6d599513 100644 --- a/src/libs/subsonic/impl/RequestContext.hpp +++ b/src/libs/subsonic/impl/RequestContext.hpp @@ -22,8 +22,8 @@ #include #include -#include +#include "database/Types.hpp" namespace Database { @@ -32,14 +32,12 @@ namespace Database namespace API::Subsonic { - struct RequestContext { const Wt::Http::ParameterMap& parameters; Database::Session& dbSession; - std::string userName; + Database::IdType userId; std::string clientName; }; - } diff --git a/src/libs/subsonic/impl/Stream.cpp b/src/libs/subsonic/impl/Stream.cpp index 625224e5..29085c83 100644 --- a/src/libs/subsonic/impl/Stream.cpp +++ b/src/libs/subsonic/impl/Stream.cpp @@ -81,7 +81,7 @@ getStreamParameters(RequestContext& context) } { - const User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + const User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; diff --git a/src/libs/subsonic/impl/SubsonicResource.cpp b/src/libs/subsonic/impl/SubsonicResource.cpp index 6c922a21..70ba40ba 100644 --- a/src/libs/subsonic/impl/SubsonicResource.cpp +++ b/src/libs/subsonic/impl/SubsonicResource.cpp @@ -26,6 +26,7 @@ #include #include "auth/IPasswordService.hpp" +#include "auth/IEnvService.hpp" #include "cover/ICoverArtGrabber.hpp" #include "database/Artist.hpp" #include "database/Cluster.hpp" @@ -209,14 +210,33 @@ static void checkUserIsMySelfOrAdmin(RequestContext& context, const std::string& username) { - if (username != context.userName) - { - User::pointer currentUser {User::getByLoginName(context.dbSession, context.userName)}; - if (!currentUser) - throw RequestedDataNotFoundError {}; + User::pointer currentUser {User::getById(context.dbSession, context.userId)}; + if (!currentUser) + throw RequestedDataNotFoundError {}; - if (!currentUser->isAdmin()) - throw UserNotAuthorizedError {}; + if (currentUser->getLoginName() != username && !currentUser->isAdmin()) + throw UserNotAuthorizedError {}; +} + +static +void +checkUserIsAdmin(RequestContext& context) +{ + LMS_LOG(API_SUBSONIC, DEBUG) << "Check user is admin"; + + auto transaction {context.dbSession.createSharedTransaction()}; + + User::pointer currentUser {User::getById(context.dbSession, context.userId)}; + if (!currentUser) + { + LMS_LOG(API_SUBSONIC, DEBUG) << "NOT FOUND"; + throw RequestedDataNotFoundError {}; + } + + if (!currentUser->isAdmin()) + { + LMS_LOG(API_SUBSONIC, DEBUG) << "NOT ADMIN"; + throw UserNotAuthorizedError {}; } } @@ -327,7 +347,6 @@ trackToResponseNode(const Track::pointer& track, Session& dbSession, const User: trackResponse.setAttribute("coverArt", IdToString({Id::Type::Track, track.id()})); const std::vector& artists {track->getArtists({TrackArtistLinkType::Artist})}; - LMS_LOG(API_SUBSONIC, DEBUG) << "Artists count = " << artists.size(); if (!artists.empty()) { trackResponse.setAttribute("artist", getArtistNames(artists)); @@ -573,7 +592,7 @@ handleCreatePlaylistRequest(RequestContext& context) auto transaction {context.dbSession.createUniqueTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -629,12 +648,12 @@ handleCreateUserRequest(RequestContext& context) } auto removeCreatedUser {[&]() - { - auto transaction {context.dbSession.createUniqueTransaction()}; - User::pointer user {User::getById(context.dbSession, userId)}; - if (user) - user.remove(); - }}; + { + auto transaction {context.dbSession.createUniqueTransaction()}; + User::pointer user {User::getById(context.dbSession, userId)}; + if (user) + user.remove(); + }}; try { @@ -664,7 +683,7 @@ handleDeletePlaylistRequest(RequestContext& context) auto transaction {context.dbSession.createUniqueTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -687,16 +706,16 @@ handleDeleteUserRequest(RequestContext& context) { std::string username {getMandatoryParameterAs(context.parameters, "username")}; - // cannot delete ourself - if (username == context.userName) - throw UserNotAuthorizedError {}; - auto transaction {context.dbSession.createUniqueTransaction()}; User::pointer user {User::getByLoginName(context.dbSession, username)}; if (!user) throw RequestedDataNotFoundError {}; + // cannot delete ourself + if (user.id() == context.userId) + throw UserNotAuthorizedError {}; + user.remove(); return Response::createOkResponse(context); @@ -726,7 +745,7 @@ handleGetRandomSongsRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -758,7 +777,7 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -860,7 +879,7 @@ handleGetAlbumRequest(RequestContext& context) if (!release) throw RequestedDataNotFoundError {}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -892,7 +911,7 @@ handleGetArtistRequest(RequestContext& context) if (!artist) throw RequestedDataNotFoundError {}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -943,7 +962,7 @@ handleGetArtistInfoRequestCommon(RequestContext& context, bool id3) { auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -987,7 +1006,7 @@ handleGetArtistsRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1031,7 +1050,7 @@ handleGetMusicDirectoryRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1137,7 +1156,7 @@ handleGetIndexesRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1190,7 +1209,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3) if (!artist) throw RequestedDataNotFoundError {}; - const User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + const User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1239,7 +1258,7 @@ handleGetStarredRequestCommon(RequestContext& context, bool id3) { auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1313,7 +1332,7 @@ handleGetPlaylistRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1339,7 +1358,7 @@ handleGetPlaylistsRequest(RequestContext& context) { auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1376,7 +1395,7 @@ handleGetSongsByGenreRequest(RequestContext& context) if (!cluster) throw RequestedDataNotFoundError {}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1446,7 +1465,7 @@ handleSearchRequestCommon(RequestContext& context, bool id3) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1528,7 +1547,7 @@ handleStarRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1584,7 +1603,7 @@ handleUnstarRequest(RequestContext& context) auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw RequestedDataNotFoundError {}; @@ -1631,7 +1650,7 @@ handleScrobble(RequestContext& context) auto transaction {context.dbSession.createUniqueTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw RequestedDataNotFoundError {}; @@ -1707,7 +1726,7 @@ handleUpdatePlaylistRequest(RequestContext& context) auto transaction {context.dbSession.createUniqueTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1756,7 +1775,7 @@ handleGetBookmarks(RequestContext& context) { auto transaction {context.dbSession.createSharedTransaction()}; - User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1790,7 +1809,7 @@ handleCreateBookmark(RequestContext& context) auto transaction {context.dbSession.createUniqueTransaction()}; - const User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + const User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1821,7 +1840,7 @@ handleDeleteBookmark(RequestContext& context) auto transaction {context.dbSession.createUniqueTransaction()}; - const User::pointer user {User::getByLoginName(context.dbSession, context.userName)}; + const User::pointer user {User::getById(context.dbSession, context.userId)}; if (!user) throw UserNotAuthorizedError {}; @@ -1995,6 +2014,39 @@ static std::unordered_map mediaRetrieval {"getCoverArt", handleGetCoverArt}, }; +static +Database::IdType +authenticateUser(const Wt::Http::Request &request, const ClientInfo& clientInfo, Session& dbSession) +{ + if (auto *authEnvService {Service<::Auth::IEnvService>::get()}) + { + const auto checkResult {authEnvService->processRequest(dbSession, request)}; + if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted) + throw UserNotAuthorizedError {}; + + return *checkResult.userId; + } + 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)}; + + switch (checkResult.state) + { + case Auth::IPasswordService::CheckResult::State::Granted: + return *checkResult.userId; + break; + case Auth::IPasswordService::CheckResult::State::Denied: + throw WrongUsernameOrPasswordError {}; + case Auth::IPasswordService::CheckResult::State::Throttled: + throw LoginThrottledGenericError {}; + } + } + + throw InternalErrorGenericError {"No service avalaible to authenticate user"}; +} + void SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) { @@ -2024,21 +2076,8 @@ SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Resp Session& dbSession {_db.getTLSSession()}; - const Auth::IPasswordService::CheckResult checkResult {Service::get()->checkUserPassword(dbSession, - boost::asio::ip::address::from_string(request.clientAddress()), - clientInfo.user, clientInfo.password)}; - - switch (checkResult.state) - { - case Auth::IPasswordService::CheckResult::State::Granted: - break; - case Auth::IPasswordService::CheckResult::State::Denied: - throw WrongUsernameOrPasswordError {}; - case Auth::IPasswordService::CheckResult::State::Throttled: - throw LoginThrottledGenericError {}; - } - - RequestContext requestContext {parameters, dbSession, clientInfo.user, clientInfo.name}; + const Database::IdType userId {authenticateUser(request, clientInfo, dbSession)}; + RequestContext requestContext {parameters, dbSession, userId, clientInfo.name}; auto itEntryPoint {requestEntryPoints.find(requestPath)}; if (itEntryPoint != requestEntryPoints.end()) @@ -2047,13 +2086,7 @@ SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Resp itEntryPoint->second.checkFunc(); if (itEntryPoint->second.mustBeAdmin) - { - auto transaction {dbSession.createSharedTransaction()}; - - User::pointer user {User::getByLoginName(dbSession, clientInfo.user)}; - if (!user || !user->isAdmin()) - throw UserNotAuthorizedError {}; - } + checkUserIsAdmin(requestContext); Response resp {(itEntryPoint->second.func)(requestContext)}; diff --git a/src/lms/ui/LmsApplication.cpp b/src/lms/ui/LmsApplication.cpp index 861b3501..f86906ee 100644 --- a/src/lms/ui/LmsApplication.cpp +++ b/src/lms/ui/LmsApplication.cpp @@ -65,6 +65,19 @@ static constexpr const char* defaultPath {"/releases"}; std::unique_ptr LmsApplication::create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups) { + if (auto *authEnvService {Service<::Auth::IEnvService>::get()}) + { + const auto checkResult {authEnvService->processEnv(db.getTLSSession(), env)}; + if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted) + { + LMS_LOG(UI, ERROR) << "Cannot authenticate user from environment!"; + // return a blank page + return std::make_unique(env); + } + + return std::make_unique(env, db, appGroups, checkResult.userId); + } + return std::make_unique(env, db, appGroups); } @@ -121,10 +134,12 @@ LmsApplication::getUserLoginName() LmsApplication::LmsApplication(const Wt::WEnvironment& env, Database::Db& db, - LmsApplicationGroupContainer& appGroups) -: Wt::WApplication {env}, - _db {db}, - _appGroups {appGroups} + LmsApplicationGroupContainer& appGroups, + std::optional userId) +: Wt::WApplication {env} +, _db {db} +, _appGroups {appGroups} +, _authenticatedUser {userId ? std::make_optional(UserAuthInfo {*userId, false}) : std::nullopt} { try { @@ -181,23 +196,12 @@ LmsApplication::init() // Handle Media Scanner events and other session events enableUpdates(true); - if (Service<::Auth::IEnvService>::exists()) - processEnvAuth(); + if (_authenticatedUser) + { + onUserLoggedIn(); + } else if (Service<::Auth::IPasswordService>::exists()) processPasswordAuth(); - else - throw LmsException {"No auth service available!"}; -} - -void -LmsApplication::processEnvAuth() -{ - const auto checkResult {Service<::Auth::IEnvService>::get()->processEnv(getDbSession(), wApp->environment())}; - if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted) - throw DeploymentException {}; - - _authenticatedUser = {*checkResult.userId, false}; - onUserLoggedIn(); } void diff --git a/src/lms/ui/LmsApplication.hpp b/src/lms/ui/LmsApplication.hpp index 453007a2..2fdd8d10 100644 --- a/src/lms/ui/LmsApplication.hpp +++ b/src/lms/ui/LmsApplication.hpp @@ -60,7 +60,7 @@ class LmsApplication : public Wt::WApplication { public: - LmsApplication(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups); + LmsApplication(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups, std::optional userId = std::nullopt); ~LmsApplication(); static std::unique_ptr create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups); @@ -110,7 +110,6 @@ class LmsApplication : public Wt::WApplication void init(); void setTheme(); - void processEnvAuth(); void processPasswordAuth(); void handleException(LmsApplicationException& e); void goHomeAndQuit(); diff --git a/src/lms/ui/LmsApplicationException.hpp b/src/lms/ui/LmsApplicationException.hpp index 3acdde67..61ef2dbd 100644 --- a/src/lms/ui/LmsApplicationException.hpp +++ b/src/lms/ui/LmsApplicationException.hpp @@ -31,12 +31,6 @@ class LmsApplicationException : public LmsException LmsApplicationException(const Wt::WString& error) : LmsException {error.toUTF8()} {} }; -class DeploymentException : public LmsApplicationException -{ - public: - DeploymentException() : LmsApplicationException {Wt::WString::tr("Lms.Error.deployment-error")} {} -}; - class ArtistNotFoundException : public LmsApplicationException { public: