玉兔远程控制 0.1.0-bate4
载入中...
搜索中...
未找到
DlgWebAuth.cpp
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
4#include <QVBoxLayout>
5#include <QRadioButton>
6#include <QLineEdit>
7#include <QTextEdit>
8#include <QPushButton>
9#include <QWebEngineView>
10#include <QLoggingCategory>
11
12#include "DlgWebAuth.h"
13static Q_LOGGING_CATEGORY(log, "WebBrowser.Dlg.Auth")
14CDlgWebAuth::CDlgWebAuth(QWebEngineWebAuthUxRequest *request, QWidget *parent)
15 : QDialog(parent), uxRequest(request), ui(new Ui::CDlgWebAuth)
16{
17 qDebug(log) << Q_FUNC_INFO;
18 ui->setupUi(this);
19
20 buttonGroup = new QButtonGroup(this);
21 buttonGroup->setExclusive(true);
22
23 scrollArea = new QScrollArea(this);
24 selectAccountWidget = new QWidget(this);
25 scrollArea->setWidget(selectAccountWidget);
26 scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
27 scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
28 selectAccountWidget->resize(400, 150);
29 selectAccountLayout = new QVBoxLayout(selectAccountWidget);
30 ui->m_mainVerticalLayout->addWidget(scrollArea);
31 selectAccountLayout->setAlignment(Qt::AlignTop);
32
33 updateDisplay();
34
35 connect(ui->buttonBox, &QDialogButtonBox::rejected, this,
36 qOverload<>(&CDlgWebAuth::onCancelRequest));
37
38 connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
39 qOverload<>(&CDlgWebAuth::onAcceptRequest));
40 QAbstractButton *button = ui->buttonBox->button(QDialogButtonBox::Retry);
41 connect(button, &QAbstractButton::clicked, this, qOverload<>(&CDlgWebAuth::onRetry));
42 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
43}
44
45CDlgWebAuth::~CDlgWebAuth()
46{
47 qDebug(log) << Q_FUNC_INFO;
48 QList<QAbstractButton *> buttons = buttonGroup->buttons();
49 auto itr = buttons.begin();
50 while (itr != buttons.end()) {
51 QAbstractButton *radioButton = *itr;
52 delete radioButton;
53 itr++;
54 }
55
56 if (buttonGroup) {
57 delete buttonGroup;
58 buttonGroup = nullptr;
59 }
60
61 if (ui) {
62 delete ui;
63 ui = nullptr;
64 }
65
66 // selectAccountWidget and it's children will get deleted when scroll area is destroyed
67 if (scrollArea) {
68 delete scrollArea;
69 scrollArea = nullptr;
70 }
71}
72
73void CDlgWebAuth::updateDisplay()
74{
75 switch (uxRequest->state()) {
76 case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
77 setupSelectAccountUI();
78 break;
79 case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
80 setupCollectPinUI();
81 break;
82 case QWebEngineWebAuthUxRequest::WebAuthUxState::FinishTokenCollection:
83 setupFinishCollectTokenUI();
84 break;
85 case QWebEngineWebAuthUxRequest::WebAuthUxState::RequestFailed:
86 setupErrorUI();
87 break;
88 default:
89 break;
90 }
91 adjustSize();
92}
93
94void CDlgWebAuth::setupSelectAccountUI()
95{
96 ui->m_headingLabel->setText(tr("Choose a Passkey"));
97 ui->m_description->setText(tr("Which passkey do you want to use for ")
98 + uxRequest->relyingPartyId() + tr("? "));
99 ui->m_pinGroupBox->setVisible(false);
100 ui->m_mainVerticalLayout->removeWidget(ui->m_pinGroupBox);
101 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
102
103 clearSelectAccountButtons();
104 scrollArea->setVisible(true);
105 selectAccountWidget->resize(this->width(), this->height());
106 QStringList userNames = uxRequest->userNames();
107 // Create radio buttons for each name
108 for (const QString &name : userNames) {
109 QRadioButton *radioButton = new QRadioButton(name);
110 selectAccountLayout->addWidget(radioButton);
111 buttonGroup->addButton(radioButton);
112 }
113
114 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Ok"));
115 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(true);
116 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(true);
117 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
118}
119
120void CDlgWebAuth::setupFinishCollectTokenUI()
121{
122 clearSelectAccountButtons();
123 ui->m_headingLabel->setText(tr("Use your security key with")
124 + uxRequest->relyingPartyId());
125 ui->m_description->setText(
126 tr("Touch your security key again to complete the request."));
127 ui->m_pinGroupBox->setVisible(false);
128 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
129 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
130 scrollArea->setVisible(false);
131}
132void CDlgWebAuth::setupCollectPinUI()
133{
134 clearSelectAccountButtons();
135 ui->m_mainVerticalLayout->addWidget(ui->m_pinGroupBox);
136 ui->m_pinGroupBox->setVisible(true);
137 ui->m_confirmPinLabel->setVisible(false);
138 ui->m_confirmPinLineEdit->setVisible(false);
139 ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Next"));
140 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(true);
141 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(true);
142 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(false);
143 scrollArea->setVisible(false);
144
145 QWebEngineWebAuthPinRequest pinRequestInfo = uxRequest->pinRequest();
146
147 if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Challenge) {
148 ui->m_headingLabel->setText(tr("PIN Required"));
149 ui->m_description->setText(tr("Enter the PIN for your security key"));
150 ui->m_confirmPinLabel->setVisible(false);
151 ui->m_confirmPinLineEdit->setVisible(false);
152 } else {
153 if (pinRequestInfo.reason == QWebEngineWebAuthUxRequest::PinEntryReason::Set) {
154 ui->m_headingLabel->setText(tr("New PIN Required"));
155 ui->m_description->setText(tr("Set new PIN for your security key"));
156 } else {
157 ui->m_headingLabel->setText(tr("Change PIN Required"));
158 ui->m_description->setText(tr("Change PIN for your security key"));
159 }
160 ui->m_confirmPinLabel->setVisible(true);
161 ui->m_confirmPinLineEdit->setVisible(true);
162 }
163
164 QString errorDetails;
165 switch (pinRequestInfo.error) {
166 case QWebEngineWebAuthUxRequest::PinEntryError::NoError:
167 break;
168 case QWebEngineWebAuthUxRequest::PinEntryError::InternalUvLocked:
169 errorDetails = tr("Internal User Verification Locked ");
170 break;
171 case QWebEngineWebAuthUxRequest::PinEntryError::WrongPin:
172 errorDetails = tr("Wrong PIN");
173 break;
174 case QWebEngineWebAuthUxRequest::PinEntryError::TooShort:
175 errorDetails = tr("Too Short");
176 break;
177 case QWebEngineWebAuthUxRequest::PinEntryError::InvalidCharacters:
178 errorDetails = tr("Invalid Characters");
179 break;
180 case QWebEngineWebAuthUxRequest::PinEntryError::SameAsCurrentPin:
181 errorDetails = tr("Same as current PIN");
182 break;
183 }
184 if (!errorDetails.isEmpty()) {
185 errorDetails += tr(" ") + QString::number(pinRequestInfo.remainingAttempts)
186 + tr(" attempts remaining");
187 }
188 ui->m_pinEntryErrorLabel->setText(errorDetails);
189}
190
191void CDlgWebAuth::onCancelRequest()
192{
193 uxRequest->cancel();
194}
195
196void CDlgWebAuth::onAcceptRequest()
197{
198 switch (uxRequest->state()) {
199 case QWebEngineWebAuthUxRequest::WebAuthUxState::SelectAccount:
200 if (buttonGroup->checkedButton()) {
201 uxRequest->setSelectedAccount(buttonGroup->checkedButton()->text());
202 }
203 break;
204 case QWebEngineWebAuthUxRequest::WebAuthUxState::CollectPin:
205 uxRequest->setPin(ui->m_pinLineEdit->text());
206 break;
207 default:
208 break;
209 }
210}
211
212void CDlgWebAuth::setupErrorUI()
213{
214 clearSelectAccountButtons();
215 QString errorDescription;
216 QString errorHeading = tr("Something went wrong");
217 bool isVisibleRetry = false;
218 switch (uxRequest->requestFailureReason()) {
219 case QWebEngineWebAuthUxRequest::RequestFailureReason::Timeout:
220 errorDescription = tr("Request Timeout");
221 break;
222 case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyNotRegistered:
223 errorDescription = tr("Key not registered");
224 break;
225 case QWebEngineWebAuthUxRequest::RequestFailureReason::KeyAlreadyRegistered:
226 errorDescription = tr("You already registered this device."
227 "Try again with device");
228 isVisibleRetry = true;
229 break;
230 case QWebEngineWebAuthUxRequest::RequestFailureReason::SoftPinBlock:
231 errorDescription =
232 tr("The security key is locked because the wrong PIN was entered too many times."
233 "To unlock it, remove and reinsert it.");
234 isVisibleRetry = true;
235 break;
236 case QWebEngineWebAuthUxRequest::RequestFailureReason::HardPinBlock:
237 errorDescription =
238 tr("The security key is locked because the wrong PIN was entered too many times."
239 " You'll need to reset the security key.");
240 break;
241 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorRemovedDuringPinEntry:
242 errorDescription =
243 tr("Authenticator removed during verification. Please reinsert and try again");
244 break;
245 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingResidentKeys:
246 errorDescription = tr("Authenticator doesn't have resident key support");
247 break;
248 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingUserVerification:
249 errorDescription = tr("Authenticator missing user verification");
250 break;
251 case QWebEngineWebAuthUxRequest::RequestFailureReason::AuthenticatorMissingLargeBlob:
252 errorDescription = tr("Authenticator missing Large Blob support");
253 break;
254 case QWebEngineWebAuthUxRequest::RequestFailureReason::NoCommonAlgorithms:
255 errorDescription = tr("Authenticator missing Large Blob support");
256 break;
257 case QWebEngineWebAuthUxRequest::RequestFailureReason::StorageFull:
258 errorDescription = tr("Storage Full");
259 break;
260 case QWebEngineWebAuthUxRequest::RequestFailureReason::UserConsentDenied:
261 errorDescription = tr("User consent denied");
262 break;
263 case QWebEngineWebAuthUxRequest::RequestFailureReason::WinUserCancelled:
264 errorDescription = tr("User Cancelled Request");
265 break;
266 }
267
268 ui->m_headingLabel->setText(errorHeading);
269 ui->m_description->setText(errorDescription);
270 ui->m_description->adjustSize();
271 ui->m_pinGroupBox->setVisible(false);
272 ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
273 ui->buttonBox->button(QDialogButtonBox::Retry)->setVisible(isVisibleRetry);
274 if (isVisibleRetry)
275 ui->buttonBox->button(QDialogButtonBox::Retry)->setFocus();
276 ui->buttonBox->button(QDialogButtonBox::Cancel)->setVisible(true);
277 ui->buttonBox->button(QDialogButtonBox::Cancel)->setText(tr("Close"));
278 scrollArea->setVisible(false);
279}
280
281void CDlgWebAuth::onRetry()
282{
283 uxRequest->retry();
284}
285
286void CDlgWebAuth::clearSelectAccountButtons()
287{
288 QList<QAbstractButton *> buttons = buttonGroup->buttons();
289 auto itr = buttons.begin();
290 while (itr != buttons.end()) {
291 QAbstractButton *radioButton = *itr;
292 selectAccountLayout->removeWidget(radioButton);
293 buttonGroup->removeButton(radioButton);
294 delete radioButton;
295 itr++;
296 }
297}