diff --git a/src/appconfig.h b/src/appconfig.h index 3db18c0..fbd49d8 100644 --- a/src/appconfig.h +++ b/src/appconfig.h @@ -55,19 +55,14 @@ class AppConfig { /// readConfig attempts to read the provided path and parse the configuration file. /// If successful, the config file is loaded. If the config file is missing, then a /// default file will be generated. If some other error occurs, a FileError is thrown. - void readConfig(QString location=Constants::configLocation()) { + void readConfig(QString location = Constants::configLocation) { QFile configFile(location); if (!configFile.open(QIODevice::ReadOnly)) { if (configFile.exists()) { throw FileError::mkError("Error reading config file", location.toStdString(), configFile.error()); } - try { - writeDefaultConfig(); - } - catch (...) { - // ignoring -- just trying to generate an empty config - } + writeDefaultConfig(); return; } @@ -89,19 +84,14 @@ class AppConfig { /// writeDefaultConfig attempts to write a basic configuration to disk. /// This is useful on first runs/when no config data is set. void writeDefaultConfig() { - evidenceRepo = Constants::defaultEvidenceRepo(); + evidenceRepo = Constants::defaultEvidenceRepo; #ifdef Q_OS_MACOS - screenshotExec = "screencapture -s %file"; - captureWindowExec = "screencapture -w %file"; + screenshotExec = QStringLiteral("screencapture -s %file"); + captureWindowExec = QStringLiteral("screencapture -w %file"); #endif - try { - writeConfig(); - } - catch (...) { - // ignoring error -- best effort approach - } + writeConfig(); } public: @@ -118,7 +108,7 @@ class AppConfig { QPair(QStringLiteral("captureWindowExec"), &captureWindowExec), QPair(QStringLiteral("captureWindowShortcut"), &captureWindowShortcut), QPair(QStringLiteral("captureCodeblockShortcut"), &captureCodeblockShortcut), - }; + }; for (auto fieldPair : fields) { QJsonValue val = src.value(fieldPair.first); @@ -145,8 +135,8 @@ class AppConfig { /// writeConfig serializes the running config, and writes the assoicated file to the given path. /// The path defaults to Constants::configLocation() - void writeConfig(QString alternateSavePath="") { - QString writeLoc = alternateSavePath == "" ? Constants::configLocation() : alternateSavePath; + void writeConfig(QString alternateSavePath = QString()) { + QString writeLoc = alternateSavePath.isEmpty() ? Constants::configLocation : alternateSavePath; auto configContent = QJsonDocument(serializeConfig()).toJson(); diff --git a/src/components/code_editor/codeeditor.cpp b/src/components/code_editor/codeeditor.cpp index 71d3f29..f1e5249 100644 --- a/src/components/code_editor/codeeditor.cpp +++ b/src/components/code_editor/codeeditor.cpp @@ -71,7 +71,7 @@ CodeEditor::CodeEditor(QWidget *parent) // customize for text/code editing setLineWrapMode(LineWrapMode::NoWrap); setTabChangesFocus(false); - QFont font(Constants::codeFont()); + QFont font(Constants::codeFont); font.setStyleHint(QFont::TypeWriter); setFont(font); @@ -83,7 +83,7 @@ void CodeEditor::keyReleaseEvent(QKeyEvent *e) { QPlainTextEdit::keyReleaseEvent int CodeEditor::lineNumberAreaWidth() { int digits = 1; - int max = qMax(1, blockCount()); + int max = std::max(1, blockCount()); while (max >= 10) { max /= 10; ++digits; diff --git a/src/components/tagging/tagview.cpp b/src/components/tagging/tagview.cpp index 332a29b..9026012 100644 --- a/src/components/tagging/tagview.cpp +++ b/src/components/tagging/tagview.cpp @@ -48,7 +48,7 @@ void TagView::removeWidget(TagWidget* tagWidget) { // remove from includedTags auto itr = std::find(includedTags.begin(), includedTags.end(), tagWidget); - if(itr != includedTags.cend()) { + if(itr != includedTags.end()) { auto last = includedTags.end()-1; std::iter_swap(itr, last); includedTags.pop_back(); diff --git a/src/components/tagging/tagwidget.cpp b/src/components/tagging/tagwidget.cpp index 2c6dd86..196869a 100644 --- a/src/components/tagging/tagwidget.cpp +++ b/src/components/tagging/tagwidget.cpp @@ -46,26 +46,19 @@ void TagWidget::buildTag() { int labelWidth = labelSize.width(); int innerTagHeight = std::max(labelSize.height(), removeSize.height()); //tag height without the buffer + int labelTopOffset = ((innerTagHeight - labelSize.height())/2) + smBuffer; + int removeLeftOffset = lgBuffer + labelWidth; + int removeTopOffset = ((innerTagHeight - removeSize.height())/2) + smBuffer; - int tagHeightBuffer = 12; // space around the top/bottom (real size is half as much) - int tagWidthBuffer = 12; // space around the outer left/right edges (real size is half as much) - int innerBuffer = 6; // space between each segment - - int labelLeftOffset = tagWidthBuffer/2; - int labelTopOffset = ((innerTagHeight - labelSize.height())/2) + (tagHeightBuffer/2); - - int removeLeftOffset = labelLeftOffset + labelWidth + innerBuffer; - int removeTopOffset = ((innerTagHeight - removeSize.height())/2) + (tagHeightBuffer/2); - - int fullTagWidth = labelWidth + tagWidthBuffer; - int fullTagHeight = innerTagHeight + tagHeightBuffer; + int fullTagWidth = labelWidth + lgBuffer; + int fullTagHeight = innerTagHeight + lgBuffer; // set bounds for mouse release event labelArea = QRectF(0, 0, removeLeftOffset, fullTagHeight); removeArea = QRectF(-1, -1, 0, 0); // set to dummy value in case we don't have a remove area if (!readonly) { - fullTagWidth += removeSize.width() + innerBuffer; + fullTagWidth += removeSize.width() + smBuffer; removeArea = QRectF(removeLeftOffset, 0, fullTagWidth - removeLeftOffset, fullTagHeight); } @@ -92,7 +85,7 @@ void TagWidget::buildTag() { painter.setPen(fontColor); // draw label - painter.drawText(QRectF(QPointF(labelLeftOffset, labelTopOffset), labelSize), Qt::AlignCenter, tag.name); + painter.drawText(QRectF(QPointF(smBuffer, labelTopOffset), labelSize), Qt::AlignCenter, tag.name); // draw remove (if needed) if(!readonly) { diff --git a/src/components/tagging/tagwidget.h b/src/components/tagging/tagwidget.h index 358f191..f309f2e 100644 --- a/src/components/tagging/tagwidget.h +++ b/src/components/tagging/tagwidget.h @@ -76,4 +76,6 @@ class TagWidget : public QLabel { {QStringLiteral("lightViolet"), QColor(0xC274C2)}, }; inline static QStringList allColorNames = colorMap.keys(); + inline static int smBuffer = 6; + inline static int lgBuffer = 12; }; diff --git a/src/db/databaseconnection.h b/src/db/databaseconnection.h index 015b4cc..8931a13 100644 --- a/src/db/databaseconnection.h +++ b/src/db/databaseconnection.h @@ -44,7 +44,7 @@ class DatabaseConnection { * interaction is localized and infrequent. * @param dbPath The path to the database file * @param dbName The name of the database connection (can be anything, but should be unique. - * Specifically, it should NOT be the value from Constants::databaseName()) + * Specifically, it should NOT be the value from Constants::databaseName) * @param actions A function that will execute after a connection is established. This is where * all db interactions should occur. */ diff --git a/src/dtos/checkConnection.h b/src/dtos/checkConnection.h index d841ef3..888a2c0 100644 --- a/src/dtos/checkConnection.h +++ b/src/dtos/checkConnection.h @@ -19,7 +19,7 @@ class CheckConnection { cc.parsedCorrectly = false; if (err.error == QJsonParseError::NoError) { - QJsonValue val = doc["ok"]; + QJsonValue val = doc.object().value(QStringLiteral("ok")); if (!val.isUndefined()) { cc.parsedCorrectly = true; cc.ok = val.toBool(); diff --git a/src/dtos/github_release.h b/src/dtos/github_release.h index 4890086..232dea9 100644 --- a/src/dtos/github_release.h +++ b/src/dtos/github_release.h @@ -104,22 +104,21 @@ class GithubRelease { private: static GithubRelease fromJson(QJsonObject obj) { GithubRelease release; - release.url = obj["url"].toString(); - release.htmlURL = obj["html_url"].toString(); - release.assetsURL = obj["assets_url"].toString(); - release.uploadURL = obj["upload_url"].toString(); - release.tarballURL = obj["tarball_url"].toString(); - release.zipballURL = obj["zipball_url"].toString(); - release.tagName = obj["tag_name"].toString(); - release.body = obj["body"].toString(); - release.releaseName = obj["name"].toString(); - release.publishedAt = obj["published_at"].toString(); - release.draft = obj["draft"].toBool(); - release.prerelease = obj["prerelease"].toBool(); + release.url = obj.value(QStringLiteral("url")).toString(); + release.htmlURL = obj.value(QStringLiteral("html_url")).toString(); + release.assetsURL = obj.value(QStringLiteral("assets_url")).toString(); + release.uploadURL = obj.value(QStringLiteral("upload_url")).toString(); + release.tarballURL = obj.value(QStringLiteral("tarball_url")).toString(); + release.zipballURL = obj.value(QStringLiteral("zipball_url")).toString(); + release.tagName = obj.value(QStringLiteral("tag_name")).toString(); + release.body = obj.value(QStringLiteral("body")).toString(); + release.releaseName = obj.value(QStringLiteral("name")).toString(); + release.publishedAt = obj.value(QStringLiteral("published_at")).toString(); + release.draft = obj.value(QStringLiteral("draft")).toBool(); + release.prerelease = obj.value(QStringLiteral("prerelease")).toBool(); // missing a number of fields here that maybe aren't relevant - - release.id = obj["id"].toVariant().toLongLong(); + release.id = obj.value(QStringLiteral("id")).toVariant().toLongLong(); return release; } diff --git a/src/dtos/operation.h b/src/dtos/operation.h index 611357b..8888841 100644 --- a/src/dtos/operation.h +++ b/src/dtos/operation.h @@ -51,11 +51,10 @@ class Operation { // provides a Operation from a given QJsonObject static Operation fromJson(QJsonObject obj) { Operation o; - o.slug = obj["slug"].toString(); - o.name = obj["name"].toString(); - o.numUsers = obj["numUsers"].toInt(); - o.status = static_cast(obj["status"].toInt()); - + o.slug = obj.value(QStringLiteral("slug")).toString(); + o.name = obj.value(QStringLiteral("name")).toString(); + o.numUsers = obj.value(QStringLiteral("numUsers")).toInt(); + o.status = static_cast(obj.value(QStringLiteral("status")).toInt()); return o; } }; diff --git a/src/dtos/tag.h b/src/dtos/tag.h index a0ff289..941d2ef 100644 --- a/src/dtos/tag.h +++ b/src/dtos/tag.h @@ -16,10 +16,9 @@ class Tag { ~Tag() = default; Tag(const Tag &) = default; - Tag(QString name, QString colorName) { - this->name = name; - this->colorName = colorName; - } + Tag(QString name, QString colorName) + : name(name) + , colorName(colorName) { } public: static Tag parseData(QByteArray data) { return parseJSONItem(data, Tag::fromJson); } @@ -46,10 +45,9 @@ class Tag { // provides a Tag from a given QJsonObject static Tag fromJson(QJsonObject obj) { Tag t; - t.id = obj["id"].toVariant().toLongLong(); - t.colorName = obj["colorName"].toString(); - t.name = obj["name"].toString(); - + t.id = obj.value(QStringLiteral("id")).toVariant().toLongLong(); + t.colorName = obj.value(QStringLiteral("colorName")).toString(); + t.name = obj.value(QStringLiteral("name")).toString(); return t; } diff --git a/src/forms/credits/credits.cpp b/src/forms/credits/credits.cpp index 6cdd546..baf1723 100644 --- a/src/forms/credits/credits.cpp +++ b/src/forms/credits/credits.cpp @@ -5,127 +5,21 @@ #include #include -#include +#include #include #include #include "helpers/constants.h" #include "helpers/netman.h" -struct Attribution { - std::string library; - std::string libraryUrl; - std::string authors; - std::string license; - std::string licenseUrl; - - Attribution() = default; - Attribution(std::string library, std::string libraryUrl, std::string authors, std::string license, - std::string licenseUrl) { - this->library = library; - this->libraryUrl = libraryUrl; - this->authors = authors; - this->license = license; - this->licenseUrl = licenseUrl; - } -}; - -static std::string hyperlinkMd(std::string label, std::string url) { - return "[" + label + "](" + url + ")"; -} - -static std::string attributionMarkdown() { - QList attribs = { - Attribution("Qt", "http://qt.io", "The Qt Company", "LGPLv3", - "https://www.gnu.org/licenses/lgpl-3.0.html"), - Attribution("QProgressIndicator", "https://github.com/mojocorp/QProgressIndicator", - "Mojocorp, et al", "MIT License", - "https://github.com/mojocorp/QProgressIndicator/blob/master/LICENSE"), - Attribution("MultipartEncoder", "https://github.com/AndsonYe/MultipartEncoder", "Ye Yangang", - "MIT License", - "https://github.com/AndsonYe/MultipartEncoder/blob/master/LICENSE"), - Attribution("UGlobalHotkey", "https://github.com/joelatdeluxe/UGlobalHotkey", - "Anton Konstantinov, et al", "Public Domain", ""), - Attribution("AspectRatioPixmapLabel", "https://stackoverflow.com/a/22618496/4262552", - "phyatt, et al", "CC BY-SA 3.0", - "https://creativecommons.org/licenses/by-sa/3.0/"), - }; - - std::string msg = - "This application uses the following open source software:\n\n" - "| Project/Library | Authors | License |\n" - "| --------------- | ------- | ------- |\n"; - - for (const auto& attrib : attribs) { - std::string license; - std::string suffix; - if (!attrib.licenseUrl.empty()) { - license += "["; - suffix = "](" + attrib.licenseUrl + ")"; - } - license += attrib.license + suffix; - - // clang-format off - msg += "| " + hyperlinkMd(attrib.library, attrib.libraryUrl) + - " | " + attrib.authors + - " | " + license + - " |\n"; - // clang-format on - } - - return msg; -} - -static std::string copyrightDate() { - int initialYear = 2020; - int currentYear = QDateTime::currentDateTime().date().year(); - auto rtn = std::to_string(initialYear); - if (currentYear != initialYear) { - rtn += "-" + std::to_string(currentYear); - } - return rtn; -} - -static std::string preambleMarkdown() { - const std::string lf = "\n\n"; // double linefeed to add in linebreaks in markdown - // clang-format off - return "Version: " + Constants::releaseTag().toStdString() + - lf + "Commit Hash: " + Constants::commitHash().toStdString() + - lf + "Copyright " + copyrightDate() + ", Verizon Media" + - lf + "Licensed under the terms of [MIT](https://github.com/theparanoids/ashirt/blob/master/LICENSE)" + - lf + "A short user guide can be found " + hyperlinkMd("here", Constants::userGuideUrl().toStdString()) + - lf + "Report issues " + hyperlinkMd("here", Constants::reportAnIssueUrl().toStdString()) + - lf; - // clang-format on -} - -static std::string normalBodyMarkdown() { - // clang-format off - return "# ASHIRT\n\n" - + preambleMarkdown() - + "## Credits\n" - + attributionMarkdown(); - // clang-format on -} - Credits::Credits(QWidget* parent) - : AShirtDialog(parent, AShirtDialog::commonWindowFlags) - , updateLabel(new QLabel(this)) + : AShirtDialog(parent, AShirtDialog::commonWindowFlags) + , updateLabel(new QLabel(this)) { - buildUi(); - wireUi(); -} + setWindowTitle("About"); + connect(&NetMan::getInstance(), &NetMan::releasesChecked, this, &Credits::onReleasesUpdate); -void Credits::updateRelease() { - if (updateDigest.hasUpgrade()) { - updateLabel->setText(baseUpdateText.arg(Constants::releasePageUrl())); - } - else { - updateLabel->clear(); - } -} - -void Credits::buildUi() { + updateLabel->setVisible(false); updateLabel->setOpenExternalLinks(true); updateLabel->setTextFormat(Qt::RichText); updateLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); @@ -136,39 +30,30 @@ void Credits::buildUi() { auto creditsArea = new QTextBrowser(this); creditsArea->setOpenExternalLinks(true); creditsArea->setReadOnly(true); - creditsArea->setMarkdown(normalBodyMarkdown().c_str()); + creditsArea->setMarkdown(normalBodyMarkdown); - // Layout - /* 0 - +------------------------------------+ - 0 | update label | - +------------------------------------+ - | | - 1 | Credits Area | - | | - +------------------------------------+ - 2 | Dialog button Box{close} | - +------------------------------------+ - */ - - auto gridLayout = new QGridLayout(this); - gridLayout->addWidget(updateLabel, 0, 0); - gridLayout->addWidget(creditsArea, 1, 0); - gridLayout->addWidget(buttonBox, 2, 0); + auto gridLayout = new QVBoxLayout(this); + gridLayout->addWidget(updateLabel); + gridLayout->addWidget(creditsArea); + gridLayout->addWidget(buttonBox); setLayout(gridLayout); - - resize(450, 500); - setWindowTitle("About"); + setMinimumSize(425, 500); } -void Credits::wireUi() { - connect(&NetMan::getInstance(), &NetMan::releasesChecked, this, &Credits::onReleasesUpdate); +void Credits::updateRelease() { + if (updateDigest.hasUpgrade()) { + updateLabel->setVisible(true); + updateLabel->setText(baseUpdateText.arg(Constants::releasePageUrl)); + } + else { + updateLabel->setVisible(false); + updateLabel->clear(); + } } void Credits::onReleasesUpdate(bool success, QList releases) { - if (!success) { - return; //doesn't matter if this fails - } + if (!success) + return; auto digest = dto::ReleaseDigest::fromReleases(Constants::releaseTag(), releases); updateDigest = digest; diff --git a/src/forms/credits/credits.h b/src/forms/credits/credits.h index d83a73d..6cfd5df 100644 --- a/src/forms/credits/credits.h +++ b/src/forms/credits/credits.h @@ -5,6 +5,7 @@ #include "ashirtdialog/ashirtdialog.h" #include "dtos/github_release.h" +#include "helpers/constants.h" class QLabel; @@ -19,10 +20,6 @@ class Credits : public AShirtDialog { void onReleasesUpdate(bool success, QList releases); private: - /// buildUi creates the window structure. - void buildUi(); - /// wireUi connects the components to each other. - void wireUi(); /// updateRelease waits for an update on a new version, if any. If called, and a new version does exist /// this will update the updateLabel to have a link to the new release void updateRelease(); @@ -30,5 +27,46 @@ class Credits : public AShirtDialog { private: QLabel* updateLabel = nullptr; dto::ReleaseDigest updateDigest; + inline static const auto attribBLOB_splitChar = QStringLiteral(">"); + inline static const auto attrib_splitChar = QStringLiteral("~"); + inline static const auto hyperlinkMd = QStringLiteral("[%1](%2)"); + inline static const auto creditLine = QStringLiteral("| %1 | %2 | %3 |\n"); inline static const QString baseUpdateText = QStringLiteral("A new update is available! Click here for more details."); + inline static const auto attribBLOB + = QStringLiteral( + "Qt~http://qt.io~The Qt Company~LGPLv3~https://www.gnu.org/licenses/lgpl-3.0.html" + ">QProgressIndicator~https://github.com/mojocorp/QProgressIndicator~Mojocorp, et al~MIT License~https://github.com/mojocorp/QProgressIndicator/blob/master/LICENSE" + ">MultipartEncoder~https://github.com/AndsonYe/MultipartEncoder~Ye Yangang~MIT License~https://github.com/AndsonYe/MultipartEncoder/blob/master/LICENSE" + ">UGlobalHotkey~https://github.com/joelatdeluxe/UGlobalHotkey~Anton Konstantinov, et al~Public Domain~https://fairuse.stanford.edu/overview/public-domain/welcome" + ">AspectRatioPixmapLabel~https://stackoverflow.com/a/22618496/4262552~phyatt, et al~CC BY-SA 3.0~https://creativecommons.org/licenses/by-sa/3.0/" + ); + inline static const auto preambleMarkdown + = QStringLiteral("Version: %1 \n\n" + "Commit Hash: %2\n\n" + "Copyright %3, Verizon Media\n\n" + "Licensed under the terms of %4\n\n" + "A short user guide can be found %5\n\n" + "Report issues %6\n\n") + .arg(Constants::releaseTag() + , Constants::commitHash + , QStringLiteral("2020 - %1").arg(QDateTime::currentDateTime().date().year()) + , hyperlinkMd.arg(QStringLiteral("MIT"), QStringLiteral("https://github.com/theparanoids/ashirt/blob/master/LICENSE")) + , hyperlinkMd.arg(QStringLiteral("here"), Constants::userGuideUrl) + , hyperlinkMd.arg(QStringLiteral("here"), Constants::reportAnIssueUrl)); + + static QString attributionMarkdown() { + const QStringList attribs = attribBLOB.split(attribBLOB_splitChar); + auto msg = + QStringLiteral("This application uses the following open source software:\n\n" + "| Project/Library | Authors | License |\n" + "| --------------- | ------- | ------- |\n"); + for (const auto& attrib: attribs) { + const QStringList credit = attrib.split(attrib_splitChar); + auto library = hyperlinkMd.arg(credit.at(0), credit.at(1)); + auto copyright = hyperlinkMd.arg(credit.at(3), credit.at(4)); + msg.append(creditLine.arg(library, credit.at(2), copyright)); + } + return msg; + } + inline static const auto normalBodyMarkdown = QStringLiteral("# ASHIRT\n\n %1 ## Credits\n %2").arg(preambleMarkdown, attributionMarkdown()); }; diff --git a/src/forms/porting/porting_dialog.cpp b/src/forms/porting/porting_dialog.cpp index d48cd59..fcb03ea 100644 --- a/src/forms/porting/porting_dialog.cpp +++ b/src/forms/porting/porting_dialog.cpp @@ -163,7 +163,7 @@ void PortingDialog::doExport(porting::SystemManifest* manifest, const QString& e // Qt db access is limited to single-thread access. A new connection needs to be made, hence // the withconnection here that connects to the same database. Note: we shouldn't write to the db // in this thread, if possible. - QString threadedDbName = Constants::defaultDbName() + "_mt_forExport"; + QString threadedDbName = QStringLiteral("%1_mt_forExport").arg(Constants::defaultDbName); DatabaseConnection::withConnection( db->getDatabasePath(), threadedDbName, [this, &manifest, exportPath, options](DatabaseConnection conn){ try { @@ -198,7 +198,7 @@ void PortingDialog::doImport(porting::SystemManifest* manifest) { options.importDb = portEvidenceCheckBox->isChecked() ? options.Merge : options.None; options.importConfig = portConfigCheckBox->isChecked(); - QString threadedDbName = QStringLiteral("%1_mt_forImport").arg(Constants::defaultDbName()); + QString threadedDbName = QStringLiteral("%1_mt_forImport").arg(Constants::defaultDbName); DatabaseConnection::withConnection( db->getDatabasePath(), threadedDbName, [this, &manifest, options](DatabaseConnection conn){ try { diff --git a/src/forms/settings/settings.cpp b/src/forms/settings/settings.cpp index 59f18e9..b003b92 100644 --- a/src/forms/settings/settings.cpp +++ b/src/forms/settings/settings.cpp @@ -162,8 +162,7 @@ void Settings::checkForDuplicateShortcuts(const QKeySequence& keySequence, QKeyS bool alreadyUsed = usesKeySequence(captureWindowShortcutTextBox) || usesKeySequence(recordCodeblockShortcutTextBox) - || usesKeySequence(captureAreaShortcutTextBox) - ; + || usesKeySequence(captureAreaShortcutTextBox); if(alreadyUsed) { parentComponent->clear(); @@ -231,12 +230,9 @@ void Settings::onSaveClicked() { inst.captureWindowShortcut = captureWindowShortcutTextBox->keySequence().toString(); inst.captureCodeblockShortcut = recordCodeblockShortcutTextBox->keySequence().toString(); - try { - inst.writeConfig(); - } - catch (std::exception &e) { - couldNotSaveSettingsMsg->showMessage(tr("Unable to save settings. Error: %1").arg(e.what())); - } + inst.writeConfig(); + if(!inst.errorText.isEmpty()) + couldNotSaveSettingsMsg->showMessage(tr("Unable to save settings. Error: %1").arg(inst.errorText)); hotkeyManager->updateHotkeys(); close(); diff --git a/src/helpers/constants.h b/src/helpers/constants.h index fbf2f79..52f1411 100644 --- a/src/helpers/constants.h +++ b/src/helpers/constants.h @@ -1,35 +1,28 @@ #pragma once +#include #include #include -#include -#include - class Constants { public: - static QString unknownRepoValue() { - return QStringLiteral("???"); - } - static QString unknownOwnerValue() { - return QStringLiteral("???"); - } - - static QString configLocation() { + inline static const auto unknownValue = QStringLiteral("???"); + inline static const auto dbLocation = QStringLiteral("%1/evidence.sqlite").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); + inline static const auto defaultEvidenceRepo = QStringLiteral("%1/evidence").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); + inline static const auto commitHash = QStringLiteral("%1").arg(COMMIT_HASH); + inline static const auto userGuideUrl = QStringLiteral("https://www.github.com/theparanoids/ashirt/blob/master/README.md"); + inline static const auto reportAnIssueUrl = QStringLiteral("https://www.github.com/theparanoids/ashirt/issues"); + inline static const auto releasePageUrl = QStringLiteral("https://github.com/theparanoids/ashirt/releases"); + /// defaultDbName returns a string storing the "name" of the database for Qt identification + /// purposes. This _value_ should not be reused for other db connections. + inline static const auto defaultDbName = QStringLiteral("evidence"); #ifdef Q_OS_MACOS - return QStringLiteral("%1/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); + inline static const auto configLocation = QStringLiteral("%1/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); + inline static const auto codeFont = QStringLiteral("monaco"); #else - return QStringLiteral("%1/ashirt/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + inline static const auto configLocation = QStringLiteral("%1/ashirt/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + inline static const auto codeFont = QStringLiteral("source code pro"); #endif - } - - static QString dbLocation() { - return QStringLiteral("%1/evidence.sqlite").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); - } - - static QString defaultEvidenceRepo() { - return QStringLiteral("%1/evidence").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); - } static QString releaseOwner() { return parseRepo(RepoField::owner); @@ -39,49 +32,17 @@ class Constants { return parseRepo(RepoField::repo); } - static QString commitHash() { - return QStringLiteral("%1").arg(COMMIT_HASH); - } - static QString releaseTag() { static QString parsedReleaseTag; - if (parsedReleaseTag.isEmpty()) { QRegularExpression compiledTagRegex(QStringLiteral("(?:tags/)?v(.*)")); auto rawVersion = QStringLiteral("%1").arg(VERSION_TAG); QRegularExpressionMatch match = compiledTagRegex.match(rawVersion); parsedReleaseTag = match.hasMatch() ? QStringLiteral("v") + match.captured(1) : QStringLiteral("v0.0.0-unversioned"); } - return parsedReleaseTag; } - static QString userGuideUrl() { - return QStringLiteral("https://www.github.com/theparanoids/ashirt/blob/master/README.md"); - } - - static QString reportAnIssueUrl() { - return QStringLiteral("https://www.github.com/theparanoids/ashirt/issues"); - } - - static QString releasePageUrl() { - return QStringLiteral("https://github.com/theparanoids/ashirt/releases"); - } - - static QString codeFont() { - #ifdef Q_OS_MACX - return QStringLiteral("monaco"); - #endif - - return QStringLiteral("source code pro"); - } - - /// defaultDbName returns a string storing the "name" of the database for Qt identification - /// purposes. This _value_ should not be reused for other db connections. - static QString defaultDbName() { - return QStringLiteral("evidence"); - } - private: enum RepoField { owner = 0, @@ -91,15 +52,14 @@ class Constants { static QString parseRepo(RepoField field) { static QString parsedRepo; static QString parsedOwner; - if (parsedRepo.isEmpty()) { auto rawRepo = QStringLiteral("%1").arg(SOURCE_CONTROL_REPO); QRegularExpression ownerRegex(QStringLiteral("^([^/]+)/(.*)")); QRegularExpressionMatch match = ownerRegex.match(rawRepo); // Note that the specific values for the error cases below don't matter // They are set to avoid rerunning the parsing (since these values won't change mid-run) - parsedOwner = match.hasMatch() ? match.captured(1) : unknownOwnerValue(); - parsedRepo = match.hasMatch() ? match.captured(2) : unknownRepoValue(); + parsedOwner = match.hasMatch() ? match.captured(1) : unknownValue; + parsedRepo = match.hasMatch() ? match.captured(2) : unknownValue; } return field == RepoField::owner ? parsedOwner : parsedRepo; } diff --git a/src/helpers/file_helpers.h b/src/helpers/file_helpers.h index 07752d7..1340aff 100644 --- a/src/helpers/file_helpers.h +++ b/src/helpers/file_helpers.h @@ -55,23 +55,10 @@ class FileHelpers { return templateStr.replace(templateIndex, replaceToken.length(), replacement); } - /// converts a c++ std string into QByteArray, ensuring proper encoding - static QByteArray stdStringToByteArray(std::string str) { - return QByteArray(str.c_str(), str.size()); - } - - /** - * @brief qstringToByteArray converts a QString into a QByteArray, ensuring proper encoding. Only - * safe for ascii content. - * @param q The string to convert - * @return the QString as a QByteArray - */ - static QByteArray qstringToByteArray(QString q) { return stdStringToByteArray(q.toStdString()); } - /// writeFile write the provided content to the provided path. /// @throws a FileError if there are issues opening or writing to the file. static void writeFile(QString path, QString content) { - writeFile(path, qstringToByteArray(content)); + writeFile(path, content.toUtf8()); } /// writeFile write the provided content to the provided path. diff --git a/src/helpers/hotkeys/hotkeymap.h b/src/helpers/hotkeys/hotkeymap.h index 951b8c6..9558c6c 100644 --- a/src/helpers/hotkeys/hotkeymap.h +++ b/src/helpers/hotkeys/hotkeymap.h @@ -123,9 +123,8 @@ inline size_t QtKeyToWin(Qt::Key key) return key; } #elif defined(Q_OS_LINUX) - #include "ukeysequence.h" -#include +#include #include "xcb/xcb.h" #include "xcb/xcb_keysyms.h" #include "X11/keysym.h" @@ -135,7 +134,7 @@ struct UKeyData { int mods; }; -static std::unordered_map KEY_MAP = { +inline const static QMap KEY_MAP = { {Qt::Key_Escape, XK_Escape}, {Qt::Key_Tab, XK_Tab}, {Qt::Key_Backspace, XK_BackSpace}, @@ -163,15 +162,15 @@ inline UKeyData QtKeyToLinux(const UKeySequence &keySeq) auto key = keySeq.getSimpleKeys(); if (key.size() > 0) { - data.key = key[0]; + data.key = key.first(); } else { qWarning() << "Invalid hotkey"; return data; } // Key conversion // Misc Keys - if (KEY_MAP.find(key[0]) != KEY_MAP.end()) { - data.key = KEY_MAP[key[0]]; + if (KEY_MAP.find(key.first()) != KEY_MAP.end()) { + data.key = KEY_MAP.value(key.first()); } else if (data.key >= Qt::Key_F1 && data.key <= Qt::Key_F35) { // Qt's F keys need conversion const size_t DIFF = Qt::Key_F1 - XK_F1; data.key -= DIFF; @@ -198,18 +197,19 @@ inline UKeyData QtKeyToLinux(const UKeySequence &keySeq) return data; } + xcb_connection_t *X11Connection; + xcb_window_t X11Wid; + xcb_key_symbols_t *X11KeySymbs; #elif defined(Q_OS_MAC) - #include "ukeysequence.h" #include -#include - +#include struct UKeyData { uint32_t key; uint32_t mods; }; -static std::unordered_map KEY_MAP = { +static QMap KEY_MAP = { {Qt::Key_A, kVK_ANSI_A}, {Qt::Key_B, kVK_ANSI_B}, {Qt::Key_C, kVK_ANSI_C}, @@ -263,7 +263,7 @@ static std::unordered_map KEY_MAP = { {Qt::Key_Print, kVK_F14}, }; -static std::unordered_map MOD_MAP = { +static QMap MOD_MAP = { {Qt::Key_Shift, shiftKey}, {Qt::Key_Alt, optionKey}, {Qt::Key_Control, controlKey}, @@ -277,8 +277,8 @@ inline UKeyData QtKeyToMac(const UKeySequence &keySeq) auto key = keySeq.getSimpleKeys(); auto mods = keySeq.getModifiers(); - if (key.size() == 1 && KEY_MAP.find(key[0]) != KEY_MAP.end()) { - data.key = KEY_MAP[key[0]]; + if (key.size() == 1 && KEY_MAP.find(key.first()) != KEY_MAP.end()) { + data.key = KEY_MAP.value(key.first()); } else { qWarning() << "Invalid hotkey"; return data; @@ -288,9 +288,9 @@ inline UKeyData QtKeyToMac(const UKeySequence &keySeq) if (MOD_MAP.find(mod) == MOD_MAP.end()) return data; - data.mods += MOD_MAP[mod]; + data.mods += MOD_MAP.value(mod); } return data; } - + QHash HotkeyRefs; #endif diff --git a/src/helpers/hotkeys/ukeysequence.cpp b/src/helpers/hotkeys/ukeysequence.cpp index e2fbcc0..3f7d158 100644 --- a/src/helpers/hotkeys/ukeysequence.cpp +++ b/src/helpers/hotkeys/ukeysequence.cpp @@ -22,8 +22,8 @@ void UKeySequence::fromString(const QString &str) QString UKeySequence::toString() { - const QVector simpleKeys = getSimpleKeys(); - const QVector modifiers = getModifiers(); + const QList simpleKeys = getSimpleKeys(); + const QList modifiers = getModifiers(); QStringList result; for (auto mod : modifiers) result.append(keyToStr(mod)); @@ -34,9 +34,9 @@ QString UKeySequence::toString() return result.join('+'); } -QVector UKeySequence::getSimpleKeys() const +QList UKeySequence::getSimpleKeys() const { - QVector result; + QList result; for (auto key : qAsConst(mKeys)) { if (!isModifier(key)) { result.append(key); @@ -45,9 +45,9 @@ QVector UKeySequence::getSimpleKeys() const return result; } -QVector UKeySequence::getModifiers() const +QList UKeySequence::getModifiers() const { - QVector result; + QList result; for (auto key : qAsConst(mKeys)) { if (isModifier(key)) { result.append(key); diff --git a/src/helpers/hotkeys/ukeysequence.h b/src/helpers/hotkeys/ukeysequence.h index 7aa816f..35305fa 100644 --- a/src/helpers/hotkeys/ukeysequence.h +++ b/src/helpers/hotkeys/ukeysequence.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -34,11 +34,11 @@ public: return mKeys[n]; } - QVector getSimpleKeys() const; - QVector getModifiers() const; + QList getSimpleKeys() const; + QList getModifiers() const; private: - QVector mKeys; + QList mKeys; inline static bool isModifier(Qt::Key key) { diff --git a/src/helpers/netman.h b/src/helpers/netman.h index 706124f..a445b40 100644 --- a/src/helpers/netman.h +++ b/src/helpers/netman.h @@ -115,10 +115,10 @@ class NetMan : public QObject { } QMessageAuthenticationCode code(QCryptographicHash::Sha256); - QByteArray key = QByteArray::fromBase64(FileHelpers::qstringToByteArray(secretKeyCopy)); + QByteArray key = QByteArray::fromBase64(secretKeyCopy.toUtf8()); code.setKey(key); - code.addData(FileHelpers::stdStringToByteArray(msg)); + code.addData(QByteArray::fromStdString(msg)); return code.result().toBase64(); } @@ -178,7 +178,7 @@ class NetMan : public QObject { parser.AddFile("file", evidence.path.toStdString()); - auto body = FileHelpers::stdStringToByteArray(parser.GenBodyContent()); + auto body = QByteArray::fromStdString(parser.GenBodyContent()); auto builder = ashirtFormPost(QStringLiteral("/api/operations/%1/evidence").arg(evidence.operationSlug), body, parser.boundary().c_str()); addASHIRTAuth(builder); @@ -256,7 +256,7 @@ class NetMan : public QObject { /// checkForNewRelease retrieves the recent releases from github for the provided owner/repo project. /// Callers should retrieve the result by listening for the releasesChecked signal void checkForNewRelease(QString owner, QString repo) { - if (owner == Constants::unknownOwnerValue() || repo == Constants::unknownRepoValue()) { + if (owner == Constants::unknownValue || repo == Constants::unknownValue) { std::cerr << "Skipping release check: no owner or repo set." << std::endl; return; } diff --git a/src/helpers/request_builder.h b/src/helpers/request_builder.h index 25d76b0..5494d4f 100644 --- a/src/helpers/request_builder.h +++ b/src/helpers/request_builder.h @@ -149,7 +149,7 @@ class RequestBuilder { QNetworkRequest req; for(const auto& header : rawHeaders) { - req.setRawHeader(FileHelpers::qstringToByteArray(header.first), FileHelpers::qstringToByteArray(header.second)); + req.setRawHeader(header.first.toUtf8(), header.second.toUtf8()); } for(const auto& header : knownHeaders) { diff --git a/src/main.cpp b/src/main.cpp index 987940b..cc93646 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) { DatabaseConnection* conn; try { - conn = new DatabaseConnection(Constants::dbLocation(), Constants::defaultDbName()); + conn = new DatabaseConnection(Constants::dbLocation, Constants::defaultDbName); conn->connect(); } catch (FileError& err) { diff --git a/src/models/codeblock.cpp b/src/models/codeblock.cpp index 2a0678b..e0af845 100644 --- a/src/models/codeblock.cpp +++ b/src/models/codeblock.cpp @@ -10,11 +10,11 @@ static Codeblock fromJson(QJsonObject obj) { Codeblock rtn; - rtn.content = obj["content"].toVariant().toString(); - rtn.subtype = obj["contentSubtype"].toString(); - QJsonObject meta = obj["metadata"].toObject(); + rtn.content = obj.value(QStringLiteral("content")).toVariant().toString(); + rtn.subtype = obj.value(QStringLiteral("contentSubtype")).toString(); + QJsonObject meta = obj.value(QStringLiteral("metadata")).toObject(); if (!meta.empty()) { - rtn.source = meta["source"].toString(); + rtn.source = obj.value(QStringLiteral("source")).toString(); } return rtn; diff --git a/src/porting/system_manifest.cpp b/src/porting/system_manifest.cpp index 8bbaa58..f8de182 100644 --- a/src/porting/system_manifest.cpp +++ b/src/porting/system_manifest.cpp @@ -30,7 +30,7 @@ void SystemManifest::migrateConfig() { } } AppConfig::getInstance().applyConfig(src); - return ""; + return QString(); }); AppConfig::getInstance().writeConfig(); // save updated config } diff --git a/src/traymanager.cpp b/src/traymanager.cpp index 43bc77d..1f9e7cd 100644 --- a/src/traymanager.cpp +++ b/src/traymanager.cpp @@ -317,7 +317,7 @@ QIcon TrayManager::getTrayIcon() void TrayManager::onTrayMessageClicked() { switch(currentTrayMessage) { case UPGRADE: - QDesktopServices::openUrl(Constants::releasePageUrl()); + QDesktopServices::openUrl(Constants::releasePageUrl); break; case OPEN_PATH: QDesktopServices::openUrl(openServicesPath);