#include "User.h" #include "BlogUserDatabase.h" #include class TransactionImpl : public Wt::Auth::AbstractUserDatabase::Transaction, public Wt::Dbo::Transaction { public: TransactionImpl(Wt::Dbo::Session &session) : Wt::Dbo::Transaction(session) { } virtual ~TransactionImpl() noexcept(false) { } virtual void commit() { Wt::Dbo::Transaction::commit(); } virtual void rollback() { Wt::Dbo::Transaction::rollback(); } }; class InvalidUser : public std::runtime_error { public: InvalidUser(const std::string &id) : std::runtime_error("Invalid user: " + id) { } }; BlogUserDatabase::BlogUserDatabase(Wt::Dbo::Session &session) : m_session(session) { } BlogUserDatabase::~BlogUserDatabase() { } Wt::Dbo::ptr BlogUserDatabase::find(const Wt::Auth::User &user) const { getUser(user.id()); return m_user; } Wt::Auth::User BlogUserDatabase::find(Wt::Dbo::ptr user) const { m_user = user; return Wt::Auth::User(std::to_string(m_user.id()), *this); } BlogUserDatabase::Transaction *BlogUserDatabase::startTransaction() { return new TransactionImpl(m_session); } Wt::Auth::User BlogUserDatabase::findWithId(const std::string &id) const { getUser(id); if (m_user) return Wt::Auth::User(id, *this); else return Wt::Auth::User(); } Wt::Auth::User BlogUserDatabase::findWithIdentity(const std::string &provider, const Wt::WString &identity) const { Wt::Dbo::Transaction t(m_session); if (provider == Wt::Auth::Identity::LoginName) { if (!m_user || m_user->name != identity) m_user = m_session.find().where("name = ?").bind(identity); } else m_user = m_session.find().where("oauth_id = ?").bind(identity.toUTF8()).where("oauth_provider = ?").bind(provider); t.commit(); if (m_user) return Wt::Auth::User(std::to_string(m_user.id()), *this); else return Wt::Auth::User(); } void BlogUserDatabase::addIdentity(const Wt::Auth::User &user, const std::string &provider, const Wt::WString &identity) { WithUser find(*this, user); if (provider == Wt::Auth::Identity::LoginName) m_user.modify()->name = identity; else { m_user.modify()->oAuthProvider = provider; m_user.modify()->oAuthId = identity.toUTF8(); } } void BlogUserDatabase::removeIdentity(const Wt::Auth::User &user, const std::string &provider) { WithUser find(*this, user); if (provider == Wt::Auth::Identity::LoginName) m_user.modify()->name = ""; else if (provider == m_user->oAuthProvider) { m_user.modify()->oAuthProvider = std::string(); m_user.modify()->oAuthId = std::string(); } } Wt::WString BlogUserDatabase::identity(const Wt::Auth::User &user, const std::string &provider) const { WithUser find(*this, user); if (provider == Wt::Auth::Identity::LoginName) return m_user->name; else if (provider == m_user->oAuthProvider) return Wt::WString(m_user->oAuthId); else return Wt::WString::Empty; } void BlogUserDatabase::setLastLoginAttempt(const Wt::Auth::User &user, const Wt::WDateTime &t) { WithUser find(*this, user); m_user.modify()->lastLoginAttempt = t; } Wt::Auth::PasswordHash BlogUserDatabase::password(const Wt::Auth::User &user) const { WithUser find(*this, user); return Wt::Auth::PasswordHash(m_user->passwordMethod, m_user->passwordSalt, m_user->password); } void BlogUserDatabase::setPassword(const Wt::Auth::User &user, const Wt::Auth::PasswordHash &password) { WithUser find(*this, user); m_user.modify()->password = password.value(); m_user.modify()->passwordMethod = password.function(); m_user.modify()->passwordSalt = password.salt(); } BlogUserDatabase::WithUser::WithUser(const BlogUserDatabase &self, const Wt::Auth::User &user) : transaction(self.m_session) { self.getUser(user.id()); if (!self.m_user) throw InvalidUser(user.id()); } BlogUserDatabase::WithUser::~WithUser() { transaction.commit(); } void BlogUserDatabase::getUser(const std::string &id) const { if (!m_user || std::to_string(m_user.id()) != id) { Wt::Dbo::Transaction t(m_session); m_user = m_session.find().where("id = ?").bind(User::stringToId(id)); t.commit(); } }