easy access to admin information
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 9.0.2, 2024-05-08T20:43:18. -->
|
<!-- Written by QtCreator 9.0.2, 2024-05-29T13:37:12. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
|
|||||||
@@ -217,3 +217,6 @@ main {
|
|||||||
.output-box-format-other {
|
.output-box-format-other {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
.padding-right {
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
|||||||
119
src/app.cpp
119
src/app.cpp
@@ -27,6 +27,7 @@
|
|||||||
#include <Wt/Json/Array.h>
|
#include <Wt/Json/Array.h>
|
||||||
#include <Wt/Json/Object.h>
|
#include <Wt/Json/Object.h>
|
||||||
#include <Wt/Json/Serializer.h>
|
#include <Wt/Json/Serializer.h>
|
||||||
|
#include <Wt/Json/Parser.h>
|
||||||
#include <Wt/WLink.h>
|
#include <Wt/WLink.h>
|
||||||
#include <Wt/WFileResource.h>
|
#include <Wt/WFileResource.h>
|
||||||
#include <Wt/WTable.h>
|
#include <Wt/WTable.h>
|
||||||
@@ -524,11 +525,129 @@ void App::onInternalPathChanged(const std::string &path) {
|
|||||||
showStandardPage();
|
showStandardPage();
|
||||||
} else if (path == "/partners") {
|
} else if (path == "/partners") {
|
||||||
showPartnerSites();
|
showPartnerSites();
|
||||||
|
} else if (path == "/adm/info/logins" || path == "/adm/info/starts") {
|
||||||
|
showAdminPage(path);
|
||||||
} else {
|
} else {
|
||||||
setInternalPath("/", true);
|
setInternalPath("/", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::showAdminPage(std::string page) {
|
||||||
|
if (isLoggedInAsAdmin) {
|
||||||
|
if (page == "/adm/info/logins") {
|
||||||
|
showAdminLogins();
|
||||||
|
} else if (page == "/adm/info/starts") {
|
||||||
|
showAdminStarts();
|
||||||
|
} else {
|
||||||
|
showPageNotExists();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
showAdminLogin(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::showAdminLogin(std::string page) {
|
||||||
|
contentContainer_->clear();
|
||||||
|
auto loginContainer = contentContainer_->addNew<Wt::WContainerWidget>();
|
||||||
|
loginContainer->addNew<Wt::WText>("Name:");
|
||||||
|
auto nameEdit = loginContainer->addNew<Wt::WLineEdit>();
|
||||||
|
loginContainer->addNew<Wt::WBreak>();
|
||||||
|
loginContainer->addNew<Wt::WText>("Password:");
|
||||||
|
auto passwordEdit = loginContainer->addNew<Wt::WLineEdit>();
|
||||||
|
passwordEdit->setEchoMode(Wt::EchoMode::Password);
|
||||||
|
loginContainer->addNew<Wt::WBreak>();
|
||||||
|
auto loginButton = loginContainer->addNew<Wt::WPushButton>("Login");
|
||||||
|
auto messageLabel = loginContainer->addNew<Wt::WText>();
|
||||||
|
auto loginAction = [=, this] {
|
||||||
|
if (nameEdit->text().toUTF8() == adminName && passwordEdit->text().toUTF8() == adminPassword) {
|
||||||
|
isLoggedInAsAdmin = true;
|
||||||
|
messageLabel->setText("");
|
||||||
|
showAdminPage(page);
|
||||||
|
} else {
|
||||||
|
isLoggedInAsAdmin = false;
|
||||||
|
messageLabel->setText("Incorrect username or password.");
|
||||||
|
messageLabel->decorationStyle().setForegroundColor(Wt::WColor("red"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
loginButton->clicked().connect(loginAction);
|
||||||
|
passwordEdit->enterPressed().connect(loginAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::showPageNotExists() {
|
||||||
|
contentContainer_->clear();
|
||||||
|
auto errorMessageLabel = contentContainer_->addNew<Wt::WText>("Error 400 - Page not found");
|
||||||
|
errorMessageLabel->decorationStyle().setForegroundColor(Wt::WColor("red"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::showAdminLogins() {
|
||||||
|
contentContainer_->clear();
|
||||||
|
contentContainer_->addNew<Wt::WText>("<h2>Logins</h2>", Wt::TextFormat::UnsafeXHTML);
|
||||||
|
std::ifstream file("../logs/logins.log");
|
||||||
|
if (!file.is_open()) {
|
||||||
|
contentContainer_->addNew<Wt::WText>("Error opening file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << file.rdbuf();
|
||||||
|
std::string fileContent = buffer.str();
|
||||||
|
Wt::Json::Array jsonArray;
|
||||||
|
Wt::Json::parse(fileContent, jsonArray);
|
||||||
|
auto table = contentContainer_->addNew<Wt::WTable>();
|
||||||
|
table->setHeaderCount(1);
|
||||||
|
table->elementAt(0, 0)->addNew<Wt::WText>("Name");
|
||||||
|
table->elementAt(0, 1)->addNew<Wt::WText>("Country");
|
||||||
|
table->elementAt(0, 2)->addNew<Wt::WText>("Gender");
|
||||||
|
table->elementAt(0, 3)->addNew<Wt::WText>("Age");
|
||||||
|
int row = 1;
|
||||||
|
for (const auto& item : jsonArray) {
|
||||||
|
Wt::Json::Object jsonData = item;
|
||||||
|
std::string name = jsonData.get("name").orIfNull("");
|
||||||
|
std::string country = jsonData.get("country").orIfNull("");
|
||||||
|
std::string gender = jsonData.get("gender").orIfNull("");
|
||||||
|
int age = jsonData.get("age").orIfNull(0);
|
||||||
|
auto nameCell = table->elementAt(row, 0)->addNew<Wt::WText>(name);
|
||||||
|
nameCell->setStyleClass("padding-right");
|
||||||
|
auto countryCell = table->elementAt(row, 1)->addNew<Wt::WText>(country);
|
||||||
|
countryCell->setStyleClass("padding-right");
|
||||||
|
auto genderCell = table->elementAt(row, 2)->addNew<Wt::WText>(gender);
|
||||||
|
genderCell->setStyleClass("padding-right");
|
||||||
|
table->elementAt(row, 3)->addNew<Wt::WText>(std::to_string(age));
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void App::showAdminStarts() {
|
||||||
|
contentContainer_->clear();
|
||||||
|
contentContainer_->addNew<Wt::WText>("<h2>Chat starts</h2>", Wt::TextFormat::UnsafeXHTML);
|
||||||
|
std::ifstream file("../logs/starts.log");
|
||||||
|
if (!file.is_open()) {
|
||||||
|
contentContainer_->addNew<Wt::WText>("Error opening file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto table = contentContainer_->addNew<Wt::WTable>();
|
||||||
|
table->setHeaderCount(1);
|
||||||
|
table->elementAt(0, 0)->addNew<Wt::WText>("Datum");
|
||||||
|
table->elementAt(0, 1)->addNew<Wt::WText>("Uhrzeit");
|
||||||
|
std::string line;
|
||||||
|
int row = 1;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
std::istringstream ss(line);
|
||||||
|
std::tm tm{};
|
||||||
|
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||||
|
std::ostringstream dateStream;
|
||||||
|
std::ostringstream timeStream;
|
||||||
|
dateStream.imbue(std::locale("de_DE.utf8"));
|
||||||
|
timeStream.imbue(std::locale("de_DE.utf8"));
|
||||||
|
dateStream << std::put_time(&tm, "%d.%m.%Y");
|
||||||
|
timeStream << std::put_time(&tm, "%H:%M:%S");
|
||||||
|
auto dateCell = table->elementAt(row, 0)->addNew<Wt::WText>(dateStream.str());
|
||||||
|
dateCell->setStyleClass("padding-right");
|
||||||
|
table->elementAt(row, 1)->addNew<Wt::WText>(timeStream.str());
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Wt::WContainerWidget* App::createSmileyButton(Wt::WHBoxLayout* inputLayout, Wt::WLineEdit* inputLine, std::shared_ptr<int> cursorPosition) {
|
Wt::WContainerWidget* App::createSmileyButton(Wt::WHBoxLayout* inputLayout, Wt::WLineEdit* inputLine, std::shared_ptr<int> cursorPosition) {
|
||||||
auto smileyButton = inputLayout->addNew<Wt::WContainerWidget>();
|
auto smileyButton = inputLayout->addNew<Wt::WContainerWidget>();
|
||||||
smileyButton->addNew<Wt::WImage>(Wt::WLink("/smileys.png"));
|
smileyButton->addNew<Wt::WImage>(Wt::WLink("/smileys.png"));
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ public:
|
|||||||
~App();
|
~App();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const std::string adminName {"comiciusadmin"};
|
||||||
|
const std::string adminPassword {"p3Lv9!7?+Qq"};
|
||||||
|
|
||||||
std::map<Wt::WString, Wt::WString> genders_ {
|
std::map<Wt::WString, Wt::WString> genders_ {
|
||||||
{"F", "Female"},
|
{"F", "Female"},
|
||||||
{"M", "Male"},
|
{"M", "Male"},
|
||||||
@@ -94,6 +97,7 @@ private:
|
|||||||
Search searchFields;
|
Search searchFields;
|
||||||
Wt::WTimer *loginTimer_;
|
Wt::WTimer *loginTimer_;
|
||||||
Wt::WTimer *timeoutRemainingTimer_;
|
Wt::WTimer *timeoutRemainingTimer_;
|
||||||
|
bool isLoggedInAsAdmin {false};
|
||||||
void setMetaTags();
|
void setMetaTags();
|
||||||
void initApp();
|
void initApp();
|
||||||
void reSetUser();
|
void reSetUser();
|
||||||
@@ -212,6 +216,11 @@ private:
|
|||||||
bool isAnimatedGIF(const Magick::Blob &blob);
|
bool isAnimatedGIF(const Magick::Blob &blob);
|
||||||
void showStandardPage();
|
void showStandardPage();
|
||||||
void onInternalPathChanged(const std::string &path);
|
void onInternalPathChanged(const std::string &path);
|
||||||
|
void showAdminPage(std::string page);
|
||||||
|
void showAdminLogin(std::string page);
|
||||||
|
void showPageNotExists();
|
||||||
|
void showAdminLogins();
|
||||||
|
void showAdminStarts();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APP_H
|
#endif // APP_H
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <Wt/WAny.h>
|
#include <Wt/WAny.h>
|
||||||
#include <Wt/Json/Array.h>
|
#include <Wt/Json/Array.h>
|
||||||
#include <Wt/Json/Serializer.h>
|
#include <Wt/Json/Serializer.h>
|
||||||
|
#include <Wt/Json/Parser.h>
|
||||||
|
#include <Wt/Json/Object.h>
|
||||||
#include <Wt/Auth/HashFunction.h>
|
#include <Wt/Auth/HashFunction.h>
|
||||||
#include <Wt/WLocalDateTime.h>
|
#include <Wt/WLocalDateTime.h>
|
||||||
#include <Wt/Utils.h>
|
#include <Wt/Utils.h>
|
||||||
@@ -61,17 +63,22 @@ void Broadcast::connect(Client *client, const std::function<void ()> &fct) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Broadcast::logClientLogin(const Wt::Json::Object &clientJson) {
|
void Broadcast::logClientLogin(const Wt::Json::Object &clientJson) {
|
||||||
const std::string logFilePath = "/opt/ypchat/logs/logins.log";
|
const std::string logFilePath = "../logs/logins.log";
|
||||||
|
Wt::Json::Array logArray;
|
||||||
std::ifstream infile(logFilePath);
|
std::ifstream infile(logFilePath);
|
||||||
if (!infile.good()) {
|
if (infile.is_open()) {
|
||||||
std::ofstream outfile(logFilePath);
|
std::stringstream buffer;
|
||||||
outfile.close();
|
buffer << infile.rdbuf();
|
||||||
|
std::string fileContent = buffer.str();
|
||||||
|
infile.close();
|
||||||
|
if (!fileContent.empty()) {
|
||||||
|
Wt::Json::parse(fileContent, logArray);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
infile.close();
|
logArray.push_back(clientJson);
|
||||||
std::string clientData = Wt::Json::serialize(clientJson);
|
std::ofstream outfile(logFilePath);
|
||||||
std::ofstream outfile(logFilePath, std::ios_base::app);
|
|
||||||
if (outfile.is_open()) {
|
if (outfile.is_open()) {
|
||||||
outfile << clientData << std::endl;
|
outfile << Wt::Json::serialize(logArray) << std::endl;
|
||||||
outfile.close();
|
outfile.close();
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Fehler beim Öffnen der Datei: " << logFilePath << std::endl;
|
std::cerr << "Fehler beim Öffnen der Datei: " << logFilePath << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user