| 1 | #include "ServerConfigDlg.h" |
| 2 | #include "ui_ServerConfigDlg.h" |
| 3 | |
| 4 | #include <GitBase.h> |
| 5 | #include <GitConfig.h> |
| 6 | #include <GitQlientStyles.h> |
| 7 | #include <GitQlientSettings.h> |
| 8 | #include <GitHubRestApi.h> |
| 9 | #include <GitLabRestApi.h> |
| 10 | #include <GitServerCache.h> |
| 11 | |
| 12 | #include <QLogger.h> |
| 13 | |
| 14 | #include <QTimer> |
| 15 | #include <QNetworkAccessManager> |
| 16 | #include <QNetworkRequest> |
| 17 | #include <QNetworkReply> |
| 18 | #include <QJsonDocument> |
| 19 | #include <QJsonObject> |
| 20 | #include <QJsonArray> |
| 21 | #include <QFile> |
| 22 | #include <QMessageBox> |
| 23 | #include <QDesktopServices> |
| 24 | |
| 25 | #include <utility> |
| 26 | |
| 27 | using namespace QLogger; |
| 28 | using namespace GitServer; |
| 29 | |
| 30 | namespace |
| 31 | { |
| 32 | enum GitServerPlatform |
| 33 | { |
| 34 | GitHub, |
| 35 | GitHubEnterprise, |
| 36 | GitLab, |
| 37 | Bitbucket |
| 38 | }; |
| 39 | |
| 40 | static const QMap<GitServerPlatform, const char *> repoUrls { { GitHub, "https://api.github.com" }, |
| 41 | { GitHubEnterprise, "" }, |
| 42 | { GitLab, "https://gitlab.com/api/v4" } }; |
| 43 | } |
| 44 | |
| 45 | ServerConfigDlg::ServerConfigDlg(const QSharedPointer<GitServerCache> &gitServerCache, |
| 46 | const GitServer::ConfigData &data, QWidget *parent) |
| 47 | : QDialog(parent) |
| 48 | , ui(new Ui::ServerConfigDlg) |
| 49 | , mGitServerCache(gitServerCache) |
| 50 | , mData(data) |
| 51 | , mManager(new QNetworkAccessManager()) |
| 52 | { |
| 53 | setStyleSheet(GitQlientStyles::getStyles()); |
| 54 | |
| 55 | ui->setupUi(this); |
| 56 | |
| 57 | connect(ui->cbServer, &QComboBox::currentTextChanged, this, &ServerConfigDlg::onServerChanged); |
| 58 | |
| 59 | ui->leEndPoint->setHidden(true); |
| 60 | |
| 61 | GitQlientSettings settings("" ); |
| 62 | ui->leUserName->setText(mData.user); |
| 63 | ui->leUserToken->setText(mData.token); |
| 64 | ui->leEndPoint->setText( |
| 65 | settings.globalValue(QString("%1/endpoint" ).arg(mData.serverUrl), repoUrls.value(GitHub)).toString()); |
| 66 | |
| 67 | ui->cbServer->insertItem(GitHub, "GitHub" , repoUrls.value(GitHub)); |
| 68 | ui->cbServer->insertItem(GitHubEnterprise, "GitHub Enterprise" , repoUrls.value(GitHubEnterprise)); |
| 69 | |
| 70 | if (mData.serverUrl.contains("github" )) |
| 71 | { |
| 72 | const auto index = repoUrls.key(ui->leEndPoint->text().toUtf8(), GitHubEnterprise); |
| 73 | ui->cbServer->setCurrentIndex(index); |
| 74 | } |
| 75 | else |
| 76 | { |
| 77 | ui->cbServer->insertItem(GitLab, "GitLab" , repoUrls.value(GitLab)); |
| 78 | ui->cbServer->setCurrentIndex(GitLab); |
| 79 | ui->cbServer->setVisible(false); |
| 80 | } |
| 81 | |
| 82 | ui->lAccessToken->setText(tr("How to get a token?" )); |
| 83 | connect(ui->lAccessToken, &ButtonLink::clicked, [this]() { |
| 84 | const auto url = mData.serverUrl.contains("github" ) |
| 85 | ? "https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token" |
| 86 | : "https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html" ; |
| 87 | QDesktopServices::openUrl(QUrl(QString::fromUtf8(url))); |
| 88 | }); |
| 89 | |
| 90 | connect(ui->leUserToken, &QLineEdit::editingFinished, this, &ServerConfigDlg::checkToken); |
| 91 | connect(ui->leUserToken, &QLineEdit::returnPressed, this, &ServerConfigDlg::accept); |
| 92 | connect(ui->pbAccept, &QPushButton::clicked, this, &ServerConfigDlg::accept); |
| 93 | connect(ui->pbCancel, &QPushButton::clicked, this, &ServerConfigDlg::reject); |
| 94 | connect(ui->pbTest, &QPushButton::clicked, this, &ServerConfigDlg::testToken); |
| 95 | } |
| 96 | |
| 97 | ServerConfigDlg::~ServerConfigDlg() |
| 98 | { |
| 99 | delete mManager; |
| 100 | delete ui; |
| 101 | } |
| 102 | |
| 103 | void ServerConfigDlg::checkToken() |
| 104 | { |
| 105 | if (ui->leUserToken->text().isEmpty()) |
| 106 | ui->leUserName->setStyleSheet("border: 1px solid red;" ); |
| 107 | } |
| 108 | |
| 109 | void ServerConfigDlg::accept() |
| 110 | { |
| 111 | const auto endpoint = ui->cbServer->currentIndex() == GitHubEnterprise ? ui->leEndPoint->text() |
| 112 | : ui->cbServer->currentData().toString(); |
| 113 | GitQlientSettings settings("" ); |
| 114 | settings.setGlobalValue(QString("%1/user" ).arg(mData.serverUrl), ui->leUserName->text()); |
| 115 | settings.setGlobalValue(QString("%1/token" ).arg(mData.serverUrl), ui->leUserToken->text()); |
| 116 | settings.setGlobalValue(QString("%1/endpoint" ).arg(mData.serverUrl), endpoint); |
| 117 | |
| 118 | connect(mGitServerCache.get(), &GitServerCache::errorOccurred, this, &ServerConfigDlg::onGitServerError); |
| 119 | connect(mGitServerCache.get(), &GitServerCache::connectionTested, this, [this]() { onDataValidated(); }); |
| 120 | |
| 121 | mGitServerCache->init(mData.serverUrl, mData.repoInfo); |
| 122 | } |
| 123 | |
| 124 | void ServerConfigDlg::testToken() |
| 125 | { |
| 126 | if (ui->leUserToken->text().isEmpty()) |
| 127 | ui->leUserName->setStyleSheet("border: 1px solid red;" ); |
| 128 | else |
| 129 | { |
| 130 | const auto endpoint = ui->cbServer->currentIndex() == GitHubEnterprise ? ui->leEndPoint->text() |
| 131 | : ui->cbServer->currentData().toString(); |
| 132 | IRestApi *api = nullptr; |
| 133 | |
| 134 | if (ui->cbServer->currentIndex() == GitLab) |
| 135 | { |
| 136 | api = new GitLabRestApi(ui->leUserName->text(), mData.repoInfo.second, mData.serverUrl, |
| 137 | { ui->leUserName->text(), ui->leUserToken->text(), endpoint }, this); |
| 138 | } |
| 139 | else |
| 140 | { |
| 141 | api = new GitHubRestApi(mData.repoInfo.first, mData.repoInfo.second, |
| 142 | { ui->leUserName->text(), ui->leUserToken->text(), endpoint }, this); |
| 143 | } |
| 144 | |
| 145 | api->testConnection(); |
| 146 | |
| 147 | connect(api, &IRestApi::connectionTested, this, &ServerConfigDlg::onTestSucceeded); |
| 148 | connect(api, &IRestApi::errorOccurred, this, &ServerConfigDlg::onGitServerError); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | void ServerConfigDlg::onServerChanged() |
| 153 | { |
| 154 | ui->leEndPoint->setVisible(ui->cbServer->currentIndex() == GitHubEnterprise); |
| 155 | } |
| 156 | |
| 157 | void ServerConfigDlg::onTestSucceeded() |
| 158 | { |
| 159 | ui->lTestResult->setText(tr("Token confirmed!" )); |
| 160 | QTimer::singleShot(3000, ui->lTestResult, &QLabel::clear); |
| 161 | } |
| 162 | |
| 163 | void ServerConfigDlg::onGitServerError(const QString &error) |
| 164 | { |
| 165 | QMessageBox::warning(this, tr("API access error!" ), error); |
| 166 | } |
| 167 | |
| 168 | void ServerConfigDlg::onDataValidated() |
| 169 | { |
| 170 | emit configured(); |
| 171 | |
| 172 | QDialog::accept(); |
| 173 | } |
| 174 | |