add optional paramater account state to user search to able to search users which haven't activated there account yet

This commit is contained in:
einhornimmond 2021-03-22 13:03:08 +01:00
parent bf35ff33ad
commit db99a1077e
4 changed files with 89 additions and 11 deletions

View File

@ -12,7 +12,8 @@ Poco::JSON::Object* JsonGetUsers::handle(Poco::Dynamic::Var params)
int session_id = 0;
std::string searchString;
std::string accountState = "";
static std::string emptySearchString = "... empty ...";
// if is json object
if (params.type() == typeid(Poco::JSON::Object::Ptr)) {
Poco::JSON::Object::Ptr paramJsonObject = params.extract<Poco::JSON::Object::Ptr>();
@ -23,6 +24,9 @@ Poco::JSON::Object* JsonGetUsers::handle(Poco::Dynamic::Var params)
/// Throws InvalidAccessException if Var is empty.
try {
paramJsonObject->get("search").convert(searchString);
if (paramJsonObject->has("account_state")) {
paramJsonObject->get("account_state").convert(accountState);
}
paramJsonObject->get("session_id").convert(session_id);
}
catch (Poco::Exception& ex) {
@ -67,17 +71,20 @@ Poco::JSON::Object* JsonGetUsers::handle(Poco::Dynamic::Var params)
}
auto user = session->getNewUser();
if (searchString == emptySearchString) {
searchString = "";
}
if (user.isNull()) {
return customStateError("not found", "Session didn't contain user");
}
else if (searchString == "") {
return customStateError("not found", "Search string is empty");
else if (searchString == "" && (accountState == "" || accountState == "all")) {
return customStateError("not found", "Search string is empty and account_state is all or empty");
}
else if (user->getModel()->getRole() != model::table::ROLE_ADMIN) {
return customStateError("wrong role", "User hasn't correct role");
}
auto results = controller::User::search(searchString);
auto results = controller::User::search(searchString, accountState);
if (!results.size()) {
return stateSuccess();
}

View File

@ -46,24 +46,49 @@ namespace controller {
return Poco::AutoPtr<User>(user);
}
std::vector<User*> User::search(const std::string& searchString)
std::vector<User*> User::search(const std::string& searchString, const std::string& accountState /* = "all" */)
{
auto sm = SessionManager::getInstance();
auto cm = ConnectionManager::getInstance();
auto db = new model::table::User();
static const char* functionName = "User::search";
std::string globalSearch = "%" + searchString + "%";
std::vector<model::table::UserTuple> resultFromDB;
// check if search string is email
/*if (sm->isValid(searchString, VALIDATE_EMAIL)) {
resultFromDB = db->loadFromDB <std::string, model::table::UserTuple>("email", globalSearch);
if (accountState == "email not activated") {
std::vector<std::string> fieldNames = { "first_name", "last_name", "email", "email_checked" };
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
std::vector<model::table::UserTuple> results;
using namespace Poco::Data::Keywords;
Poco::Data::Statement select(session);
// typedef Poco::Tuple<std::string, std::string, std::string, Poco::Nullable<Poco::Data::BLOB>, int> UserTuple;
select << "SELECT id, first_name, last_name, email, pubkey, created, email_checked, disabled FROM " << db->getTableName();
select << " where email_checked = 0 ";
select, into(resultFromDB);
if (searchString != "") {
select << "AND (first_name LIKE ? OR last_name LIKE ? OR email LIKE ?)";
select, useRef(globalSearch), useRef(globalSearch), useRef(globalSearch);
}
try {
select.execute();
}
catch (Poco::Exception& ex) {
ErrorList errors;
errors.addError(new ParamError(functionName, "mysql error ", ex.displayText()));
errors.addError(new ParamError(functionName, "search string", searchString));
errors.addError(new ParamError(functionName, "account state", accountState));
errors.sendErrorsAsEmail();
}
}
else {*/
else {
std::vector<std::string> fieldNames = { "first_name", "last_name", "email" };
std::vector<std::string> fieldValues = { globalSearch, globalSearch, globalSearch };
resultFromDB = db->loadFromDB<std::string, model::table::UserTuple>(fieldNames, fieldValues, model::table::MYSQL_CONDITION_OR);
//}
}
db->release();
db = nullptr;

View File

@ -28,7 +28,7 @@ namespace controller {
static Poco::AutoPtr<User> create();
static Poco::AutoPtr<User> create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de");
static std::vector<User*> search(const std::string& searchString);
static std::vector<User*> search(const std::string& searchString, const std::string& accountState = "all");
//! \brief go through whole db and search users with email_checked = false and schedule resend 7 days after email_opt_in created date
//!

View File

@ -40,10 +40,19 @@ namespace model {
size_t loadFromDB(const std::string& fieldName, const T& fieldValue);
template<class T>
bool isExistInDB(const std::string& fieldName, const T& fieldValue);
template<class WhereFieldType, class Tuple>
std::vector<Tuple> loadFromDB(const std::string& fieldName, const WhereFieldType& fieldValue, int expectedResults = 0);
template<class T1, class T2>
size_t loadFromDB(const std::vector<std::string>& fieldNames, const T1& field1Value, const T2& field2Value, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
template<class Tuple, class T1, class T2, class T3, class T4>
std::vector<Tuple> loadMultipleFromDB(
const std::vector<std::string>& fieldNames,
const T1& field1Value, const T2& field2Value, const T3& field3Value, const T4& field4Value,
MysqlConditionType conditionType = MYSQL_CONDITION_AND);
template<class WhereFieldType, class Tuple>
std::vector<Tuple> loadFromDB(const std::vector<std::string>& fieldNames, const std::vector<WhereFieldType>& fieldValues, MysqlConditionType conditionType = MYSQL_CONDITION_AND, int expectedResults = 0);
bool insertIntoDB(bool loadId);
@ -211,6 +220,43 @@ namespace model {
return resultCount;
}
template<class Tuple, class T1, class T2, class T3, class T4>
std::vector<Tuple> ModelBase::loadMultipleFromDB(
const std::vector<std::string>& fieldNames,
const T1& field1Value, const T2& field2Value, const T3& field3Value, const T4& field4Value,
MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/)
{
auto cm = ConnectionManager::getInstance();
std::vector<Tuple> results;
if (fieldNames.size() != 4) {
addError(new Error(getTableName(), "error in loadFromDB with 4 different field values, fieldNames count isn't 4"));
return results;
}
Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex);
auto session = cm->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
Poco::Data::Statement select = _loadMultipleFromDB(session, fieldNames, conditionType);
select, Poco::Data::Keywords::into(results),
Poco::Data::Keywords::useRef(field1Value), Poco::Data::Keywords::useRef(field2Value),
Poco::Data::Keywords::useRef(field3Value), Poco::Data::Keywords::useRef(field4Value);
size_t resultCount = 0;
try {
resultCount = select.execute();
}
catch (Poco::Exception& ex) {
lock();
addError(new ParamError(getTableName(), "mysql error by selecting with 4 different field types", ex.displayText()));
int count = 0;
for (auto it = fieldNames.begin(); it != fieldNames.end(); it++) {
addError(new ParamError(getTableName(), "field name for select: ", *it));
}
//addError(new ParamError(getTableName(), "field name for select: ", fieldName.data()));
unlock();
}
return resultCount;
}
template<class T>
size_t ModelBase::updateIntoDB(const std::string& fieldName, const T& fieldValue)