Introduce HandlerUserSettings to change user settings, e. g. pw changes

This commit is contained in:
Albert S. 2021-03-26 22:50:55 +01:00
parent ac99894157
commit 70c4bfaffa
4 changed files with 91 additions and 0 deletions

View File

@ -1,5 +1,6 @@
#include <atomic>
#include <openssl/evp.h>
#include <mutex>
#include "utils.h"
#include "authenticator.h"
#include "logger.h"

View File

@ -32,6 +32,7 @@ SOFTWARE.
#include "handlercategory.h"
#include "handlerhistory.h"
#include "handlerpagedelete.h"
#include "handlerusersettings.h"
std::unique_ptr<Handler> HandlerFactory::createHandler(const std::string &action, Session &userSession)
{
@ -75,6 +76,10 @@ std::unique_ptr<Handler> HandlerFactory::createHandler(const std::string &action
{
return produce<HandlerHistory>(userSession);
}
if(action == "usersettings")
{
return produce<HandlerUserSettings>(userSession);
}
return produce<HandlerInvalidAction>(userSession);
}

View File

@ -0,0 +1,72 @@
#include "handlerusersettings.h"
#include "../authenticator.h"
#include "../random.h"
#include "../database/exceptions.h"
Response HandlerUserSettings::handleRequest(const Request &r)
{
if(r.getRequestMethod() == "POST")
{
if(r.post("do") == "submit")
{
std::string oldpassword = r.post("oldpassword");
std::string newpassword = r.post("newpassword");
std::string newpasswordconfirm = r.post("newpasswordconfirm");
if(newpassword != newpasswordconfirm)
{
//TODO: is not nice, users has to hit the back button...
return this->errorResponse("Passwords don't match", "The entered new passwords don't match");
}
auto userDao = this->database->createUserDao();
Authenticator authenticator(*userDao);
std::variant<User, AuthenticationError> authresult = authenticator.authenticate(this->userSession->user.login, oldpassword);
if(std::holds_alternative<AuthenticationError>(authresult))
{
return this->errorResponse("Invalid current password", "The old password you entered is invalid");
}
Random r;
std::vector<char> salt = r.getRandom(23);
User user = std::get<User>(authresult);
user.salt = salt;
user.password = authenticator.hash(newpassword, user.salt);
if(user.password.empty())
{
Logger::error() << "Authenticator returned empty hash";
return this->errorResponse("Error", "An error occured while trying to store new password");
}
try
{
userDao->save(user);
}
catch(const DatabaseException &e)
{
Logger::debug() << "Error saving user: " << e.what();
return errorResponse("Error", "A database error occured while trying to save user with new settings");
}
return Response::redirectTemporarily(this->urlProvider->userSettings());
}
}
TemplatePage &userSettingsPage = this->templ->getPage("usersettings");
setGeneralVars(userSettingsPage);
userSettingsPage.setVar("usersettingsurl", urlProvider->userSettings());
userSettingsPage.setVar("title", createPageTitle("User settings - " + this->userSession->user.login));
Response result;
result.setStatus(200);
result.setBody(userSettingsPage.render());
return result;
}
bool HandlerUserSettings::canAccess(const Permissions &perms)
{
return this->userSession->loggedIn;
}
std::string HandlerUserSettings::accessErrorMessage()
{
return "Only logged-in users can change their settings";
}

View File

@ -0,0 +1,13 @@
#ifndef HANDLERUSERSETTINGS_H
#define HANDLERUSERSETTINGS_H
#include "handler.h"
class HandlerUserSettings : public Handler
{
public:
using Handler::Handler;
Response handleRequest(const Request &r);
bool canAccess(const Permissions &perms);
std::string accessErrorMessage();
};
#endif // HANDLERUSERSETTINGS_H