Moved away from Wt::Auth and use a simplified (?) login/password system with a login throttler based on IP address

This commit is contained in:
emeric
2019-07-26 14:02:05 +02:00
parent 38ce2600d2
commit 9b902b1a59
44 changed files with 1226 additions and 650 deletions
+9 -9
View File
@@ -22,8 +22,9 @@
#include <Wt/WFormModel.h>
#include <Wt/WLineEdit.h>
#include <Wt/WPushButton.h>
#include <Wt/Auth/Identity.h>
#include "auth/AuthService.hpp"
#include "main/Service.hpp"
#include "utils/Exception.hpp"
#include "utils/Logger.hpp"
@@ -54,6 +55,8 @@ class InitWizardModel : public Wt::WFormModel
void saveData()
{
const Database::User::PasswordHash passwordHash {getService<::Auth::AuthService>()->hashPassword(valueText(PasswordField).toUTF8())};
auto transaction(LmsApp->getDbSession().createUniqueTransaction());
// Check if a user already exist
@@ -61,7 +64,7 @@ class InitWizardModel : public Wt::WFormModel
if (!Database::User::getAll(LmsApp->getDbSession()).empty())
throw LmsException("Admin user already created");
Database::User::pointer user {LmsApp->getDbSession().createUser(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8())};
Database::User::pointer user {Database::User::create(LmsApp->getDbSession(), valueText(AdminLoginField).toUTF8(), passwordHash)};
user.modify()->setType(Database::User::Type::ADMIN);
}
@@ -74,11 +77,8 @@ class InitWizardModel : public Wt::WFormModel
if (!valueText(PasswordField).empty())
{
// Evaluate the strength of the password
auto res = Database::Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField),
valueText(AdminLoginField), "");
if (!res.isValid())
error = res.message();
if (!getService<::Auth::AuthService>()->evaluatePasswordStrength(valueText(AdminLoginField).toUTF8(), valueText(PasswordField).toUTF8()))
error = Wt::WString::tr("Lms.password-too-weak");
}
else
return Wt::WFormModel::validateField(field);
@@ -126,7 +126,7 @@ InitWizardView::InitWizardView()
setFormWidget(InitWizardModel::PasswordConfirmField, std::move(passwordConfirmEdit));
Wt::WPushButton* saveButton = bindNew<Wt::WPushButton>("create-btn", Wt::WString::tr("Lms.create"));
saveButton->clicked().connect(std::bind([=]
saveButton->clicked().connect([=]
{
updateModel(model.get());
@@ -138,7 +138,7 @@ InitWizardView::InitWizardView()
}
updateView(model.get());
}));
});
updateView(model.get());
}
+26 -18
View File
@@ -28,7 +28,9 @@
#include <Wt/WFormModel.h>
#include "auth/AuthService.hpp"
#include "database/User.hpp"
#include "main/Service.hpp"
#include "utils/Config.hpp"
#include "utils/Exception.hpp"
#include "utils/Logger.hpp"
@@ -78,6 +80,10 @@ class UserModel : public Wt::WFormModel
void saveData()
{
boost::optional<Database::User::PasswordHash> passwordHash;
if (!valueText(PasswordField).empty())
passwordHash = getService<::Auth::AuthService>()->hashPassword(valueText(PasswordField).toUTF8());
auto transaction {LmsApp->getDbSession().createUniqueTransaction()};
if (_userId)
@@ -86,8 +92,11 @@ class UserModel : public Wt::WFormModel
Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
// Account
if (!valueText(PasswordField).empty())
LmsApp->getDbSession().updateUserPassword(user, valueText(PasswordField).toUTF8());
if (passwordHash)
{
user.modify()->setPasswordHash(*passwordHash);
user.modify()->clearAuthTokens();
}
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromString(valueText(AudioTranscodeBitrateLimitField))};
if (transcodeBitrateLimitRow)
@@ -96,7 +105,7 @@ class UserModel : public Wt::WFormModel
else
{
// Create user
Database::User::pointer user = LmsApp->getDbSession().createUser(valueText(LoginField).toUTF8(), valueText(PasswordField).toUTF8());
Database::User::pointer user {Database::User::create(LmsApp->getDbSession(), valueText(LoginField).toUTF8(), *passwordHash)};
auto transcodeBitrateLimitRow {_bitrateModel->getRowFromString(valueText(AudioTranscodeBitrateLimitField))};
if (transcodeBitrateLimitRow )
@@ -125,17 +134,17 @@ class UserModel : public Wt::WFormModel
setValue(AudioTranscodeBitrateLimitField, _bitrateModel->getString(*transcodeBitrateLimitRow));
}
Wt::WString getLoginName() const
std::string getLoginName() const
{
if (_userId)
{
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *_userId)};
return LmsApp->getDbSession().getUserLoginName(user);
return user->getLoginName();
}
else
return valueText(LoginField);
return valueText(LoginField).toUTF8();
}
bool validateField(Field field)
@@ -144,7 +153,9 @@ class UserModel : public Wt::WFormModel
if (field == LoginField)
{
const Database::User::pointer user {LmsApp->getDbSession().getUser(valueText(LoginField).toUTF8())};
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getByLoginName(LmsApp->getDbSession(), valueText(LoginField).toUTF8())};
if (user)
error = Wt::WString::tr("Lms.Admin.User.user-already-exists");
}
@@ -154,17 +165,15 @@ class UserModel : public Wt::WFormModel
{
if (Wt::asNumber(value(DemoField)))
{
//Demo account: password must be the same as the login name
// Demo account: password must be the same as the login name
if (valueText(PasswordField) != getLoginName())
error = Wt::WString::tr("Lms.Admin.User.demo-password-invalid");
}
else
{
// Evaluate the strength of the password for non demo accounts
auto res = Database::Session::getPasswordService().strengthValidator()->evaluateStrength(valueText(PasswordField), getLoginName(), "");
if (!res.isValid())
error = res.message();
if (!getService<::Auth::AuthService>()->evaluatePasswordStrength(getLoginName(), valueText(PasswordField).toUTF8()))
error = Wt::WString::tr("Lms.password-too-weak");
}
}
}
@@ -231,13 +240,12 @@ UserView::refreshView()
auto transaction {LmsApp->getDbSession().createSharedTransaction()};
const Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), *userId)};
const std::string loginName {LmsApp->getDbSession().getUserLoginName(user)};
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(loginName), Wt::TextFormat::Plain);
t->setCondition("if-has-last-login-attempt", true);
t->bindString("title", Wt::WString::tr("Lms.Admin.User.user-edit").arg(user->getLoginName()), Wt::TextFormat::Plain);
t->setCondition("if-has-last-login", true);
Wt::WLineEdit *lastLoginAttempt {t->bindNew<Wt::WLineEdit>("last-login-attempt")};
lastLoginAttempt->setText(LmsApp->getDbSession().getUserLastLoginAttempt(user).toString());
lastLoginAttempt->setEnabled(false);
Wt::WLineEdit *lastLogin {t->bindNew<Wt::WLineEdit>("last-login")};
lastLogin->setText(user->getLastLogin().toString());
lastLogin->setEnabled(false);
}
else
{
+2 -2
View File
@@ -68,7 +68,7 @@ UsersView::refreshView()
Wt::WTemplate* entry {_container->addNew<Wt::WTemplate>(Wt::WString::tr("Lms.Admin.Users.template.entry"))};
entry->bindString("name", LmsApp->getDbSession().getUserLoginName(user), Wt::TextFormat::Plain);
entry->bindString("name", user->getLoginName(), Wt::TextFormat::Plain);
// Create tag
if (user->isAdmin() || user->isDemo())
@@ -104,7 +104,7 @@ UsersView::refreshView()
Database::User::pointer user {Database::User::getById(LmsApp->getDbSession(), userId)};
if (user)
LmsApp->getDbSession().removeUser(user);
user.remove();
_container->removeWidget(entry);
}