Removed session parameters from auth services
This commit is contained in:
@@ -19,25 +19,33 @@
|
|||||||
|
|
||||||
#include "AuthServiceBase.hpp"
|
#include "AuthServiceBase.hpp"
|
||||||
|
|
||||||
|
#include "database/Db.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/User.hpp"
|
#include "database/User.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
|
|
||||||
namespace Auth
|
namespace Auth
|
||||||
{
|
{
|
||||||
Database::UserId
|
using namespace Database;
|
||||||
AuthServiceBase::getOrCreateUser(Database::Session& session, std::string_view loginName)
|
|
||||||
|
AuthServiceBase::AuthServiceBase(Db& db)
|
||||||
|
: _db {db}
|
||||||
|
{}
|
||||||
|
|
||||||
|
UserId
|
||||||
|
AuthServiceBase::getOrCreateUser(std::string_view loginName)
|
||||||
{
|
{
|
||||||
|
Session& session {getDbSession()};
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
|
||||||
Database::User::pointer user {Database::User::getByLoginName(session, loginName)};
|
User::pointer user {User::getByLoginName(session, loginName)};
|
||||||
if (!user)
|
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);
|
user.modify()->setType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,11 +53,19 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AuthServiceBase::onUserAuthenticated(Database::Session& session, Database::UserId userId)
|
AuthServiceBase::onUserAuthenticated(UserId userId)
|
||||||
{
|
{
|
||||||
|
Session& session {getDbSession()};
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
Database::User::pointer user {Database::User::getById(session, userId)};
|
|
||||||
|
User::pointer user {User::getById(session, userId)};
|
||||||
if (user)
|
if (user)
|
||||||
user.modify()->setLastLogin(Wt::WDateTime::currentDateTime());
|
user.modify()->setLastLogin(Wt::WDateTime::currentDateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session&
|
||||||
|
AuthServiceBase::getDbSession()
|
||||||
|
{
|
||||||
|
return _db.getTLSSession();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
|
class Db;
|
||||||
class Session;
|
class Session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +33,14 @@ namespace Auth
|
|||||||
class AuthServiceBase
|
class AuthServiceBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Database::UserId getOrCreateUser(Database::Session& session, std::string_view loginName);
|
AuthServiceBase(Database::Db& db);
|
||||||
void onUserAuthenticated(Database::Session& session, Database::UserId userId);
|
|
||||||
|
Database::UserId getOrCreateUser(std::string_view loginName);
|
||||||
|
void onUserAuthenticated(Database::UserId userId);
|
||||||
|
|
||||||
|
Database::Session& getDbSession();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Database::Db& _db;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,24 +32,27 @@
|
|||||||
namespace Auth
|
namespace Auth
|
||||||
{
|
{
|
||||||
|
|
||||||
std::unique_ptr<IAuthTokenService> createAuthTokenService(std::size_t maxThrottlerEntries)
|
std::unique_ptr<IAuthTokenService> createAuthTokenService(Database::Db& db, std::size_t maxThrottlerEntries)
|
||||||
{
|
{
|
||||||
return std::make_unique<AuthTokenService>(maxThrottlerEntries);
|
return std::make_unique<AuthTokenService>(db, maxThrottlerEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const Wt::Auth::SHA1HashFunction sha1Function;
|
static const Wt::Auth::SHA1HashFunction sha1Function;
|
||||||
|
|
||||||
AuthTokenService::AuthTokenService(std::size_t maxThrottlerEntries)
|
AuthTokenService::AuthTokenService(Database::Db& db, std::size_t maxThrottlerEntries)
|
||||||
: _loginThrottler {maxThrottlerEntries}
|
: AuthServiceBase {db}
|
||||||
|
, _loginThrottler {maxThrottlerEntries}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
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 secret {Wt::WRandom::generateId(32)};
|
||||||
const std::string secretHash {sha1Function.compute(secret, {})};
|
const std::string secretHash {sha1Function.compute(secret, {})};
|
||||||
|
|
||||||
|
Database::Session& session {getDbSession()};
|
||||||
|
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
|
||||||
Database::User::pointer user {Database::User::getById(session, userId)};
|
Database::User::pointer user {Database::User::getById(session, userId)};
|
||||||
@@ -66,12 +69,12 @@ namespace Auth
|
|||||||
return secret;
|
return secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
std::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo>
|
std::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo>
|
||||||
processAuthToken(Database::Session& session, std::string_view secret)
|
AuthTokenService::processAuthToken(std::string_view secret)
|
||||||
{
|
{
|
||||||
const std::string secretHash {sha1Function.compute(std::string {secret}, {})};
|
const std::string secretHash {sha1Function.compute(std::string {secret}, {})};
|
||||||
|
|
||||||
|
Database::Session& session {getDbSession()};
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
|
||||||
Database::AuthToken::pointer authToken {Database::AuthToken::getByValue(session, secretHash)};
|
Database::AuthToken::pointer authToken {Database::AuthToken::getByValue(session, secretHash)};
|
||||||
@@ -93,7 +96,7 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
AuthTokenService::AuthTokenProcessResult
|
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)
|
// Do not waste too much resource on brute force attacks (optim)
|
||||||
{
|
{
|
||||||
@@ -103,7 +106,7 @@ namespace Auth
|
|||||||
return AuthTokenProcessResult {AuthTokenProcessResult::State::Throttled};
|
return AuthTokenProcessResult {AuthTokenProcessResult::State::Throttled};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto res {Auth::processAuthToken(session, tokenValue)};
|
auto res {processAuthToken(tokenValue)};
|
||||||
{
|
{
|
||||||
std::unique_lock lock {_mutex};
|
std::unique_lock lock {_mutex};
|
||||||
|
|
||||||
@@ -117,14 +120,16 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
_loginThrottler.onGoodClientAttempt(clientAddress);
|
_loginThrottler.onGoodClientAttempt(clientAddress);
|
||||||
onUserAuthenticated(session, res->userId);
|
onUserAuthenticated(res->userId);
|
||||||
return AuthTokenProcessResult {AuthTokenProcessResult::State::Granted, std::move(*res)};
|
return AuthTokenProcessResult {AuthTokenProcessResult::State::Granted, std::move(*res)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AuthTokenService::clearAuthTokens(Database::Session& session, Database::UserId userId)
|
AuthTokenService::clearAuthTokens(Database::UserId userId)
|
||||||
{
|
{
|
||||||
|
Database::Session& session {getDbSession()};
|
||||||
|
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
|
||||||
Database::User::pointer user {Database::User::getById(session, userId)};
|
Database::User::pointer user {Database::User::getById(session, userId)};
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace Auth
|
|||||||
class AuthTokenService : public IAuthTokenService, public AuthServiceBase
|
class AuthTokenService : public IAuthTokenService, public AuthServiceBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AuthTokenService(std::size_t maxThrottlerEntries);
|
AuthTokenService(Database::Db& db, std::size_t maxThrottlerEntries);
|
||||||
|
|
||||||
AuthTokenService(const AuthTokenService&) = delete;
|
AuthTokenService(const AuthTokenService&) = delete;
|
||||||
AuthTokenService& operator=(const AuthTokenService&) = delete;
|
AuthTokenService& operator=(const AuthTokenService&) = delete;
|
||||||
@@ -43,9 +43,11 @@ namespace Auth
|
|||||||
AuthTokenService& operator=(AuthTokenService&&) = delete;
|
AuthTokenService& operator=(AuthTokenService&&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AuthTokenProcessResult processAuthToken(Database::Session& session, const boost::asio::ip::address& clientAddress, std::string_view tokenValue) override;
|
AuthTokenProcessResult processAuthToken(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;
|
std::string createAuthToken(Database::UserId userId, const Wt::WDateTime& expiry) override;
|
||||||
void clearAuthTokens(Database::Session& session, Database::UserId userId) override;
|
void clearAuthTokens(Database::UserId userId) override;
|
||||||
|
|
||||||
|
std::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo> processAuthToken(std::string_view secret);
|
||||||
|
|
||||||
std::shared_mutex _mutex;
|
std::shared_mutex _mutex;
|
||||||
LoginThrottler _loginThrottler;
|
LoginThrottler _loginThrottler;
|
||||||
|
|||||||
@@ -25,10 +25,10 @@
|
|||||||
namespace Auth
|
namespace Auth
|
||||||
{
|
{
|
||||||
std::unique_ptr<IEnvService>
|
std::unique_ptr<IEnvService>
|
||||||
createEnvService(std::string_view backendName)
|
createEnvService(std::string_view backendName, Database::Db& db)
|
||||||
{
|
{
|
||||||
if (backendName == "http-headers")
|
if (backendName == "http-headers")
|
||||||
return std::make_unique<HttpHeadersEnvService>();
|
return std::make_unique<HttpHeadersEnvService>(db);
|
||||||
|
|
||||||
throw Exception {"Authentication backend '" + std::string {backendName} + "' is not supported!"};
|
throw Exception {"Authentication backend '" + std::string {backendName} + "' is not supported!"};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,29 +39,27 @@ namespace Auth
|
|||||||
static const Wt::Auth::SHA1HashFunction sha1Function;
|
static const Wt::Auth::SHA1HashFunction sha1Function;
|
||||||
|
|
||||||
std::unique_ptr<IPasswordService>
|
std::unique_ptr<IPasswordService>
|
||||||
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")
|
if (passwordAuthenticationBackend == "internal")
|
||||||
return std::make_unique<InternalPasswordService>(maxThrottlerEntries, authTokenService);
|
return std::make_unique<InternalPasswordService>(db, maxThrottlerEntries, authTokenService);
|
||||||
#ifdef LMS_SUPPORT_PAM
|
#ifdef LMS_SUPPORT_PAM
|
||||||
else if (passwordAuthenticationBackend == "pam")
|
else if (passwordAuthenticationBackend == "pam")
|
||||||
return std::make_unique<PAMPasswordService>(maxThrottlerEntries, authTokenService);
|
return std::make_unique<PAMPasswordService>(db, maxThrottlerEntries, authTokenService);
|
||||||
#endif // LMS_SUPPORT_PAM
|
#endif // LMS_SUPPORT_PAM
|
||||||
|
|
||||||
throw Exception {"Authentication backend '" + std::string {passwordAuthenticationBackend} + "' is not supported!"};
|
throw Exception {"Authentication backend '" + std::string {passwordAuthenticationBackend} + "' is not supported!"};
|
||||||
}
|
}
|
||||||
|
|
||||||
PasswordServiceBase::PasswordServiceBase(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService)
|
PasswordServiceBase::PasswordServiceBase(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService)
|
||||||
: _loginThrottler {maxThrottlerEntries}
|
: AuthServiceBase {db}
|
||||||
|
, _loginThrottler {maxThrottlerEntries}
|
||||||
, _authTokenService {authTokenService}
|
, _authTokenService {authTokenService}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
PasswordServiceBase::CheckResult
|
PasswordServiceBase::CheckResult
|
||||||
PasswordServiceBase::checkUserPassword(Database::Session& session,
|
PasswordServiceBase::checkUserPassword(const boost::asio::ip::address& clientAddress, std::string_view loginName, std::string_view password)
|
||||||
const boost::asio::ip::address& clientAddress,
|
|
||||||
std::string_view loginName,
|
|
||||||
std::string_view password)
|
|
||||||
{
|
{
|
||||||
LMS_LOG(AUTH, DEBUG) << "Checking password for user '" << loginName << "'";
|
LMS_LOG(AUTH, DEBUG) << "Checking password for user '" << loginName << "'";
|
||||||
|
|
||||||
@@ -73,7 +71,7 @@ namespace Auth
|
|||||||
return {CheckResult::State::Throttled};
|
return {CheckResult::State::Throttled};
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool match {checkUserPassword(session, loginName, password)};
|
const bool match {checkUserPassword(loginName, password)};
|
||||||
{
|
{
|
||||||
std::unique_lock lock {_mutex};
|
std::unique_lock lock {_mutex};
|
||||||
|
|
||||||
@@ -84,8 +82,8 @@ namespace Auth
|
|||||||
{
|
{
|
||||||
_loginThrottler.onGoodClientAttempt(clientAddress);
|
_loginThrottler.onGoodClientAttempt(clientAddress);
|
||||||
|
|
||||||
const Database::UserId userId {getOrCreateUser(session, loginName)};
|
const Database::UserId userId {getOrCreateUser(loginName)};
|
||||||
onUserAuthenticated(session, userId);
|
onUserAuthenticated(userId);
|
||||||
return {CheckResult::State::Granted, userId};
|
return {CheckResult::State::Granted, userId};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
|
class Db;
|
||||||
class Session;
|
class Session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ namespace Auth
|
|||||||
class PasswordServiceBase : public IPasswordService, public AuthServiceBase
|
class PasswordServiceBase : public IPasswordService, public AuthServiceBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PasswordServiceBase(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService);
|
PasswordServiceBase(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService);
|
||||||
|
|
||||||
PasswordServiceBase(const PasswordServiceBase&) = delete;
|
PasswordServiceBase(const PasswordServiceBase&) = delete;
|
||||||
PasswordServiceBase& operator=(const PasswordServiceBase&) = delete;
|
PasswordServiceBase& operator=(const PasswordServiceBase&) = delete;
|
||||||
@@ -47,12 +48,9 @@ namespace Auth
|
|||||||
IAuthTokenService& getAuthTokenService() { return _authTokenService; }
|
IAuthTokenService& getAuthTokenService() { return _authTokenService; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool checkUserPassword(Database::Session& session,
|
virtual bool checkUserPassword(std::string_view loginName, std::string_view password) = 0;
|
||||||
std::string_view loginName,
|
|
||||||
std::string_view password) = 0;
|
|
||||||
|
|
||||||
CheckResult checkUserPassword(Database::Session& session,
|
CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
||||||
const boost::asio::ip::address& clientAddress,
|
|
||||||
std::string_view loginName,
|
std::string_view loginName,
|
||||||
std::string_view password) override;
|
std::string_view password) override;
|
||||||
|
|
||||||
|
|||||||
@@ -28,14 +28,15 @@
|
|||||||
namespace Auth
|
namespace Auth
|
||||||
{
|
{
|
||||||
|
|
||||||
HttpHeadersEnvService::HttpHeadersEnvService()
|
HttpHeadersEnvService::HttpHeadersEnvService(Database::Db& db)
|
||||||
: _fieldName {Service<IConfig>::get()->getString("http-headers-login-field", "X-Forwarded-User")}
|
: AuthServiceBase {db}
|
||||||
|
, _fieldName {Service<IConfig>::get()->getString("http-headers-login-field", "X-Forwarded-User")}
|
||||||
{
|
{
|
||||||
LMS_LOG(AUTH, INFO) << "Using http header field = '" << _fieldName << "'";
|
LMS_LOG(AUTH, INFO) << "Using http header field = '" << _fieldName << "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpHeadersEnvService::CheckResult
|
HttpHeadersEnvService::CheckResult
|
||||||
HttpHeadersEnvService::processEnv(Database::Session& session, const Wt::WEnvironment& env)
|
HttpHeadersEnvService::processEnv(const Wt::WEnvironment& env)
|
||||||
{
|
{
|
||||||
const std::string loginName {env.headerValue(_fieldName)};
|
const std::string loginName {env.headerValue(_fieldName)};
|
||||||
if (loginName.empty())
|
if (loginName.empty())
|
||||||
@@ -43,13 +44,13 @@ namespace Auth
|
|||||||
|
|
||||||
LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header";
|
LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header";
|
||||||
|
|
||||||
const Database::UserId userId {getOrCreateUser(session, loginName)};
|
const Database::UserId userId {getOrCreateUser(loginName)};
|
||||||
onUserAuthenticated(session, userId);
|
onUserAuthenticated(userId);
|
||||||
return {CheckResult::State::Granted, userId};
|
return {CheckResult::State::Granted, userId};
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpHeadersEnvService::CheckResult
|
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)};
|
const std::string loginName {request.headerValue(_fieldName)};
|
||||||
if (loginName.empty())
|
if (loginName.empty())
|
||||||
@@ -57,8 +58,8 @@ namespace Auth
|
|||||||
|
|
||||||
LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header";
|
LMS_LOG(AUTH, DEBUG) << "Extracted login name = '" << loginName << "' from HTTP header";
|
||||||
|
|
||||||
const Database::UserId userId {getOrCreateUser(session, loginName)};
|
const Database::UserId userId {getOrCreateUser(loginName)};
|
||||||
onUserAuthenticated(session, userId);
|
onUserAuthenticated(userId);
|
||||||
return {CheckResult::State::Granted, userId};
|
return {CheckResult::State::Granted, userId};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ namespace Auth
|
|||||||
class HttpHeadersEnvService : public IEnvService, public AuthServiceBase
|
class HttpHeadersEnvService : public IEnvService, public AuthServiceBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HttpHeadersEnvService();
|
HttpHeadersEnvService(Database::Db& db);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CheckResult processEnv(Database::Session& session, const Wt::WEnvironment& env) override;
|
CheckResult processEnv(const Wt::WEnvironment& env) override;
|
||||||
CheckResult processRequest(Database::Session& session, const Wt::Http::Request& request) override;
|
CheckResult processRequest(const Wt::Http::Request& request) override;
|
||||||
|
|
||||||
std::string _fieldName;
|
std::string _fieldName;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
|
|
||||||
namespace Auth
|
namespace Auth
|
||||||
{
|
{
|
||||||
InternalPasswordService::InternalPasswordService(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService)
|
InternalPasswordService::InternalPasswordService(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService)
|
||||||
: PasswordServiceBase {maxThrottlerEntries, authTokenService}
|
: PasswordServiceBase {db, maxThrottlerEntries, authTokenService}
|
||||||
{
|
{
|
||||||
_validator.setMinimumLength(Wt::Auth::PasswordStrengthType::OneCharClass, 4);
|
_validator.setMinimumLength(Wt::Auth::PasswordStrengthType::OneCharClass, 4);
|
||||||
_validator.setMinimumLength(Wt::Auth::PasswordStrengthType::TwoCharClass, 4);
|
_validator.setMinimumLength(Wt::Auth::PasswordStrengthType::TwoCharClass, 4);
|
||||||
@@ -42,14 +42,13 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InternalPasswordService::checkUserPassword(Database::Session& session,
|
InternalPasswordService::checkUserPassword(std::string_view loginName, std::string_view password)
|
||||||
std::string_view loginName,
|
|
||||||
std::string_view password)
|
|
||||||
{
|
{
|
||||||
LMS_LOG(AUTH, DEBUG) << "Checking internal password for user '" << loginName << "'";
|
LMS_LOG(AUTH, DEBUG) << "Checking internal password for user '" << loginName << "'";
|
||||||
|
|
||||||
Database::User::PasswordHash passwordHash;
|
Database::User::PasswordHash passwordHash;
|
||||||
{
|
{
|
||||||
|
Database::Session& session {getDbSession()};
|
||||||
auto transaction {session.createSharedTransaction()};
|
auto transaction {session.createSharedTransaction()};
|
||||||
|
|
||||||
const Database::User::pointer user {Database::User::getByLoginName(session, loginName)};
|
const Database::User::pointer user {Database::User::getByLoginName(session, loginName)};
|
||||||
@@ -96,10 +95,11 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)};
|
const Database::User::PasswordHash passwordHash {hashPassword(newPassword)};
|
||||||
|
|
||||||
|
Database::Session& session {getDbSession()};
|
||||||
auto transaction {session.createUniqueTransaction()};
|
auto transaction {session.createUniqueTransaction()};
|
||||||
|
|
||||||
Database::User::pointer user {Database::User::getById(session, userId)};
|
Database::User::pointer user {Database::User::getById(session, userId)};
|
||||||
@@ -117,7 +117,7 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.modify()->setPasswordHash(passwordHash);
|
user.modify()->setPasswordHash(passwordHash);
|
||||||
getAuthTokenService().clearAuthTokens(session, userId);
|
getAuthTokenService().clearAuthTokens(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::User::PasswordHash
|
Database::User::PasswordHash
|
||||||
|
|||||||
@@ -33,16 +33,14 @@ namespace Auth
|
|||||||
class InternalPasswordService : public PasswordServiceBase
|
class InternalPasswordService : public PasswordServiceBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
InternalPasswordService(std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService);
|
InternalPasswordService(Database::Db& db, std::size_t maxThrottlerEntries, IAuthTokenService& authTokenService);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool checkUserPassword(Database::Session& session,
|
bool checkUserPassword(std::string_view loginName, std::string_view password) override;
|
||||||
std::string_view loginName,
|
|
||||||
std::string_view password) override;
|
|
||||||
|
|
||||||
bool canSetPasswords() const override;
|
bool canSetPasswords() const override;
|
||||||
PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view loginName, const PasswordValidationContext& context) 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;
|
Database::User::PasswordHash hashPassword(std::string_view password) const;
|
||||||
void hashRandomPassword() const;
|
void hashRandomPassword() const;
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ namespace Auth
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool
|
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
|
try
|
||||||
{
|
{
|
||||||
@@ -193,7 +193,7 @@ namespace Auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PAMPasswordService::setPassword(Database::Session&, Database::UserId, std::string_view)
|
PAMPasswordService::setPassword(Database::UserId, std::string_view)
|
||||||
{
|
{
|
||||||
throw NotImplementedException {};
|
throw NotImplementedException {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,14 +31,9 @@ namespace Auth
|
|||||||
using PasswordServiceBase::PasswordServiceBase;
|
using PasswordServiceBase::PasswordServiceBase;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool checkUserPassword(Database::Session& session,
|
bool checkUserPassword(std::string_view loginName,std::string_view password) override;
|
||||||
std::string_view loginName,
|
|
||||||
std::string_view password) override;
|
|
||||||
|
|
||||||
bool canSetPasswords() const override;
|
bool canSetPasswords() const override;
|
||||||
PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view loginName, const PasswordValidationContext& context) const override;
|
PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view loginName, const PasswordValidationContext& context) const override;
|
||||||
void setPassword(Database::Session& session,
|
void setPassword(Database::UserId userId, std::string_view newPassword) override;
|
||||||
Database::UserId userId,
|
|
||||||
std::string_view newPassword) override;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
class Session;
|
class Db;
|
||||||
class User;
|
class User;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,12 +63,12 @@ namespace Auth
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Provided token is only accepted once
|
// 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
|
// Returns a one time token
|
||||||
virtual std::string createAuthToken(Database::Session& session, Database::UserId userid, const Wt::WDateTime& expiry) = 0;
|
virtual std::string createAuthToken(Database::UserId userid, const Wt::WDateTime& expiry) = 0;
|
||||||
virtual void clearAuthTokens(Database::Session& session, Database::UserId userid) = 0;
|
virtual void clearAuthTokens(Database::UserId userid) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IAuthTokenService> createAuthTokenService(std::size_t maxThrottlerEntryCount);
|
std::unique_ptr<IAuthTokenService> createAuthTokenService(Database::Db& db, std::size_t maxThrottlerEntryCount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
|
class Db;
|
||||||
class Session;
|
class Session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,9 +61,9 @@ namespace Auth
|
|||||||
std::optional<Database::UserId> userId {};
|
std::optional<Database::UserId> userId {};
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual CheckResult processEnv(Database::Session& session, const Wt::WEnvironment& env) = 0;
|
virtual CheckResult processEnv(const Wt::WEnvironment& env) = 0;
|
||||||
virtual CheckResult processRequest(Database::Session& session, const Wt::Http::Request& request) = 0;
|
virtual CheckResult processRequest(const Wt::Http::Request& request) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IEnvService> createEnvService(std::string_view backendName);
|
std::unique_ptr<IEnvService> createEnvService(std::string_view backendName, Database::Db& db);
|
||||||
} // namespace Auth
|
} // namespace Auth
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
class Session;
|
class Db;
|
||||||
class User;
|
class User;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,8 +56,7 @@ namespace Auth
|
|||||||
std::optional<Database::UserId> userId {};
|
std::optional<Database::UserId> userId {};
|
||||||
std::optional<Wt::WDateTime> expiry {};
|
std::optional<Wt::WDateTime> expiry {};
|
||||||
};
|
};
|
||||||
virtual CheckResult checkUserPassword(Database::Session& session,
|
virtual CheckResult checkUserPassword(const boost::asio::ip::address& clientAddress,
|
||||||
const boost::asio::ip::address& clientAddress,
|
|
||||||
std::string_view loginName,
|
std::string_view loginName,
|
||||||
std::string_view password) = 0;
|
std::string_view password) = 0;
|
||||||
|
|
||||||
@@ -70,9 +69,9 @@ namespace Auth
|
|||||||
MustMatchLoginName,
|
MustMatchLoginName,
|
||||||
};
|
};
|
||||||
virtual PasswordAcceptabilityResult checkPasswordAcceptability(std::string_view password, const PasswordValidationContext& context) const = 0;
|
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<IPasswordService> createPasswordService(std::string_view authPasswordBackend, std::size_t maxThrottlerEntryCount, IAuthTokenService& authTokenService);
|
std::unique_ptr<IPasswordService> createPasswordService(std::string_view authPasswordBackend, Database::Db& db, std::size_t maxThrottlerEntryCount, IAuthTokenService& authTokenService);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ handleChangePassword(RequestContext& context)
|
|||||||
userId = user->getId();
|
userId = user->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Service<Auth::IPasswordService>::get()->setPassword(context.dbSession, userId, password);
|
Service<Auth::IPasswordService>::get()->setPassword(userId, password);
|
||||||
}
|
}
|
||||||
catch (const Auth::PasswordMustMatchLoginNameException&)
|
catch (const Auth::PasswordMustMatchLoginNameException&)
|
||||||
{
|
{
|
||||||
@@ -604,7 +604,7 @@ handleCreateUserRequest(RequestContext& context)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Service<Auth::IPasswordService>::get()->setPassword(context.dbSession, userId, password);
|
Service<Auth::IPasswordService>::get()->setPassword(userId, password);
|
||||||
}
|
}
|
||||||
catch (const Auth::PasswordMustMatchLoginNameException&)
|
catch (const Auth::PasswordMustMatchLoginNameException&)
|
||||||
{
|
{
|
||||||
@@ -1620,7 +1620,7 @@ handleUpdateUserRequest(RequestContext& context)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Service<::Auth::IPasswordService>()->setPassword(context.dbSession, userId, decodePasswordIfNeeded(*password));
|
Service<::Auth::IPasswordService>()->setPassword(userId, decodePasswordIfNeeded(*password));
|
||||||
}
|
}
|
||||||
catch (const Auth::PasswordMustMatchLoginNameException&)
|
catch (const Auth::PasswordMustMatchLoginNameException&)
|
||||||
{
|
{
|
||||||
@@ -2043,22 +2043,18 @@ RequestContext
|
|||||||
SubsonicResource::buildRequestContext(const Wt::Http::Request& request)
|
SubsonicResource::buildRequestContext(const Wt::Http::Request& request)
|
||||||
{
|
{
|
||||||
const Wt::Http::ParameterMap& parameters {request.getParameterMap()};
|
const Wt::Http::ParameterMap& parameters {request.getParameterMap()};
|
||||||
|
|
||||||
const ClientInfo clientInfo {getClientInfo(parameters)};
|
const ClientInfo clientInfo {getClientInfo(parameters)};
|
||||||
|
const Database::UserId userId {authenticateUser(request, clientInfo)};
|
||||||
|
|
||||||
Session& dbSession {_db.getTLSSession()};
|
return {parameters, _db.getTLSSession(), userId, clientInfo, getServerProtocolVersion(clientInfo.name)};
|
||||||
|
|
||||||
const Database::UserId userId {authenticateUser(request, clientInfo, dbSession)};
|
|
||||||
|
|
||||||
return {parameters, dbSession, userId, clientInfo, getServerProtocolVersion(clientInfo.name)};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::UserId
|
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()})
|
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)
|
if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted)
|
||||||
throw UserNotAuthorizedError {};
|
throw UserNotAuthorizedError {};
|
||||||
|
|
||||||
@@ -2066,8 +2062,7 @@ SubsonicResource::authenticateUser(const Wt::Http::Request& request, const Clien
|
|||||||
}
|
}
|
||||||
else if (auto *authPasswordService {Service<::Auth::IPasswordService>::get()})
|
else if (auto *authPasswordService {Service<::Auth::IPasswordService>::get()})
|
||||||
{
|
{
|
||||||
const auto checkResult {authPasswordService->checkUserPassword(dbSession,
|
const auto checkResult {authPasswordService->checkUserPassword(boost::asio::ip::address::from_string(request.clientAddress()),
|
||||||
boost::asio::ip::address::from_string(request.clientAddress()),
|
|
||||||
clientInfo.user, clientInfo.password)};
|
clientInfo.user, clientInfo.password)};
|
||||||
|
|
||||||
switch (checkResult.state)
|
switch (checkResult.state)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace API::Subsonic
|
|||||||
static void checkProtocolVersion(ProtocolVersion client, ProtocolVersion server);
|
static void checkProtocolVersion(ProtocolVersion client, ProtocolVersion server);
|
||||||
ClientInfo getClientInfo(const Wt::Http::ParameterMap& parameters);
|
ClientInfo getClientInfo(const Wt::Http::ParameterMap& parameters);
|
||||||
RequestContext buildRequestContext(const Wt::Http::Request& request);
|
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<std::string, ProtocolVersion> _serverProtocolVersionsByClient;
|
const std::unordered_map<std::string, ProtocolVersion> _serverProtocolVersionsByClient;
|
||||||
Database::Db& _db;
|
Database::Db& _db;
|
||||||
|
|||||||
+3
-3
@@ -245,12 +245,12 @@ int main(int argc, char* argv[])
|
|||||||
const std::string authenticationBackend {StringUtils::stringToLower(config->getString("authentication-backend", "internal"))};
|
const std::string authenticationBackend {StringUtils::stringToLower(config->getString("authentication-backend", "internal"))};
|
||||||
if (authenticationBackend == "internal" || authenticationBackend == "pam")
|
if (authenticationBackend == "internal" || authenticationBackend == "pam")
|
||||||
{
|
{
|
||||||
authTokenService.assign(Auth::createAuthTokenService(config->getULong("login-throttler-max-entriees", 10000)));
|
authTokenService.assign(Auth::createAuthTokenService(database, config->getULong("login-throttler-max-entriees", 10000)));
|
||||||
authPasswordService.assign(Auth::createPasswordService(authenticationBackend, config->getULong("login-throttler-max-entriees", 10000), *authTokenService.get()));
|
authPasswordService.assign(Auth::createPasswordService(authenticationBackend, database, config->getULong("login-throttler-max-entriees", 10000), *authTokenService.get()));
|
||||||
}
|
}
|
||||||
else if (authenticationBackend == "http-headers")
|
else if (authenticationBackend == "http-headers")
|
||||||
{
|
{
|
||||||
authEnvService.assign(Auth::createEnvService(authenticationBackend));
|
authEnvService.assign(Auth::createEnvService(authenticationBackend, database));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw LmsException {"Bad value '" + authenticationBackend + "' for 'authentication-backend'"};
|
throw LmsException {"Bad value '" + authenticationBackend + "' for 'authentication-backend'"};
|
||||||
|
|||||||
+2
-3
@@ -49,7 +49,7 @@ static
|
|||||||
void
|
void
|
||||||
createAuthToken(Database::UserId userId, const Wt::WDateTime& expiry)
|
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,
|
LmsApp->setCookie(authCookieName,
|
||||||
secret,
|
secret,
|
||||||
@@ -67,7 +67,7 @@ processAuthToken(const Wt::WEnvironment& env)
|
|||||||
if (!authCookie)
|
if (!authCookie)
|
||||||
return std::nullopt;
|
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)
|
switch (res.state)
|
||||||
{
|
{
|
||||||
case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::Denied:
|
case ::Auth::IAuthTokenService::AuthTokenProcessResult::State::Denied:
|
||||||
@@ -131,7 +131,6 @@ class AuthModel : public Wt::WFormModel
|
|||||||
if (field == PasswordField)
|
if (field == PasswordField)
|
||||||
{
|
{
|
||||||
const auto checkResult {Service<::Auth::IPasswordService>::get()->checkUserPassword(
|
const auto checkResult {Service<::Auth::IPasswordService>::get()->checkUserPassword(
|
||||||
LmsApp->getDbSession(),
|
|
||||||
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
||||||
valueText(LoginNameField).toUTF8(),
|
valueText(LoginNameField).toUTF8(),
|
||||||
valueText(PasswordField).toUTF8())};
|
valueText(PasswordField).toUTF8())};
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ LmsApplication::create(const Wt::WEnvironment& env, Database::Db& db, LmsApplica
|
|||||||
{
|
{
|
||||||
if (auto *authEnvService {Service<::Auth::IEnvService>::get()})
|
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)
|
if (checkResult.state != ::Auth::IEnvService::CheckResult::State::Granted)
|
||||||
{
|
{
|
||||||
LMS_LOG(UI, ERROR) << "Cannot authenticate user from environment!";
|
LMS_LOG(UI, ERROR) << "Cannot authenticate user from environment!";
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ class SettingsModel : public Wt::WFormModel
|
|||||||
|
|
||||||
if (_authPasswordService && !valueText(PasswordField).empty())
|
if (_authPasswordService && !valueText(PasswordField).empty())
|
||||||
{
|
{
|
||||||
_authPasswordService->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8());
|
_authPasswordService->setPassword(user->getId(), valueText(PasswordField).toUTF8());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class InitWizardModel : public Wt::WFormModel
|
|||||||
|
|
||||||
Database::User::pointer user {Database::User::create(LmsApp->getDbSession(), valueText(AdminLoginField).toUTF8())};
|
Database::User::pointer user {Database::User::create(LmsApp->getDbSession(), valueText(AdminLoginField).toUTF8())};
|
||||||
user.modify()->setType(Database::UserType::ADMIN);
|
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)
|
bool validateField(Field field)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class UserModel : public Wt::WFormModel
|
|||||||
throw UserNotFoundException {};
|
throw UserNotFoundException {};
|
||||||
|
|
||||||
if (_authPasswordService && !valueText(PasswordField).empty())
|
if (_authPasswordService && !valueText(PasswordField).empty())
|
||||||
_authPasswordService->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8());
|
_authPasswordService->setPassword(user->getId(), valueText(PasswordField).toUTF8());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -103,7 +103,7 @@ class UserModel : public Wt::WFormModel
|
|||||||
user.modify()->setType(Database::UserType::DEMO);
|
user.modify()->setType(Database::UserType::DEMO);
|
||||||
|
|
||||||
if (_authPasswordService)
|
if (_authPasswordService)
|
||||||
_authPasswordService->setPassword(LmsApp->getDbSession(), user->getId(), valueText(PasswordField).toUTF8());
|
_authPasswordService->setPassword(user->getId(), valueText(PasswordField).toUTF8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ namespace UserInterface
|
|||||||
return Wt::WValidator::validate(input);
|
return Wt::WValidator::validate(input);
|
||||||
|
|
||||||
const auto checkResult {Service<::Auth::IPasswordService>::get()->checkUserPassword(
|
const auto checkResult {Service<::Auth::IPasswordService>::get()->checkUserPassword(
|
||||||
LmsApp->getDbSession(),
|
|
||||||
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
boost::asio::ip::address::from_string(LmsApp->environment().clientAddress()),
|
||||||
LmsApp->getUserLoginName(),
|
LmsApp->getUserLoginName(),
|
||||||
input.toUTF8())};
|
input.toUTF8())};
|
||||||
|
|||||||
Reference in New Issue
Block a user