commit 7f0cd77b4e3de04c20cac3c27c0220791383458a Author: Bernhard Rosenkränzer Date: Wed Aug 28 00:13:54 2024 +0200 Initial import Not much there yet, just a login dialog and an app list JSON parser diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..57ca388 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.20) +project(configurator) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_CXX_STANDARD 23) + +set(QT_VERSION 6 CACHE STRING "Major version of Qt to use (6 will work, anything else may or may not work)") + +find_package(Qt${QT_VERSION} COMPONENTS Core Gui Widgets WebEngineWidgets REQUIRED) +add_subdirectory(dialogs) +add_executable(configurator main.cpp Configurator.cpp) +target_link_libraries(configurator Qt${QT_VERSION}::Core Qt${QT_VERSION}::Gui Qt${QT_VERSION}::Widgets Qt${QT_VERSION}::WebEngineWidgets Qt${QT_VERSION}::Network dialogs) + +install(TARGETS configurator DESTINATION bin) diff --git a/Configurator.cpp b/Configurator.cpp new file mode 100644 index 0000000..9fea781 --- /dev/null +++ b/Configurator.cpp @@ -0,0 +1,51 @@ +#include "Configurator.h" +#include +#include +#include + +Configurator::Configurator(int &argc, char **&argv):QApplication(argc, argv),_nam(this) { + setQuitOnLastWindowClosed(false); + _loginDialog = new FederatedLogin(0); + _loginDialog->setModal(true); + connect(_loginDialog, &QDialog::accepted, this, &Configurator::loginRequested); + connect(_loginDialog, &QDialog::rejected, this, &QApplication::quit); + _loginDialog->show(); +} + +void Configurator::loginRequested() { + QNetworkRequest *req=new QNetworkRequest("https://dashboard." + _loginDialog->domain() + "/apps"); + connect(&_nam, &QNetworkAccessManager::finished, this, &Configurator::appListReceived); + QNetworkReply *r=_nam.get(*req); +} + +void Configurator::appListReceived(QNetworkReply *reply) { + disconnect(&_nam, &QNetworkAccessManager::finished, this, &Configurator::appListReceived); + if(reply->error() != QNetworkReply::NoError) { + _loginDialog->setMessage(tr("Failed to retrieve app list. Is the domain name correct?")); + _loginDialog->show(); + return; + } + _services=QJsonDocument::fromJson(reply->readAll()); + if(!_services.isArray()) { + _loginDialog->setMessage(tr("App list did not return an array. Is the domain name correct?")); + _loginDialog->show(); + return; + } + QJsonArray a=_services.array(); + for(auto i : a) { + if(!i.isObject()) { + std::cerr << "Non-object in JSON array" << std::endl; + continue; + } + QJsonObject o = i.toObject(); + // We can assume the object has: + // o["Title"].toString() + // o["Url"].toString() + // o["DocumentationUrl"].toString() + // o["Image"].toString() + // o["Description"].toString() + // o["SpecialNote"].toString() + // o["LDAP"].toBool() + std::cerr << qPrintable(o["Title"].toString()) << " " << o["LDAP"].toBool() << std::endl; + } +} diff --git a/Configurator.h b/Configurator.h new file mode 100644 index 0000000..f21adf1 --- /dev/null +++ b/Configurator.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include +#include + +class Configurator:public QApplication { + Q_OBJECT +public: + Configurator(int &argc, char **&argv); +protected Q_SLOTS: + void loginRequested(); + void appListReceived(QNetworkReply *reply); +private: + QNetworkAccessManager _nam; + FederatedLogin * _loginDialog; + QJsonDocument _services; +}; diff --git a/dialogs/CMakeLists.txt b/dialogs/CMakeLists.txt new file mode 100644 index 0000000..fed1b45 --- /dev/null +++ b/dialogs/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(dialogs STATIC FederatedLogin.cpp) +target_link_libraries(dialogs Qt${QT_VERSION}::Core Qt${QT_VERSION}::Gui Qt${QT_VERSION}::Widgets) diff --git a/dialogs/FederatedLogin.cpp b/dialogs/FederatedLogin.cpp new file mode 100644 index 0000000..dd18488 --- /dev/null +++ b/dialogs/FederatedLogin.cpp @@ -0,0 +1,35 @@ +#include "FederatedLogin.h" + +FederatedLogin::FederatedLogin(QWidget *parent):QDialog(parent),_layout(this) { + int y = 0; + _message = new QLabel(this); + setMessage(""); + _layout.addWidget(_message, y, 0, 1, 2); + _domainLbl = new QLabel(tr("&Domain:"), this); + _layout.addWidget(_domainLbl, ++y, 0); + _domain = new QLineEdit("f11890a1.fedcom.net", this); + _domainLbl->setBuddy(_domain); + _layout.addWidget(_domain, y, 1); + _userLbl = new QLabel(tr("&User/Email:"), this); + _layout.addWidget(_userLbl, ++y, 0); + _user = new QLineEdit(this); + _userLbl->setBuddy(_user); + _layout.addWidget(_user, y, 1); + _passwordLbl = new QLabel(tr("&Password:"), this); + _layout.addWidget(_passwordLbl, ++y, 0); + _password = new QLineEdit(this); + _password->setEchoMode(QLineEdit::Password); + _passwordLbl->setBuddy(_password); + _layout.addWidget(_password, y, 1); + _ok = new QPushButton(tr("&OK"), this); + _layout.addWidget(_ok, ++y, 0); + _cancel = new QPushButton(tr("&Cancel"), this); + _layout.addWidget(_cancel, y, 1); + connect(_ok, &QPushButton::clicked, this, &QDialog::accept); + connect(_cancel, &QPushButton::clicked, this, &QDialog::reject); +} + +void FederatedLogin::setMessage(QString const &m) { + _message->setText(m); + _message->setHidden(m.isEmpty()); +} diff --git a/dialogs/FederatedLogin.h b/dialogs/FederatedLogin.h new file mode 100644 index 0000000..c33ac8e --- /dev/null +++ b/dialogs/FederatedLogin.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include +#include + +class FederatedLogin:public QDialog { + Q_OBJECT +public: + FederatedLogin(QWidget *parent=0); + QString domain() const { return _domain->text(); } + QString user() const { return _user->text(); } + QString password() const { return _password->text(); } + void setMessage(QString const &m); +protected: + QGridLayout _layout; + QLabel * _message; + QLabel * _domainLbl; + QLineEdit * _domain; + QLabel * _userLbl; + QLineEdit * _user; + QLabel * _passwordLbl; + QLineEdit * _password; + QPushButton * _ok; + QPushButton * _cancel; +}; diff --git a/lib/DnfPackageInstaller.h b/lib/DnfPackageInstaller.h new file mode 100644 index 0000000..faafa51 --- /dev/null +++ b/lib/DnfPackageInstaller.h @@ -0,0 +1,10 @@ +#pragma once + +#include "PackageInstaller.h" + +class DnfPackageInstaller:public PackageInstaller { +public: + bool installPackages(QString const &packages) const; + bool installPackage(QString const &package) const; + bool installed(QString const &package) const; +}; diff --git a/lib/PackageInstaller.h b/lib/PackageInstaller.h new file mode 100644 index 0000000..52387d0 --- /dev/null +++ b/lib/PackageInstaller.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +class PackageInstaller { +public: + virtual bool installPackages(QStringList const &packages) const; + virtual bool installPackage(QString const &package) const = 0; + virtual bool installed(QString const &package) const = 0; +}; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..588e4ac --- /dev/null +++ b/main.cpp @@ -0,0 +1,6 @@ +#include "Configurator.h" + +int main(int argc, char **argv) { + Configurator app(argc, argv); + app.exec(); +}