Compare commits

..
25 Commits
Author SHA1 Message Date
marc 7896df41cd better build 2021-12-17 15:06:51 +01:00
marc 718a127ef3 known hosts 2021-12-13 17:15:44 +01:00
marc 1ff8e36234 ssh config 2021-12-13 17:14:31 +01:00
marc 18c602245e docker-compose 2021-12-13 16:45:34 +01:00
marc 37a61266f7 ssh 2021-12-13 16:41:26 +01:00
marc 55a16089c2 docker-compose + Dockerfile that work 2021-11-26 15:46:00 +01:00
marc 80ac5292b4 dockerfile 2021-11-26 15:41:27 +01:00
marc 5fb3a107ae docker-compose for using mongo with no dependencies by bind mouting the x11 server 2021-11-26 15:32:00 +01:00
Dj Walker-Morgan a715e33068 Update (C) date 2021-11-08 09:30:35 +00:00
Dj Walker-Morgan dbd03d410d Update README, remove survey 2021-11-08 09:22:56 +00:00
Gokhan Simsek e6ac9ec513 Changelog 2021-07-28 12:37:28 +03:00
Gokhan Simsek c58ed4a0d4 Minor fix 2021-07-28 12:09:17 +03:00
Gokhan Simsek 751c0b0ea8 Refactoring 2021-07-28 11:23:43 +03:00
Gokhan Simsek 526ae7065a Refactoring 2021-07-28 11:05:23 +03:00
Gokhan Simsek 860903cce8 Adding DefaultDB option support for From URI feature 2021-07-28 11:02:14 +03:00
Gokhan Simsek 1e1a7c84b5 Refactoring 2021-07-21 14:01:30 +03:00
Gokhan Simsek c7d97b23aa Adding AuthMechanism option support for From URI feature 2021-07-21 13:28:51 +03:00
Gokhan Simsek bf4cb999d7 Adding clearSslTab func. 2021-07-21 10:49:24 +03:00
Gokhan Simsek c6a4eb0494 Rename 2021-07-21 10:36:21 +03:00
Gokhan Simsek f94e7ce981 Adding TLS options support for From URI feature 2021-07-14 14:34:16 +03:00
Gokhan Simsek dd415d07af Adding feature auto-fill connection settings from standard URI (MongoDB Standard Connection String Format) 2021-07-14 10:02:46 +03:00
Gokhan Simsek 06b67b0adc Adding clear AuthTab func 2021-07-14 09:59:39 +03:00
Gokhan Simsek bd9a2e8227 Release 1.4.4 2021-06-29 13:11:14 +03:00
Gokhan Simsek ccd8299240 macOS, Windows: Fix Welcome Tab not loading the new content issue (disable/bypass HTTP cache) 2021-06-29 13:10:50 +03:00
kathrynvargas a288e5a3c6 Update README.md 2021-06-23 17:13:54 +02:00
17 changed files with 260 additions and 61 deletions
+6
View File
@@ -2,6 +2,12 @@
Download latest version:
https://robomongo.org/download
Robo 3T 1.4.4 (Aug/2021)
New Features:
- Support for Standard Connection String Format (Mongo URI)
Fixes:
- Fix Welcome Tab not loading the new content issue by disable/bypass HTTP cache
Robo 3T 1.4.3 (Jan/2021)
New Features:
- macOS Big Sur support
+1 -1
View File
@@ -7,7 +7,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
# Project version
set(PROJECT_VERSION_MAJOR "1")
set(PROJECT_VERSION_MINOR "4")
set(PROJECT_VERSION_PATCH "3")
set(PROJECT_VERSION_PATCH "4")
set(PROJECT_VERSION_BUILD "")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${PROJECT_VERSION_BUILD}")
+24
View File
@@ -0,0 +1,24 @@
FROM debian
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends --fix-missing\
libgl-dev \
qt5dxcb-plugin \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/
ADD https://download-test.robomongo.org/linux/robo3t-1.3.1-linux-x86_64-7419c406.tar.gz /opt/robo3t.tar.gz
RUN cd /opt/ \
&& mkdir robo3t \
&& tar -C /opt/robo3t --strip-components 1 -xzf robo3t.tar.gz && rm robo3t.tar.gz \
&& ls /opt/robo3t
VOLUME /root/.3T
VOLUME /root/.config/3T
RUN apt update && apt upgrade -y && apt autoremove -y
RUN apt install openssh-client -y
CMD /opt/robo3t/bin/robo3t
+2 -1
View File
@@ -1,3 +1,4 @@
About Robo 3T
===============
@@ -131,7 +132,7 @@ You can:
License
=======
Copyright 2014-2020 [3T Software Labs Ltd](https://studio3t.com/). All rights reserved.
Copyright 2014-2021 [3T Software Labs Ltd](https://studio3t.com/). All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
+18
View File
@@ -0,0 +1,18 @@
version: "3.9"
services:
robo3t:
image: robo3t
build:
context: .
dockerfile: ./Dockerfile
network: host
network_mode: host
environment:
- DISPLAY=${DISPLAY}
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- $HOME/.3T:/root/.3T
- $HOME/.config/.3T:/root/.config/.3T
- $HOME/.ssh/id_rsa:/root/.ssh/id_rsa
- $HOME/.ssh/config:/root/.ssh/config
- $HOME/.ssh/known_hosts:/root/.ssh/known_hosts
+3 -2
View File
@@ -246,17 +246,18 @@ if(SYSTEM_WINDOWS)
target_link_libraries(robomongo PRIVATE Qt5::WinMain)
elseif(SYSTEM_MACOSX)
string(TIMESTAMP CURRENT_YEAR "%Y")
set_target_properties(robomongo PROPERTIES
INSTALL_RPATH "@executable_path/../Frameworks"
OUTPUT_NAME "Robo 3T"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/install/macosx/Info.plist.in"
MACOSX_BUNDLE_BUNDLE_NAME "Robo 3T"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.3tsoftwarelabs.robo3t"
MACOSX_BUNDLE_INFO_STRING "Robo 3T ${PROJECT_VERSION}. Copyright 3T Software Labs Ltd, 2014 - 2017"
MACOSX_BUNDLE_INFO_STRING "Robo 3T ${PROJECT_VERSION}. Copyright 3T Software Labs Ltd, 2014 - ${CURRENT_YEAR}"
MACOSX_BUNDLE_SHORT_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_LONG_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_COPYRIGHT "Copyright 3T Software Labs Ltd, 2014 - 2017"
MACOSX_BUNDLE_COPYRIGHT "Copyright 3T Software Labs Ltd, 2014 - ${CURRENT_YEAR}"
MACOSX_BUNDLE_ICON_FILE "robomongo")
elseif(SYSTEM_LINUX)
@@ -75,6 +75,7 @@ namespace Robomongo
// be defined and placed into the vector initializer list below in order.
std::vector<QString> const SettingsManager::_configFilesOfOldVersions
{
QString("%1/.3T/robo-3t/1.4.3/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_4_3
QString("%1/.3T/robo-3t/1.4.2/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_4_2
QString("%1/.3T/robo-3t/1.4.1/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_4_1
QString("%1/.3T/robo-3t/1.4.0/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_4_0
@@ -11,7 +11,6 @@
#include "robomongo/core/settings/CredentialSettings.h"
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/gui/GuiRegistry.h"
#include "robomongo/gui/utils/GuiConstants.h"
namespace Robomongo
{
@@ -141,12 +140,28 @@ namespace Robomongo
_settings->addCredential(credential);
}
void ConnectionAuthTab::setAuthTab(QString const db, QString const username, QString const pwd)
{
void ConnectionAuthTab::setAuthTab(
QString const db,
QString const username,
QString const pwd,
AuthMechanism authMech
) {
_useAuth->setChecked(true);
_databaseName->setText(db);
_userName->setText(username);
_userPassword->setText(pwd);
_mechanismComboBox->setCurrentIndex(int(authMech));
}
void ConnectionAuthTab::clearTab()
{
_useAuth->setChecked(false);
_databaseName->clear();
_userName->clear();
_userPassword->clear();
_mechanismComboBox->setCurrentIndex(0);
_useManuallyVisibleDbs->setChecked(false);
_manuallyVisibleDbs->clear();
}
void ConnectionAuthTab::toggleEchoMode()
+10 -1
View File
@@ -1,6 +1,9 @@
#pragma once
#include <QWidget>
#include "robomongo/gui/utils/GuiConstants.h"
QT_BEGIN_NAMESPACE
class QLineEdit;
class QLabel;
@@ -20,7 +23,13 @@ namespace Robomongo
public:
ConnectionAuthTab(ConnectionSettings *settings);
void accept();
void setAuthTab(QString const db, QString const username, QString const pwd);
void setAuthTab(
QString const db,
QString const username,
QString const pwd,
AuthMechanism authMech
);
void clearTab();
private Q_SLOTS:
void toggleEchoMode();
@@ -111,17 +111,17 @@ namespace Robomongo
auto hline = new QFrame();
hline->setFrameShape(QFrame::HLine);
hline->setFrameShadow(QFrame::Sunken);
_srvEdit = new QLineEdit();
_srvEdit->setPlaceholderText("Import connection details from MongoDB SRV connection string");
_srvButton = new QPushButton("From SRV");
_uriEdit = new QLineEdit();
_uriEdit->setPlaceholderText("Import connection details from MongoDB URI connection string");
_uriButton = new QPushButton("From URI");
#ifdef _WIN32
_srvButton->setMaximumHeight(HighDpiConstants::WIN_HIGH_DPI_BUTTON_HEIGHT);
_srvButton->setMinimumWidth(60);
_uriButton->setMaximumHeight(HighDpiConstants::WIN_HIGH_DPI_BUTTON_HEIGHT);
_uriButton->setMinimumWidth(60);
#else // MacOS
_srvButton->setMaximumHeight(HighDpiConstants::MACOS_HIGH_DPI_BUTTON_HEIGHT);
_srvButton->setMaximumWidth(90);
_uriButton->setMaximumHeight(HighDpiConstants::MACOS_HIGH_DPI_BUTTON_HEIGHT);
_uriButton->setMaximumWidth(90);
#endif
VERIFY(connect(_srvButton, SIGNAL(clicked()), this, SLOT(on_srvButton_clicked())));
VERIFY(connect(_uriButton, SIGNAL(clicked()), this, SLOT(on_uriButton_clicked())));
auto connLayout = new QGridLayout;
connLayout->setVerticalSpacing(8);
@@ -142,8 +142,8 @@ namespace Robomongo
connLayout->addWidget(_setNameEdit, 9, 1, 1, 3, Qt::AlignTop);
connLayout->addWidget(fakeSpacer, 10, 0);
connLayout->addWidget(hline, 11, 0, 1, 4);
connLayout->addWidget(_srvButton, 13, 0);
connLayout->addWidget(_srvEdit, 13, 1, 1, 3);
connLayout->addWidget(_uriButton, 13, 0);
connLayout->addWidget(_uriEdit, 13, 1, 1, 3);
connLayout->setRowStretch(10, 1);
#ifdef __APPLE__
@@ -225,6 +225,16 @@ namespace Robomongo
return true;
}
void ConnectionBasicTab::clearTab()
{
_connectionType->setCurrentIndex(0);
_connectionName->setText("New Connection");
_serverAddress->clear();
_serverPort->clear();
_members->clear();
_setNameEdit->clear();
}
void ConnectionBasicTab::on_ConnectionTypeChange(int index)
{
bool const isReplica = static_cast<bool>(index);
@@ -318,38 +328,71 @@ namespace Robomongo
item->setText(0, str);
}
void ConnectionBasicTab::on_srvButton_clicked()
void ConnectionBasicTab::on_uriButton_clicked()
{
QString srvStr = _srvEdit->text().simplified();
srvStr.replace(" ", "");
auto const statusWithMongoURI = mongo::MongoURI::parse(srvStr.toStdString());
if (!statusWithMongoURI.isOK()) {
// Parse Mongo URI
QString uriStr = _uriEdit->text().simplified();
uriStr.replace(" ", "");
auto const statusWithURI = mongo::MongoURI::parse(uriStr.toStdString());
if (!statusWithURI.isOK()) {
QMessageBox errorBox;
errorBox.critical(this, "Error", ("MongoDB SRV:\n" + statusWithMongoURI.getStatus().toString()).c_str());
errorBox.critical(
this, "Error", ("MongoDB URI:\n" + statusWithURI.getStatus().toString()).c_str()
);
errorBox.show();
return;
}
auto const mongoUri = statusWithMongoURI.getValue();
auto const db = QString::fromStdString(mongoUri.getDatabase());
auto const mongoUri = statusWithURI.getValue();
// Clear tabs
clearTab();
_connectionDialog->clearConnAuthTab();
_connectionDialog->clearSslTab();
// Set Basic (this) Tab
auto const isReplicaSet = mongoUri.type() == mongo::ConnectionString::ConnectionType::SET;
if(isReplicaSet) {
_connectionType->setCurrentIndex(1); // Switch to Replica Set
for (auto const& hostAndPort : mongoUri.getServers()) {
auto host = QString::fromStdString(hostAndPort.host());
host.endsWith('.') ? host.remove(host.size()-1, 1) : "no-op";
auto const newHostAndPort = host + ':' + QString::number(hostAndPort.port());
auto item = new QTreeWidgetItem;
item->setText(0, newHostAndPort);
item->setFlags(item->flags() | Qt::ItemIsEditable);
_members->addTopLevelItem(item);
}
_setNameEdit->setText(QString::fromStdString(mongoUri.getSetName()));
}
else { // Standalone
_connectionType->setCurrentIndex(0);
_serverAddress->setText(QString::fromStdString(mongoUri.getServers()[0].host()));
_serverPort->setText(QString::number(mongoUri.getServers()[0].port()));
}
// Set Auth Tab
auto const user = QString::fromStdString(mongoUri.getUser());
auto const pwd = QString::fromStdString(mongoUri.getPassword());
auto const authDb = QString::fromStdString(mongoUri.getAuthenticationDatabase());
auto const authMechanism = mongoUri.getOption("authMechanism").get_value_or("");
if(!user.isEmpty()) _connectionDialog->setAuthTab(
authDb, user, pwd, authMechanismFromStr(authMechanism)
);
// Set SSL Tab
if(mongoUri.getSSLMode() == mongo::transport::ConnectSSLMode::kEnableSSL) {
auto tlsAllowInvalidCertificates = mongoUri.getOption("tlsAllowInvalidCertificates");
int const authMethodIndex = tlsAllowInvalidCertificates.get_value_or("") == "true" ? 0 : 1;
auto const caFile = mongoUri.getOption("tlsCAFile").get_value_or("");
auto const certKeyFile = mongoUri.getOption("tlsCertificateKeyFile").get_value_or("");
auto const certKeyFilePwd =
mongoUri.getOption("tlsCertificateKeyFilePassword").get_value_or("");
auto const allowInvalidHostnames =
mongoUri.getOption("tlsAllowInvalidHostnames").get_value_or("") == "true";
// Basic (this) Tab
_members->clear();
_connectionType->setCurrentIndex(1); // Switch to Replica Set
for (auto const& hostAndPort : mongoUri.getServers()) {
auto host = QString::fromStdString(hostAndPort.host());
host.endsWith('.') ? host.remove(host.size()-1, 1) : "no-op";
auto const newHostAndPort = host + ':' + QString::number(hostAndPort.port());
auto item = new QTreeWidgetItem;
item->setText(0, newHostAndPort);
item->setFlags(item->flags() | Qt::ItemIsEditable);
_members->addTopLevelItem(item);
_connectionDialog->setSslTab(
authMethodIndex, allowInvalidHostnames, caFile, certKeyFile, certKeyFilePwd
);
}
_setNameEdit->setText(QString::fromStdString(mongoUri.getSetName()));
_connectionDialog->setAuthTab(authDb, user, pwd); // Auth Tab
_connectionDialog->enableSslBasic(); // TLS Tab
_connectionDialog->setDefaultDb(db); // Advanced Tab
// Advanced Tab
_connectionDialog->setDefaultDb(QString::fromStdString(mongoUri.getDatabase()));
}
}
}
@@ -24,6 +24,7 @@ namespace Robomongo
public:
ConnectionBasicTab(ConnectionSettings *settings, ConnectionDialog *connectionDialog);
bool accept();
void clearTab();
private Q_SLOTS:
void on_ConnectionTypeChange(int index);
@@ -31,7 +32,7 @@ namespace Robomongo
void on_addButton_clicked();
void on_removeButton_clicked();
void on_replicaMemberItemEdit(QTreeWidgetItem* item, int column);
void on_srvButton_clicked();
void on_uriButton_clicked();
private:
QLabel *_typeLabel;
@@ -51,8 +52,8 @@ namespace Robomongo
QDialogButtonBox *_minusPlusButtonBox;
QLabel *_setNameLabel;
QLineEdit *_setNameEdit;
QLineEdit *_srvEdit;
QPushButton *_srvButton;
QLineEdit *_uriEdit;
QPushButton *_uriButton;
QPushButton *_discoverButton;
QLabel *_readPrefLabel;
QComboBox *_readPreference;
+27 -8
View File
@@ -99,14 +99,13 @@ namespace Robomongo
QWidget::closeEvent(event);
}
void ConnectionDialog::setAuthTab(QString const& db, QString const& username, QString const& pwd)
{
_authTab->setAuthTab(db, username, pwd);
}
void ConnectionDialog::enableSslBasic()
{
_sslTab->enableSslBasic();
void ConnectionDialog::setAuthTab(
QString const& db,
QString const& username,
QString const& pwd,
AuthMechanism authMech
) {
_authTab->setAuthTab(db, username, pwd, authMech);
}
void ConnectionDialog::setDefaultDb(QString const& defaultDb)
@@ -123,6 +122,26 @@ namespace Robomongo
_sshTab->toggleSshCheckboxToolTip(isReplicaSet);
}
void ConnectionDialog::clearConnAuthTab()
{
_authTab->clearTab();
}
void ConnectionDialog::clearSslTab()
{
_sslTab->clearTab();
}
void ConnectionDialog::setSslTab(
int index,
bool allowInvalidHostnames,
std::string_view caFile,
std::string_view certPemFile,
std::string_view certPemFilePwd
) {
_sslTab->setSslOptions(index, allowInvalidHostnames, caFile, certPemFile, certPemFilePwd);
}
void ConnectionDialog::restoreWindowSettings()
{
QSettings settings("3T", "Robomongo");
+18 -2
View File
@@ -3,6 +3,7 @@
#include <QDialog>
#include "robomongo/core/Core.h"
#include "robomongo/gui/utils/GuiConstants.h"
namespace Robomongo
{
@@ -12,6 +13,7 @@ namespace Robomongo
class ConnectionAdvancedTab;
class SSLTab;
class SshTunnelTab;
/**
* @brief This Dialog allows to edit single connection
*/
@@ -26,10 +28,24 @@ namespace Robomongo
ConnectionDialog(ConnectionSettings *connection, QWidget *parent = nullptr);
ConnectionSettings *const connection() const { return _connection; }
void setAuthTab(QString const& db, QString const& username, QString const& pwd);
void enableSslBasic();
void setAuthTab(
QString const& db,
QString const& username,
QString const& pwd,
AuthMechanism authMech
);
void setDefaultDb(QString const& defaultDb);
void toggleSshSupport(bool isReplicaSet);
void clearConnAuthTab();
void clearSslTab();
void setSslTab(
int index,
bool allowInvalidHostnames,
std::string_view caFile,
std::string_view certPemFile,
std::string_view certPemFilePwd
);
public Q_SLOTS:
/**
+27 -4
View File
@@ -207,10 +207,34 @@ namespace Robomongo
return _useSslCheckBox->isChecked();
}
void SSLTab::enableSslBasic()
void SSLTab::clearTab()
{
_authMethodComboBox->setCurrentIndex(1);
_caFilePathLineEdit->clear();
_usePemFileCheckBox->setChecked(false);
_pemFilePathLineEdit->clear();
_pemPassLineEdit->clear();
_useAdvancedOptionsCheckBox->setChecked(false);
_allowInvalidHostnamesComboBox->setCurrentIndex(0);
}
void SSLTab::setSslOptions(
int index,
bool allowInvalidHostnames,
std::string_view caFile,
std::string_view certPemFile,
std::string_view certPemFilePwd
) {
_useSslCheckBox->setChecked(true);
_authMethodComboBox->setCurrentIndex(0);
_authMethodComboBox->setCurrentIndex(index);
_caFilePathLineEdit->setText(QString::fromStdString(std::string(caFile)));
if(!certPemFile.empty()) _usePemFileCheckBox->setChecked(true);
_pemFilePathLineEdit->setText(QString::fromStdString(std::string(certPemFile)));
_pemPassLineEdit->setText(QString::fromStdString(std::string(certPemFilePwd)));
if (allowInvalidHostnames) _useAdvancedOptionsCheckBox->setChecked(true);
_allowInvalidHostnamesComboBox->setCurrentIndex(allowInvalidHostnames);
}
void SSLTab::useSslCheckBoxStateChange(int state)
@@ -399,5 +423,4 @@ namespace Robomongo
return QDir::toNativeSeparators(fileName);
}
}
}
+8 -1
View File
@@ -39,7 +39,14 @@ namespace Robomongo
*/
bool sslEnabled() const;
void enableSslBasic();
void clearTab();
void setSslOptions(
int index,
bool allowInvalidHostnames,
std::string_view caFile,
std::string_view certPemFile,
std::string_view certPemFilePwd
);
private Q_SLOTS :
+14 -1
View File
@@ -8,4 +8,17 @@ namespace Robomongo
int const MACOS_HIGH_DPI_BUTTON_HEIGHT = 34;
}
} /* end of Robomongo namespace */
enum AuthMechanism {
SCRAM_SHA_1,
SCRAM_SHA_256,
MONGODB_CR
};
inline AuthMechanism authMechanismFromStr(std::string_view str) {
if (str == "SCRAM-SHA-1") return SCRAM_SHA_1;
else if (str == "SCRAM-SHA-256") return SCRAM_SHA_256;
else if (str == "MONGODB-CR") return MONGODB_CR;
else return SCRAM_SHA_1;
}
} /* end of Robomongo namespace */
@@ -18,6 +18,8 @@ namespace Robomongo {
webView->setPage(new MyWebPage(this));
webView->page()->setUrl(URL);
webView->setContextMenuPolicy(Qt::NoContextMenu);
webView->page()->triggerAction(QWebEnginePage::WebAction::ReloadAndBypassCache);
webView->page()->profile()->setHttpCacheType(QWebEngineProfile::HttpCacheType::NoCache);
auto mainLayout = new QHBoxLayout;
mainLayout->setContentsMargins(-10, -10, -1, -1);