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