parent
e28a6f5190
commit
ac5fa6b875
|
@ -10,8 +10,7 @@ add_subdirectory(models)
|
|||
add_subdirectory(porting)
|
||||
|
||||
set(ASHIRT_SOURCES
|
||||
appconfig.h
|
||||
appsettings.h
|
||||
appconfig.cpp appconfig.h
|
||||
hotkeymanager.cpp hotkeymanager.h
|
||||
main.cpp
|
||||
traymanager.cpp traymanager.h
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
// New AppConfig 2022, Chris Rizzitello
|
||||
// Licensed under the terms of MIT. See LICENSE file in project root for terms.
|
||||
|
||||
#include <appconfig.h>
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonObject>
|
||||
|
||||
AppConfig::AppConfig(QObject *parent)
|
||||
: QObject(parent)
|
||||
, appConfig(new QSettings(_configFile, AppConfig::JSON, this))
|
||||
, appSettings(new QSettings(this))
|
||||
{
|
||||
validateConfig();
|
||||
}
|
||||
|
||||
void AppConfig::validateConfig()
|
||||
{
|
||||
//Remove Any invalid Keys and set or fix any keys needed.
|
||||
for (const auto &key : appConfig->allKeys()) {
|
||||
if(!_appConfigValidKeys.contains(key))
|
||||
appConfig->remove(key);
|
||||
}
|
||||
if (appConfig->value(CONFIG::EVIDENCEREPO).isNull())
|
||||
appConfig->setValue(CONFIG::EVIDENCEREPO, QStringLiteral("%1/ashirt/evidence").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)));
|
||||
#ifdef Q_OS_MACOS
|
||||
if (appConfig->value(CONFIG::COMMAND_SCREENSHOT).isNull())
|
||||
appConfig->setValue(CONFIG::COMMAND_SCREENSHOT, QStringLiteral("screencapture -s %file"));
|
||||
if (appConfig->value(CONFIG::COMMAND_CAPTUREWINDOW).isNull())
|
||||
appConfig->setValue(CONFIG::COMMAND_CAPTUREWINDOW, QStringLiteral("screencapture -w %file"));
|
||||
#endif
|
||||
}
|
||||
|
||||
QString AppConfig::value(const QString &key)
|
||||
{
|
||||
return get()->appConfig->value(key, QString()).toString();
|
||||
}
|
||||
|
||||
void AppConfig::setValue(const QString &key, const QString &value)
|
||||
{
|
||||
if (!AppConfig::appConfigKeys().contains(key))
|
||||
return;
|
||||
if (AppConfig::value(key) == value)
|
||||
return;
|
||||
|
||||
if (value.isEmpty())
|
||||
get()->appConfig->remove(key);
|
||||
else
|
||||
get()->appConfig->setValue(key, value);
|
||||
get()->appConfig->sync();
|
||||
}
|
||||
|
||||
bool AppConfig::exportConfig(const QString &fileName)
|
||||
{
|
||||
if(fileName.isEmpty())
|
||||
return false;
|
||||
QSettings newConfig(fileName, JSON);
|
||||
for (const auto &key : newConfig.allKeys())
|
||||
newConfig.setValue(key, get()->appConfig->value(key));
|
||||
newConfig.sync();
|
||||
return true;
|
||||
}
|
||||
|
||||
void AppConfig::importConfig(const QString &fileName)
|
||||
{
|
||||
if(fileName.isEmpty())
|
||||
return;
|
||||
QSettings oldConfig(fileName, JSON);
|
||||
for (const auto &key : oldConfig.allKeys()) {
|
||||
if (key != CONFIG::ACCESSKEY || key != CONFIG::SECRETKEY || key != CONFIG::APIURL)
|
||||
AppConfig::setValue(key, QString());
|
||||
else
|
||||
AppConfig::setValue(key, oldConfig.value(key).toString());
|
||||
}
|
||||
}
|
||||
|
||||
QString AppConfig::operationName()
|
||||
{
|
||||
return get()->appSettings->value(_opNameSetting).toString();
|
||||
}
|
||||
|
||||
QString AppConfig::operationSlug()
|
||||
{
|
||||
return get()->appSettings->value(_opSlugSetting).toString();
|
||||
}
|
||||
|
||||
void AppConfig::setOperationDetails(const QString &operationSlug, const QString &operationName)
|
||||
{
|
||||
get()->appSettings->setValue(_opNameSetting, operationName);
|
||||
get()->appSettings->setValue(_opSlugSetting, operationSlug);
|
||||
Q_EMIT get()->operationChanged(operationSlug, operationName);
|
||||
}
|
||||
|
||||
void AppConfig::setLastUsedTags(QList<model::Tag> lastTags)
|
||||
{
|
||||
QVariantList writeTags;
|
||||
for (const auto &tag : lastTags)
|
||||
writeTags << QVariant::fromValue(tag);
|
||||
get()->appSettings->setValue(_lastUsedTagsSetting, QVariant::fromValue(writeTags));
|
||||
}
|
||||
|
||||
QList<model::Tag> AppConfig::getLastUsedTags()
|
||||
{
|
||||
QList<model::Tag> rtn;
|
||||
const auto tags = get()->appSettings->value(_lastUsedTagsSetting).toList();
|
||||
for (const auto &tag : tags)
|
||||
rtn.append(tag.value<model::Tag>());
|
||||
return rtn;
|
||||
}
|
||||
|
||||
bool AppConfig::readJSONSettings(QIODevice &device, QMap<QString, QVariant> &map)
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonObject json = QJsonDocument::fromJson(device.readAll(), &error).object();
|
||||
if(error.error != QJsonParseError::NoError) {
|
||||
qWarning() << "Error parsing settings: " << error.errorString();
|
||||
return false;
|
||||
}
|
||||
map = json.toVariantMap();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AppConfig::writeJSONSettings(QIODevice &device, const QMap<QString, QVariant> &map)
|
||||
{
|
||||
QJsonObject temp = QJsonObject::fromVariantMap(map);
|
||||
return (device.write(QJsonDocument(temp).toJson()) != -1);
|
||||
}
|
219
src/appconfig.h
219
src/appconfig.h
|
@ -1,143 +1,92 @@
|
|||
// Copyright 2020, Verizon Media
|
||||
// New AppConfig 2022, Chris Rizzitello
|
||||
// Licensed under the terms of MIT. See LICENSE file in project root for terms.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QStandardPaths>
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <QSettings>
|
||||
#include <QVariant>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "exceptions/fileerror.h"
|
||||
#include "helpers/constants.h"
|
||||
#include "helpers/file_helpers.h"
|
||||
#include "helpers/jsonhelpers.h"
|
||||
#include "models/tag.h"
|
||||
|
||||
// AppConfig is a singleton construct for accessing the application's configuration.
|
||||
// singleton design borrowed from:
|
||||
// https://stackoverflow.com/questions/1008019/c-singleton-design-pattern
|
||||
class AppConfig {
|
||||
public:
|
||||
static AppConfig &getInstance() {
|
||||
static AppConfig instance;
|
||||
return instance;
|
||||
}
|
||||
AppConfig(AppConfig const &) = delete;
|
||||
void operator=(AppConfig const &) = delete;
|
||||
|
||||
QString evidenceRepo;
|
||||
QString accessKey;
|
||||
QString secretKey;
|
||||
QString apiURL;
|
||||
QString screenshotExec;
|
||||
QString screenshotShortcutCombo;
|
||||
QString captureWindowExec;
|
||||
QString captureWindowShortcut;
|
||||
QString captureClipboardShortcut;
|
||||
|
||||
QString errorText;
|
||||
|
||||
private:
|
||||
AppConfig() noexcept {
|
||||
try {
|
||||
readConfig();
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
errorText = e.what();
|
||||
}
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
QFile configFile(location);
|
||||
if (!configFile.open(QIODevice::ReadOnly)) {
|
||||
if (configFile.exists()) {
|
||||
throw FileError::mkError("Error reading config file", location.toStdString(),
|
||||
configFile.error());
|
||||
}
|
||||
writeDefaultConfig();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = configFile.readAll();
|
||||
if (configFile.error() != QFile::NoError) {
|
||||
throw FileError::mkError("Error reading config file", location.toStdString(),
|
||||
configFile.error());
|
||||
}
|
||||
|
||||
auto result = parseJSONItem<QString>(data, [this](QJsonObject src) {
|
||||
applyConfig(src);
|
||||
return "";
|
||||
});
|
||||
if (result.isNull()) {
|
||||
throw std::runtime_error("Unable to parse config file");
|
||||
}
|
||||
}
|
||||
|
||||
/// 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;
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
screenshotExec = QStringLiteral("screencapture -s %file");
|
||||
captureWindowExec = QStringLiteral("screencapture -w %file");
|
||||
#endif
|
||||
|
||||
writeConfig();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// applyConfig takes a parsed json configuration, and applies it to the current running app instance
|
||||
void applyConfig(QJsonObject src) {
|
||||
QList<QPair<QString, QString*>> fields = {
|
||||
QPair<QString, QString*>(QStringLiteral("evidenceRepo"), &evidenceRepo),
|
||||
QPair<QString, QString*>(QStringLiteral("accessKey"), &accessKey),
|
||||
QPair<QString, QString*>(QStringLiteral("secretKey"), &secretKey),
|
||||
QPair<QString, QString*>(QStringLiteral("apiURL"), &apiURL),
|
||||
QPair<QString, QString*>(QStringLiteral("screenshotCommand"), &screenshotExec),
|
||||
QPair<QString, QString*>(QStringLiteral("screenshotShortcut"), &screenshotShortcutCombo),
|
||||
QPair<QString, QString*>(QStringLiteral("captureWindowExec"), &captureWindowExec),
|
||||
QPair<QString, QString*>(QStringLiteral("captureWindowShortcut"), &captureWindowShortcut),
|
||||
QPair<QString, QString*>(QStringLiteral("captureClipboardShortcut"), &captureClipboardShortcut),
|
||||
};
|
||||
|
||||
for (auto fieldPair : fields) {
|
||||
QJsonValue val = src.value(fieldPair.first);
|
||||
if (!val.isUndefined() && val.isString()) {
|
||||
*fieldPair.second = val.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// serializeConfig creates a Json Object from the currently-used configuration
|
||||
QJsonObject serializeConfig() {
|
||||
QJsonObject root;
|
||||
root["evidenceRepo"] = evidenceRepo;
|
||||
root["accessKey"] = accessKey;
|
||||
root["secretKey"] = secretKey;
|
||||
root["apiURL"] = apiURL;
|
||||
root["screenshotCommand"] = screenshotExec;
|
||||
root["screenshotShortcut"] = screenshotShortcutCombo;
|
||||
root["captureWindowExec"] = captureWindowExec;
|
||||
root["captureWindowShortcut"] = captureWindowShortcut;
|
||||
root["captureClipboardShortcut"] = captureClipboardShortcut;
|
||||
return root;
|
||||
}
|
||||
|
||||
/// writeConfig serializes the running config, and writes the assoicated file to the given path.
|
||||
/// The path defaults to Constants::configLocation()
|
||||
/// Returns True if successful
|
||||
bool writeConfig(const QString &alternateSavePath = QString()) {
|
||||
QString writeLoc = alternateSavePath.isEmpty() ? Constants::configLocation : alternateSavePath;
|
||||
auto configContent = QJsonDocument(serializeConfig()).toJson();
|
||||
return FileHelpers::writeFile(writeLoc, configContent);
|
||||
}
|
||||
struct CONFIG {
|
||||
inline static const auto EVIDENCEREPO = QStringLiteral("evidenceRepo");
|
||||
inline static const auto ACCESSKEY = QStringLiteral("accessKey");
|
||||
inline static const auto SECRETKEY = QStringLiteral("secretKey");
|
||||
inline static const auto APIURL = QStringLiteral("apiURL");
|
||||
inline static const auto COMMAND_SCREENSHOT = QStringLiteral("screenshotCommand");
|
||||
inline static const auto SHORTCUT_SCREENSHOT = QStringLiteral("screenshotShortcut");
|
||||
inline static const auto COMMAND_CAPTUREWINDOW = QStringLiteral("captureWindowExec");
|
||||
inline static const auto SHORTCUT_CAPTUREWINDOW = QStringLiteral("captureWindowShortcut");
|
||||
inline static const auto SHORTCUT_CAPTURECLIPBOARD = QStringLiteral("captureClipboardShortcut");
|
||||
};
|
||||
|
||||
/// AppConfig is a singleton for accessing the application's configuration.
|
||||
class AppConfig : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/// Access the AppConfig for connections
|
||||
static AppConfig* get() {
|
||||
static AppConfig instance;
|
||||
return &instance;
|
||||
}
|
||||
/// Request the value of a key; returns a QString version of that value or empty QString
|
||||
static QString value(const QString &key = QString());
|
||||
/// Sets a value of a key to any QString Only accepts QStrings
|
||||
static void setValue(const QString &key = QString(), const QString &value = QString());
|
||||
/// Returns a List of all the Valid Keys in the config file
|
||||
static QStringList appConfigKeys() { return _appConfigValidKeys; }
|
||||
/// Writes a Copy of the config to FileName. Returns true if successful
|
||||
static bool exportConfig(const QString &fileName = QString());
|
||||
/// Import configuration from a file.
|
||||
static void importConfig(const QString &fileName = QString());
|
||||
/// Helper to get the operation Name
|
||||
static QString operationName();
|
||||
/// Helper to get the operation Slug
|
||||
static QString operationSlug();
|
||||
/// Helper to write operation Details, emits operationsChanged when called.
|
||||
static void setOperationDetails(const QString &operationSlug = QString(), const QString &operationName = QString());
|
||||
/// Get the list of the last used tag(s)
|
||||
static QList<model::Tag> getLastUsedTags();
|
||||
/// Set the last used Tags
|
||||
static void setLastUsedTags(QList<model::Tag> lastTags);
|
||||
|
||||
signals:
|
||||
void operationChanged(QString operationSlug, QString operationName);
|
||||
|
||||
private:
|
||||
AppConfig(QObject *parent = nullptr);
|
||||
~AppConfig() = default;
|
||||
AppConfig(AppConfig const &) = delete;
|
||||
void operator=(AppConfig const &) = delete;
|
||||
void validateConfig();
|
||||
// Helpers for JSON Format
|
||||
static bool readJSONSettings(QIODevice &device, QMap<QString, QVariant> &map);
|
||||
static bool writeJSONSettings(QIODevice &device, const QMap<QString, QVariant> &map);
|
||||
inline static const auto JSON = QSettings::registerFormat(QStringLiteral("json"), &readJSONSettings, &writeJSONSettings);
|
||||
//Vars Used Internally
|
||||
QSettings *appConfig = nullptr;
|
||||
QSettings *appSettings = nullptr;
|
||||
#ifdef Q_OS_MAC
|
||||
inline static const auto _configFile = QStringLiteral("%1/ashirt/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
|
||||
#else
|
||||
inline static const QString _configFile = QStringLiteral("%1/ashirt/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation));
|
||||
#endif
|
||||
inline static const auto _opSlugSetting = QStringLiteral("operation/slug");
|
||||
inline static const auto _opNameSetting = QStringLiteral("operation/name");
|
||||
inline static const auto _lastUsedTagsSetting = QStringLiteral("gather/tags");
|
||||
inline static const QStringList _appConfigValidKeys {
|
||||
CONFIG::EVIDENCEREPO,
|
||||
CONFIG::ACCESSKEY,
|
||||
CONFIG::SECRETKEY,
|
||||
CONFIG::APIURL,
|
||||
CONFIG::COMMAND_SCREENSHOT,
|
||||
CONFIG::SHORTCUT_SCREENSHOT,
|
||||
CONFIG::COMMAND_CAPTUREWINDOW,
|
||||
CONFIG::SHORTCUT_CAPTUREWINDOW,
|
||||
CONFIG::SHORTCUT_CAPTURECLIPBOARD,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
// Copyright 2020, Verizon Media
|
||||
// Licensed under the terms of MIT. See LICENSE file in project root for terms.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QSequentialIterable>
|
||||
#include <QSettings>
|
||||
|
||||
#include "models/tag.h"
|
||||
|
||||
// AppSettings is a singleton construct for accessing the application's settings. This is different
|
||||
// from configuration, as it represents the application's state, rather than how the application
|
||||
// communicates.
|
||||
//
|
||||
// singleton design borrowed from:
|
||||
// https://stackoverflow.com/questions/1008019/c-singleton-design-pattern
|
||||
class AppSettings : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static AppSettings &getInstance() {
|
||||
static AppSettings instance;
|
||||
return instance;
|
||||
}
|
||||
AppSettings(AppSettings const &) = delete;
|
||||
void operator=(AppSettings const &) = delete;
|
||||
|
||||
private:
|
||||
QSettings settings;
|
||||
|
||||
const char *opSlugSetting = "operation/slug";
|
||||
const char *opNameSetting = "operation/name";
|
||||
const char *lastUsedTagsSetting = "gather/tags";
|
||||
|
||||
AppSettings() : QObject(nullptr) {}
|
||||
|
||||
public:
|
||||
signals:
|
||||
void onOperationUpdated(QString operationSlug, QString operationName);
|
||||
void onSettingsSynced();
|
||||
|
||||
public:
|
||||
void sync() {
|
||||
settings.sync(); // ignoring the error
|
||||
Q_EMIT this->onSettingsSynced();
|
||||
}
|
||||
|
||||
void setOperationDetails(QString operationSlug, QString operationName) {
|
||||
settings.setValue(opSlugSetting, operationSlug);
|
||||
settings.setValue(opNameSetting, operationName);
|
||||
|
||||
Q_EMIT onOperationUpdated(operationSlug, operationName);
|
||||
}
|
||||
QString operationSlug() { return settings.value(opSlugSetting).toString(); }
|
||||
QString operationName() { return settings.value(opNameSetting).toString(); }
|
||||
|
||||
void setLastUsedTags(QList<model::Tag> lastTags) {
|
||||
QVariantList writeTags;
|
||||
|
||||
for (const auto &tag : lastTags) {
|
||||
writeTags << QVariant::fromValue(tag);
|
||||
}
|
||||
|
||||
settings.setValue(lastUsedTagsSetting, QVariant::fromValue(writeTags));
|
||||
}
|
||||
|
||||
QList<model::Tag> getLastUsedTags() {
|
||||
QList<model::Tag> rtn;
|
||||
|
||||
auto val = settings.value(lastUsedTagsSetting);
|
||||
|
||||
if (val.canConvert<QVariantList>()) {
|
||||
QSequentialIterable iter = val.value<QSequentialIterable>();
|
||||
for (const QVariant& item : iter) {
|
||||
rtn.append(qvariant_cast<model::Tag>(item));
|
||||
}
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
};
|
|
@ -175,9 +175,12 @@ QList<model::Tag> DatabaseConnection::getFullTagsForEvidenceIDs(
|
|||
return tags;
|
||||
}
|
||||
|
||||
void DatabaseConnection::setEvidenceTags(const QList<model::Tag> &newTags,
|
||||
qint64 evidenceID) {
|
||||
void DatabaseConnection::setEvidenceTags(const QList<model::Tag> &newTags, qint64 evidenceID)
|
||||
{
|
||||
// todo: this this actually work?
|
||||
if(newTags.isEmpty())
|
||||
return;
|
||||
|
||||
auto db = getDB();
|
||||
QVariantList newTagIds;
|
||||
for (const auto &tag : newTags) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <QNetworkReply>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "appsettings.h"
|
||||
#include "appconfig.h"
|
||||
#include "dtos/ashirt_error.h"
|
||||
#include "components/loading_button/loadingbutton.h"
|
||||
#include "helpers/netman.h"
|
||||
|
@ -79,7 +79,7 @@ void CreateOperation::onRequestComplete() {
|
|||
auto data = NetMan::extractResponse(createOpReply, isValid);
|
||||
if (isValid) {
|
||||
dto::Operation op = dto::Operation::parseData(data);
|
||||
AppSettings::getInstance().setOperationDetails(op.slug, op.name);
|
||||
AppConfig::setOperationDetails(op.slug, op.name);
|
||||
operationNameTextBox->clear();
|
||||
NetMan::refreshOperationsList();
|
||||
close();
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRandomGenerator>
|
||||
#include <QStandardPaths>
|
||||
#include <QTableWidgetItem>
|
||||
|
||||
#include "appsettings.h"
|
||||
#include "appconfig.h"
|
||||
#include "dtos/tag.h"
|
||||
#include "exceptions/fileerror.h"
|
||||
#include "forms/evidence_filter/evidencefilter.h"
|
||||
#include "forms/evidence_filter/evidencefilterform.h"
|
||||
#include "helpers/netman.h"
|
||||
|
@ -274,8 +274,9 @@ void EvidenceManager::deleteSet(QList<qint64> ids) {
|
|||
|
||||
if (undeletedFiles.length() > 0) {
|
||||
bool logWritten = true;
|
||||
auto today = QDateTime::currentDateTime();
|
||||
auto errLogPath = AppConfig::getInstance().evidenceRepo + "/" +QString("%1.log").arg(today.toMSecsSinceEpoch());
|
||||
auto errLogPath = QStringLiteral("%1/%2.log")
|
||||
.arg(AppConfig::value(CONFIG::EVIDENCEREPO)
|
||||
, QDateTime::currentDateTime().toMSecsSinceEpoch());
|
||||
try {
|
||||
QByteArray dataToWrite = tr("Paths to files that could not be deleted: \n\n %1")
|
||||
.arg(undeletedFiles.join(QStringLiteral("\n"))).toUtf8();
|
||||
|
@ -321,7 +322,7 @@ void EvidenceManager::openTableContextMenu(QPoint pos) {
|
|||
|
||||
void EvidenceManager::resetFilterButtonClicked() {
|
||||
EvidenceFilters filter;
|
||||
filter.operationSlug = AppSettings::getInstance().operationSlug();
|
||||
filter.operationSlug = AppConfig::operationSlug();
|
||||
filterTextBox->setText(filter.toString());
|
||||
loadEvidence();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
|
||||
#include "appsettings.h"
|
||||
#include "appconfig.h"
|
||||
#include "helpers/netman.h"
|
||||
#include "helpers/ui_helpers.h"
|
||||
|
||||
|
@ -191,6 +191,6 @@ void EvidenceFilterForm::onOperationListUpdated(bool success,
|
|||
for (const auto &op : operations) {
|
||||
operationComboBox->addItem(op.name, op.slug);
|
||||
}
|
||||
UIHelpers::setComboBoxValue(operationComboBox, AppSettings::getInstance().operationSlug());
|
||||
UIHelpers::setComboBoxValue(operationComboBox, AppConfig::operationSlug());
|
||||
operationComboBox->setEnabled(true);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <QGridLayout>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "appsettings.h"
|
||||
#include "components/evidence_editor/evidenceeditor.h"
|
||||
#include "components/loading_button/loadingbutton.h"
|
||||
#include "db/databaseconnection.h"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include "db/databaseconnection.h"
|
||||
#include "exceptions/fileerror.h"
|
||||
|
||||
PortingDialog::PortingDialog(PortType dialogType, DatabaseConnection* db, QWidget *parent)
|
||||
: AShirtDialog(parent)
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <QString>
|
||||
|
||||
#include "appconfig.h"
|
||||
#include "appsettings.h"
|
||||
#include "dtos/checkConnection.h"
|
||||
#include "helpers/http_status.h"
|
||||
#include "helpers/netman.h"
|
||||
|
@ -175,20 +174,18 @@ void Settings::checkForDuplicateShortcuts(const QKeySequence& keySequence, QKeyS
|
|||
void Settings::showEvent(QShowEvent *evt) {
|
||||
QDialog::showEvent(evt);
|
||||
hotkeyManager->disableHotkeys();
|
||||
|
||||
AppConfig &inst = AppConfig::getInstance();
|
||||
eviRepoTextBox->setFocus(); //setting focus to prevent retaining focus for macs
|
||||
|
||||
// reset the form in case a user left junk in the text boxes and pressed "cancel"
|
||||
eviRepoTextBox->setText(QDir::toNativeSeparators(inst.evidenceRepo));
|
||||
accessKeyTextBox->setText(inst.accessKey);
|
||||
secretKeyTextBox->setText(inst.secretKey);
|
||||
hostPathTextBox->setText(inst.apiURL);
|
||||
captureAreaCmdTextBox->setText(inst.screenshotExec);
|
||||
captureAreaShortcutTextBox->setKeySequence(QKeySequence::fromString(inst.screenshotShortcutCombo));
|
||||
captureWindowCmdTextBox->setText(inst.captureWindowExec);
|
||||
captureWindowShortcutTextBox->setKeySequence(QKeySequence::fromString(inst.captureWindowShortcut));
|
||||
captureClipboardShortcutTextBox->setKeySequence(QKeySequence::fromString(inst.captureClipboardShortcut));
|
||||
eviRepoTextBox->setText(QDir::toNativeSeparators(AppConfig::value(CONFIG::EVIDENCEREPO)));
|
||||
secretKeyTextBox->setText(AppConfig::value(CONFIG::SECRETKEY));
|
||||
accessKeyTextBox->setText(AppConfig::value(CONFIG::ACCESSKEY));
|
||||
hostPathTextBox->setText(AppConfig::value(CONFIG::APIURL));
|
||||
captureAreaCmdTextBox->setText(AppConfig::value(CONFIG::COMMAND_SCREENSHOT));
|
||||
captureAreaShortcutTextBox->setKeySequence(QKeySequence::fromString(AppConfig::value(CONFIG::SHORTCUT_SCREENSHOT)));
|
||||
captureWindowCmdTextBox->setText(AppConfig::value(CONFIG::COMMAND_CAPTUREWINDOW));
|
||||
captureWindowShortcutTextBox->setKeySequence(QKeySequence::fromString(AppConfig::value(CONFIG::SHORTCUT_CAPTUREWINDOW)));
|
||||
captureClipboardShortcutTextBox->setKeySequence(QKeySequence::fromString(AppConfig::value(CONFIG::SHORTCUT_CAPTURECLIPBOARD)));
|
||||
|
||||
// re-enable form
|
||||
connStatusLabel->clear();
|
||||
|
@ -211,26 +208,20 @@ void Settings::onSaveClicked() {
|
|||
stopReply(¤tTestReply);
|
||||
connStatusLabel->clear();
|
||||
|
||||
AppConfig &inst = AppConfig::getInstance();
|
||||
AppConfig::setValue(CONFIG::EVIDENCEREPO, QDir::fromNativeSeparators(eviRepoTextBox->text()));
|
||||
AppConfig::setValue(CONFIG::ACCESSKEY, accessKeyTextBox->text());
|
||||
AppConfig::setValue(CONFIG::SECRETKEY, secretKeyTextBox->text());
|
||||
|
||||
inst.evidenceRepo = QDir::fromNativeSeparators(eviRepoTextBox->text());
|
||||
inst.accessKey = accessKeyTextBox->text();
|
||||
inst.secretKey = secretKeyTextBox->text();
|
||||
|
||||
QString originalApiUrl = inst.apiURL;
|
||||
inst.apiURL = hostPathTextBox->text();
|
||||
if (originalApiUrl != hostPathTextBox->text()) {
|
||||
QString originalApiUrl = AppConfig::value(CONFIG::APIURL);
|
||||
AppConfig::setValue(CONFIG::APIURL, hostPathTextBox->text());
|
||||
if (originalApiUrl != hostPathTextBox->text())
|
||||
NetMan::refreshOperationsList();
|
||||
}
|
||||
|
||||
inst.screenshotExec = captureAreaCmdTextBox->text();
|
||||
inst.screenshotShortcutCombo = captureAreaShortcutTextBox->keySequence().toString();
|
||||
inst.captureWindowExec = captureWindowCmdTextBox->text();
|
||||
inst.captureWindowShortcut = captureWindowShortcutTextBox->keySequence().toString();
|
||||
inst.captureClipboardShortcut = captureClipboardShortcutTextBox->keySequence().toString();
|
||||
|
||||
if(!inst.writeConfig())
|
||||
couldNotSaveSettingsMsg->showMessage(tr("Unable to save settings. Error: %1").arg(inst.errorText));
|
||||
AppConfig::setValue(CONFIG::COMMAND_SCREENSHOT, captureAreaCmdTextBox->text());
|
||||
AppConfig::setValue(CONFIG::SHORTCUT_SCREENSHOT, captureAreaShortcutTextBox->keySequence().toString());
|
||||
AppConfig::setValue(CONFIG::COMMAND_CAPTUREWINDOW, captureWindowCmdTextBox->text());
|
||||
AppConfig::setValue(CONFIG::SHORTCUT_CAPTUREWINDOW, captureWindowShortcutTextBox->keySequence().toString());
|
||||
AppConfig::setValue(CONFIG::SHORTCUT_CAPTURECLIPBOARD, captureClipboardShortcutTextBox->keySequence().toString());
|
||||
|
||||
hotkeyManager->updateHotkeys();
|
||||
close();
|
||||
|
|
|
@ -10,10 +10,8 @@ class Constants {
|
|||
/// purposes. This _value_ should not be reused for other db connections.
|
||||
inline static const auto defaultDbName = QStringLiteral("evidence");
|
||||
#ifdef Q_OS_MACOS
|
||||
inline static const auto configLocation = QStringLiteral("%1/config.json").arg(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
|
||||
inline static const auto codeFont = QStringLiteral("monaco");
|
||||
#else
|
||||
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
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "dtos/operation.h"
|
||||
#include "dtos/tag.h"
|
||||
#include "dtos/github_release.h"
|
||||
#include <helpers/multipartparser.h>
|
||||
#include "helpers/multipartparser.h"
|
||||
#include "helpers/stopreply.h"
|
||||
#include "models/evidence.h"
|
||||
|
||||
|
@ -144,7 +144,7 @@ private:
|
|||
/// Allows for an optional altHost parameter, in order to check for ashirt servers.
|
||||
/// Normal usage should provide no value for this parameter.
|
||||
static RequestBuilder* ashirtGet(QString endpoint, const QString & altHost= QString()) {
|
||||
QString base = (altHost.isEmpty()) ? AppConfig::getInstance().apiURL : altHost;
|
||||
QString base = (altHost.isEmpty()) ? AppConfig::value(CONFIG::APIURL) : altHost;
|
||||
return RequestBuilder::newGet()
|
||||
->setHost(base)
|
||||
->setEndpoint(endpoint);
|
||||
|
@ -154,8 +154,8 @@ private:
|
|||
/// authentication is provided (use addASHIRTAuth to do this)
|
||||
static RequestBuilder* ashirtJSONPost(QString endpoint, QByteArray body) {
|
||||
return RequestBuilder::newJSONPost()
|
||||
->setHost(AppConfig::getInstance().apiURL)
|
||||
->setEndpoint(endpoint)
|
||||
->setHost(AppConfig::value(CONFIG::APIURL))
|
||||
->setEndpoint(endpoint)
|
||||
->setBody(body);
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ private:
|
|||
/// No authentication is provided (use addASHIRTAuth to do this)
|
||||
static RequestBuilder* ashirtFormPost(QString endpoint, QByteArray body, QString boundry) {
|
||||
return RequestBuilder::newFormPost(boundry)
|
||||
->setHost(AppConfig::getInstance().apiURL)
|
||||
->setHost(AppConfig::value(CONFIG::APIURL))
|
||||
->setEndpoint(endpoint)
|
||||
->setBody(body);
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ private:
|
|||
reqBuilder->addRawHeader(QStringLiteral("Date"), now);
|
||||
|
||||
// load default key if not present
|
||||
QString apiKeyCopy = altApiKey.isEmpty() ? AppConfig::getInstance().accessKey : QString(altApiKey);
|
||||
QString apiKeyCopy = altApiKey.isEmpty() ? AppConfig::value(CONFIG::ACCESSKEY) : QString(altApiKey);
|
||||
|
||||
auto code = generateHash(RequestMethodToString(reqBuilder->getMethod()),
|
||||
reqBuilder->getEndpoint(), now, reqBuilder->getBody(), altSecretKey);
|
||||
|
@ -192,7 +192,7 @@ private:
|
|||
const QString &secretKey = QString()) {
|
||||
|
||||
QString msg = QStringLiteral("%1\n%2\n%3\n").arg(method, path, date);
|
||||
QString secretKeyCopy = secretKey.isEmpty() ? AppConfig::getInstance().secretKey : QString(secretKey);
|
||||
QString secretKeyCopy = secretKey.isEmpty() ? AppConfig::value(CONFIG::SECRETKEY) : QString(secretKey);
|
||||
|
||||
QMessageAuthenticationCode code(QCryptographicHash::Sha256);
|
||||
code.setKey(QByteArray::fromBase64(secretKeyCopy.toUtf8()));
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
|
||||
Screenshot::Screenshot(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void Screenshot::captureArea() { basicScreenshot(AppConfig::getInstance().screenshotExec); }
|
||||
void Screenshot::captureArea() { basicScreenshot(AppConfig::value(CONFIG::COMMAND_SCREENSHOT)); }
|
||||
|
||||
void Screenshot::captureWindow() { basicScreenshot(AppConfig::getInstance().captureWindowExec); }
|
||||
void Screenshot::captureWindow() { basicScreenshot(AppConfig::value(CONFIG::COMMAND_CAPTUREWINDOW)); }
|
||||
|
||||
QString Screenshot::mkName()
|
||||
{
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <QDir>
|
||||
|
||||
#include "appconfig.h"
|
||||
#include "appsettings.h"
|
||||
|
||||
class SystemHelpers {
|
||||
|
||||
|
@ -13,8 +12,8 @@ class SystemHelpers {
|
|||
/// Returns (and creates, if necessary) the path to where evidence should be stored (includes
|
||||
/// ending path separator)
|
||||
static QString pathToEvidence() {
|
||||
auto op = AppSettings::getInstance().operationSlug();
|
||||
auto root = QStringLiteral("%1/").arg(AppConfig::getInstance().evidenceRepo);
|
||||
auto op = AppConfig::operationSlug();
|
||||
auto root = QStringLiteral("%1/").arg(AppConfig::value(CONFIG::EVIDENCEREPO));
|
||||
if (!op.isEmpty()) {
|
||||
root.append(QStringLiteral("%1/").arg(op));
|
||||
}
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
// Licensed under the terms of MIT. See LICENSE file in project root for terms.
|
||||
|
||||
#include "hotkeymanager.h"
|
||||
|
||||
#include "appconfig.h"
|
||||
#include "appsettings.h"
|
||||
|
||||
HotkeyManager::HotkeyManager(QObject *parent)
|
||||
: QObject (parent)
|
||||
|
@ -50,7 +48,7 @@ void HotkeyManager::updateHotkeys() {
|
|||
registerKey(combo, evt);
|
||||
}
|
||||
};
|
||||
regKey(AppConfig::getInstance().screenshotShortcutCombo, ACTION_CAPTURE_AREA);
|
||||
regKey(AppConfig::getInstance().captureWindowShortcut, ACTION_CAPTURE_WINDOW);
|
||||
regKey(AppConfig::getInstance().captureClipboardShortcut, ACTION_CAPTURE_CLIPBOARD);
|
||||
regKey(AppConfig::value(CONFIG::SHORTCUT_SCREENSHOT), ACTION_CAPTURE_AREA);
|
||||
regKey(AppConfig::value(CONFIG::SHORTCUT_CAPTUREWINDOW), ACTION_CAPTURE_WINDOW);
|
||||
regKey(AppConfig::value(CONFIG::SHORTCUT_CAPTURECLIPBOARD), ACTION_CAPTURE_CLIPBOARD);
|
||||
}
|
||||
|
|
|
@ -13,8 +13,6 @@ void handleCLI(std::vector<std::string> args);
|
|||
#include <QMessageBox>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "appconfig.h"
|
||||
#include "appsettings.h"
|
||||
#include "db/databaseconnection.h"
|
||||
#include "exceptions/fileerror.h"
|
||||
#include "traymanager.h"
|
||||
|
@ -37,12 +35,6 @@ int main(int argc, char* argv[]) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
auto configError = AppConfig::getInstance().errorText;
|
||||
if (!configError.isEmpty()) { // quick check & preload config data
|
||||
QMessageBox::critical(nullptr, QStringLiteral("ASHIRT Error"), QStringLiteral("Unable to connect to load settings"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rtn;
|
||||
try {
|
||||
QApplication app(argc, argv);
|
||||
|
@ -62,7 +54,6 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
auto window = new TrayManager(nullptr, conn);
|
||||
rtn = app.exec();
|
||||
AppSettings::getInstance().sync();
|
||||
window->deleteLater();
|
||||
}
|
||||
catch (std::exception const& ex) {
|
||||
|
|
|
@ -16,10 +16,7 @@ class Tag {
|
|||
|
||||
Tag(qint64 id, qint64 evidenceID, qint64 tagId, QString name) : Tag(id, tagId, name) { this->evidenceId = evidenceID; }
|
||||
Tag(qint64 id, qint64 tagId, QString name) : Tag(tagId, name) { this->id = id; }
|
||||
Tag(qint64 tagId, QString name) {
|
||||
this->serverTagId = tagId;
|
||||
this->tagName = name;
|
||||
}
|
||||
Tag(qint64 tagId, QString name) : serverTagId(tagId), tagName(name) { }
|
||||
|
||||
public:
|
||||
friend QDataStream& operator<<(QDataStream& out, const model::Tag& v) {
|
||||
|
@ -41,6 +38,4 @@ class Tag {
|
|||
qint64 evidenceId;
|
||||
};
|
||||
} // namespace model
|
||||
|
||||
Q_DECLARE_METATYPE(model::Tag)
|
||||
Q_DECLARE_METATYPE(QList<model::Tag>)
|
||||
|
|
|
@ -11,7 +11,7 @@ void SystemManifest::applyManifest(SystemManifestImportOptions options, Database
|
|||
|
||||
if (shouldMigrateConfig) {
|
||||
Q_EMIT onStatusUpdate(tr("Importing Settings"));
|
||||
migrateConfig();
|
||||
AppConfig::importConfig(configPath);
|
||||
}
|
||||
|
||||
if (shouldMigrateDb) {
|
||||
|
@ -20,21 +20,6 @@ void SystemManifest::applyManifest(SystemManifestImportOptions options, Database
|
|||
Q_EMIT onComplete();
|
||||
}
|
||||
|
||||
void SystemManifest::migrateConfig()
|
||||
{
|
||||
parseJSONItem<QString>(FileHelpers::readFile(pathToFile(configPath)), [](QJsonObject src) {
|
||||
for(const QString& key : src.keys()) {
|
||||
// only migrate connections settings, other are not portable
|
||||
src.remove(QStringLiteral("evidenceRepo")); // we never want to replace what the user has set there.
|
||||
if (key != QStringLiteral("accessKey") && key != QStringLiteral("secretKey") && key != QStringLiteral("apiURL"))
|
||||
src.remove(key);
|
||||
}
|
||||
AppConfig::getInstance().applyConfig(src);
|
||||
return QString();
|
||||
});
|
||||
AppConfig::getInstance().writeConfig(); // save updated config
|
||||
}
|
||||
|
||||
void SystemManifest::migrateDb(DatabaseConnection* systemDb)
|
||||
{
|
||||
Q_EMIT onStatusUpdate(tr("Reading Exported Evidence"));
|
||||
|
@ -50,7 +35,7 @@ void SystemManifest::migrateDb(DatabaseConnection* systemDb)
|
|||
if (importRecord.id == 0)
|
||||
continue; // in the odd situation that evidence doesn't match up, just skip it
|
||||
QString newEvidencePath = QStringLiteral("%1/%2/%3")
|
||||
.arg(AppConfig::getInstance().evidenceRepo
|
||||
.arg(AppConfig::value(CONFIG::EVIDENCEREPO)
|
||||
, importRecord.operationSlug
|
||||
, contentSensitiveFilename(importRecord.contentType));
|
||||
|
||||
|
@ -121,19 +106,7 @@ void SystemManifest::exportManifest(DatabaseConnection* db, const QString& outpu
|
|||
if (options.exportConfig) {
|
||||
Q_EMIT onStatusUpdate(tr("Exporting settings"));
|
||||
configPath = QStringLiteral("config.json");
|
||||
AppConfig::getInstance().writeConfig(m_fileTemplate.arg(basePath, configPath));
|
||||
}
|
||||
|
||||
if (options.exportDb) {
|
||||
Q_EMIT onStatusUpdate(tr("Exporting Evidence"));
|
||||
dbPath = QStringLiteral("db.sqlite");
|
||||
evidenceManifestPath = QStringLiteral("evidence.json");
|
||||
auto allEvidence = DatabaseConnection::createEvidenceExportView(m_fileTemplate.arg(basePath, dbPath), EvidenceFilters(), db);
|
||||
Q_EMIT onReady(allEvidence.size());
|
||||
porting::EvidenceManifest evidenceManifest = copyEvidence(basePath, allEvidence);
|
||||
// write evidence manifest
|
||||
FileHelpers::writeFile(m_fileTemplate.arg(basePath, evidenceManifestPath),
|
||||
QJsonDocument(EvidenceManifest::serialize(evidenceManifest)).toJson());
|
||||
AppConfig::exportConfig(m_fileTemplate.arg(basePath, configPath));
|
||||
}
|
||||
|
||||
m_pathToManifest = QStringLiteral("%1/system.json").arg(basePath);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "helpers/jsonhelpers.h"
|
||||
#include "helpers/screenshot.h"
|
||||
#include "appconfig.h"
|
||||
#include "appsettings.h"
|
||||
#include "db/databaseconnection.h"
|
||||
#include "evidence_manifest.h"
|
||||
#include "models/codeblock.h"
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include <QDesktopServices>
|
||||
#include <iostream>
|
||||
#include "appconfig.h"
|
||||
#include "appsettings.h"
|
||||
#include "db/databaseconnection.h"
|
||||
#include "exceptions/fileerror.h"
|
||||
#include "forms/getinfo/getinfo.h"
|
||||
#include "helpers/netman.h"
|
||||
#include "helpers/screenshot.h"
|
||||
|
@ -122,8 +122,8 @@ void TrayManager::wireUi() {
|
|||
// connect to network signals
|
||||
connect(NetMan::get(), &NetMan::operationListUpdated, this, &TrayManager::onOperationListUpdated);
|
||||
connect(NetMan::get(), &NetMan::releasesChecked, this, &TrayManager::onReleaseCheck);
|
||||
connect(&AppSettings::getInstance(), &AppSettings::onOperationUpdated, this, &TrayManager::setActiveOperationLabel);
|
||||
|
||||
connect(AppConfig::get(), &AppConfig::operationChanged, this, &TrayManager::setActiveOperationLabel);
|
||||
|
||||
connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &TrayManager::onTrayMessageClicked);
|
||||
connect(trayIcon, &QSystemTrayIcon::activated, this, [this] {
|
||||
newOperationAction->setEnabled(false);
|
||||
|
@ -166,24 +166,21 @@ void TrayManager::changeEvent(QEvent *event)
|
|||
|
||||
void TrayManager::spawnGetInfoWindow(qint64 evidenceID) {
|
||||
auto getInfoWindow = new GetInfo(db, evidenceID, this);
|
||||
connect(getInfoWindow, &GetInfo::evidenceSubmitted, [](const model::Evidence& evi){
|
||||
AppSettings::getInstance().setLastUsedTags(evi.tags);
|
||||
connect(getInfoWindow, &GetInfo::evidenceSubmitted, [](const model::Evidence& evi) {
|
||||
AppConfig::setLastUsedTags(evi.tags);
|
||||
});
|
||||
getInfoWindow->show();
|
||||
}
|
||||
|
||||
qint64 TrayManager::createNewEvidence(const QString& filepath, const QString& evidenceType) {
|
||||
AppSettings& inst = AppSettings::getInstance();
|
||||
auto evidenceID = db->createEvidence(filepath, inst.operationSlug(), evidenceType);
|
||||
auto tags = inst.getLastUsedTags();
|
||||
if (!tags.empty()) {
|
||||
db->setEvidenceTags(tags, evidenceID);
|
||||
}
|
||||
auto evidenceID = db->createEvidence(filepath, AppConfig::operationSlug(), evidenceType);
|
||||
auto tags = AppConfig::getLastUsedTags();
|
||||
db->setEvidenceTags(tags, evidenceID);
|
||||
return evidenceID;
|
||||
}
|
||||
|
||||
void TrayManager::captureWindowActionTriggered() {
|
||||
if(AppSettings::getInstance().operationSlug().isEmpty()) {
|
||||
if(AppConfig::operationSlug().isEmpty()) {
|
||||
showNoOperationSetTrayMessage();
|
||||
return;
|
||||
}
|
||||
|
@ -191,7 +188,7 @@ void TrayManager::captureWindowActionTriggered() {
|
|||
}
|
||||
|
||||
void TrayManager::captureAreaActionTriggered() {
|
||||
if(AppSettings::getInstance().operationSlug().isEmpty()) {
|
||||
if(AppConfig::operationSlug().isEmpty()) {
|
||||
showNoOperationSetTrayMessage();
|
||||
return;
|
||||
}
|
||||
|
@ -199,7 +196,7 @@ void TrayManager::captureAreaActionTriggered() {
|
|||
}
|
||||
|
||||
void TrayManager::captureClipboardActionTriggered() {
|
||||
if(AppSettings::getInstance().operationSlug().isEmpty()) {
|
||||
if(AppConfig::operationSlug().isEmpty()) {
|
||||
showNoOperationSetTrayMessage();
|
||||
return;
|
||||
}
|
||||
|
@ -263,7 +260,7 @@ void TrayManager::showNoOperationSetTrayMessage() {
|
|||
}
|
||||
|
||||
void TrayManager::setActiveOperationLabel() {
|
||||
const auto& opName = AppSettings::getInstance().operationName();
|
||||
const auto& opName = AppConfig::operationName();
|
||||
chooseOpSubmenu->setTitle(tr("Operation: %1").arg(opName.isEmpty() ? tr("<None>") : opName));
|
||||
}
|
||||
|
||||
|
@ -273,7 +270,7 @@ void TrayManager::onOperationListUpdated(bool success,
|
|||
if (!success)
|
||||
return;
|
||||
|
||||
auto currentOp = AppSettings::getInstance().operationSlug();
|
||||
auto currentOp = AppConfig::operationSlug();
|
||||
newOperationAction->setEnabled(true);
|
||||
newOperationAction->setText(tr("New Operation"));
|
||||
cleanChooseOpSubmenu();
|
||||
|
@ -287,15 +284,15 @@ void TrayManager::onOperationListUpdated(bool success,
|
|||
}
|
||||
allOperationActions.addAction(newAction.get());
|
||||
connect(newAction.get(), &QAction::triggered, this, [this, newAction, op] {
|
||||
AppSettings::getInstance().setLastUsedTags(QList<model::Tag>{}); // clear last used tags
|
||||
AppSettings::getInstance().setOperationDetails(op.slug, op.name);
|
||||
AppConfig::setLastUsedTags(QList<model::Tag>{}); // clear last used tags
|
||||
AppConfig::setOperationDetails(op.slug, op.name);
|
||||
selectedAction = newAction.get();
|
||||
});
|
||||
chooseOpSubmenu->addAction(newAction.get());
|
||||
}
|
||||
|
||||
if (!selectedAction) {
|
||||
AppSettings::getInstance().setOperationDetails(QString(), QString());
|
||||
AppConfig::setOperationDetails(QString(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue