#include "usersimpl.h" #include "users.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // IWYU pragma: no_include "resourcePool.impl.h" namespace Gentoo::Service { Users::Users(const DB::ConnectionPoolPtr & ro, const DB::ConnectionPoolPtr & rw) : rodb {ro}, rwdb {rw} { } Gentoo::UserPtr Users::authenticate(const std::string_view username, const std::string_view password, const Ice::Current &) { return rodb.fetchCache(sql::users::authenticate, 30, username, password); } Gentoo::UserPtr Users::verify(const std::string_view username, const std::string_view verifyguid, const Ice::Current &) { return rwdb.fetch(sql::users::verify, username, verifyguid); } Gentoo::UserPtr Users::get(Ice::Int id, const Ice::Current &) { return rodb.fetch(sql::users::get, id); } Gentoo::NewUserPtr Users::getNew(const std::string_view username, const std::string_view password, const Ice::Current &) { return rodb.fetch(sql::users::getNew, username, password); } Gentoo::UserPtr Users::find(const std::string_view username, const Ice::Current &) { return rodb.fetch(sql::users::find, username); } template Gentoo::NewUserPtr Users::authOrCreate(IceTray::TransactionalDatabaseClient & db, const std::string_view & username, const std::string_view & password, const std::string_view & realname, const std::string_view & email) { auto existing = db.template fetch>(sql::users::getNew, username, password); if (existing && *existing) { return *existing; } return db.template fetch(sql::users::create, username, password, realname, email); } Gentoo::NewUserPtr Users::create(const std::string_view username, const std::string_view password, const std::string_view realname, const std::string_view email, const Ice::Current &) { static const std::regex invalid {".*://.*"}; static const std::regex validUsername {".+"}; static const std::regex validRealname {".+"}; static const std::regex validEmail {"[^ ]+@[^ ]+(\\.[^ ]+)+"}; auto notifications = IceTray::Cube::get(); auto mailServer = IceTray::Cube::get(); const auto check = [](const auto in, const auto & valid, const auto & invalid) { if (!std::regex_match(in.begin(), in.end(), valid) || std::regex_match(in.begin(), in.end(), invalid)) { throw Rejected {}; } }; check(username, validUsername, invalid); check(realname, validRealname, invalid); check(email, validEmail, invalid); auto tx = rwdb.transactional(); auto newUser = authOrCreate(tx, username, password, realname, email); auto mail = notifications->getSignup(newUser); mailServer->sendEmail(mail); return newUser; } void Users::mailshotsent(Ice::Int id, const Ice::Current &) { rwdb.modify(sql::users::mailshotsent, id); } void Users::remove(Ice::Int id, const std::string_view password, const Ice::Current &) { rwdb.modify(sql::users::safeDelete, id, password); } void Users::prune(const Ice::Current & current) { auto properties = current.adapter->getCommunicator()->getProperties(); auto prunePeriod = properties->getPropertyWithDefault("GentooBrowseAPI.Users.PrunePeriod", "8 weeks"); rwdb.modify(sql::users::prune, prunePeriod); } void Users::track(Ice::Int userId, Ice::Int packageId, const Ice::Current &) { rwdb.modify(sql::users::track, userId, packageId); } void Users::untrack(Ice::Int userId, Ice::Int packageId, const Ice::Current &) { rwdb.modify(sql::users::untrack, userId, packageId); } Gentoo::PackageIds Users::tracked(Ice::Int userId, const Ice::Current &) { return rodb.fetchCache(sql::users::tracked, 10, userId); } }