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 | |