From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH dart-login-manager] support new TFA login flow
Date: Mon, 13 Dec 2021 13:24:04 +0100 [thread overview]
Message-ID: <20211213122404.84050-2-w.bumiller@proxmox.com> (raw)
In-Reply-To: <20211213122404.84050-1-w.bumiller@proxmox.com>
For now this just shows a simple dialog to select the TFA type, this
can probably be switched to using tabs or a dropdown or something.
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
---
lib/proxmox_login_form.dart | 78 +++++++++++++++++++++++++++++++++----
lib/proxmox_tfa_form.dart | 17 ++++++--
2 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/lib/proxmox_login_form.dart b/lib/proxmox_login_form.dart
index 59a9f61..da0c02f 100644
--- a/lib/proxmox_login_form.dart
+++ b/lib/proxmox_login_form.dart
@@ -398,12 +398,73 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
var client = await proxclient.authenticate(
'$username@$realm', password, origin, settings.sslValidation!);
- if (client.credentials.tfa) {
- client = await Navigator.of(context).push(MaterialPageRoute(
- builder: (context) => ProxmoxTfaForm(
- apiClient: client,
- ),
+ if (client.credentials.tfa != null) {
+ var tfa = client.credentials.tfa!;
+
+ if (!tfa.totp && !tfa.yubico && tfa.recovery.isEmpty) {
+ return await showDialog<void>(
+ context: context,
+ builder: (context) => AlertDialog(
+ title: Text('TFA Error'),
+ content: Text('No supported TFA method available.'),
+ actions: [
+ FlatButton(
+ onPressed: () => Navigator.of(context).pop(),
+ child: Text('Close'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ final route = (await showDialog<MaterialPageRoute>(
+ context: context,
+ builder: (BuildContext context) {
+ var buttons = <Widget>[];
+
+ void simpleTfa(String label, String tfaType, String message) {
+ buttons.add(
+ SimpleDialogOption(
+ onPressed: () => Navigator.pop(
+ context,
+ MaterialPageRoute(
+ builder: (context) => ProxmoxTfaForm(
+ apiClient: client,
+ tfaType: tfaType,
+ message: message,
+ ),
+ ),
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [ Text(label) ],
+ ),
+ ),
+ );
+ };
+
+ if (tfa.totp) {
+ simpleTfa('TOTP', 'totp', 'Enter your TOTP code');
+ }
+
+ if (tfa.yubico) {
+ simpleTfa('Yubico OTP', 'yubico', 'Enter your Yubico OTP code');
+ }
+
+ if (!tfa.recovery.isEmpty) {
+ simpleTfa('Recovery Code', 'recovery', 'Enter a Recovery Code');
+ }
+
+ return SimpleDialog(
+ title: const Text("Select 2nd Factor"),
+ children: buttons,
+ );
+ }
));
+ if (route == null)
+ return;
+ client = await Navigator.of(context).push(route!);
}
final status = await client.getClusterStatus();
@@ -466,10 +527,11 @@ class _ProxmoxLoginPageState extends State<ProxmoxLoginPage> {
builder: (context) => ProxmoxCertificateErrorDialog(),
);
}
+ } finally {
+ setState(() {
+ _progressModel.inProgress = false;
+ });
}
- setState(() {
- _progressModel.inProgress = false;
- });
}
Future<List<PveAccessDomainModel?>?> _getAccessDomains() async {
diff --git a/lib/proxmox_tfa_form.dart b/lib/proxmox_tfa_form.dart
index db3cfa7..c9eea49 100644
--- a/lib/proxmox_tfa_form.dart
+++ b/lib/proxmox_tfa_form.dart
@@ -1,11 +1,19 @@
import 'package:flutter/material.dart';
import 'package:proxmox_dart_api_client/proxmox_dart_api_client.dart';
+import 'package:proxmox_dart_api_client/src/tfa_challenge.dart';
import 'package:proxmox_login_manager/proxmox_login_form.dart';
class ProxmoxTfaForm extends StatefulWidget {
final ProxmoxApiClient? apiClient;
+ final String? tfaType;
+ final String? message;
- const ProxmoxTfaForm({Key? key, this.apiClient}) : super(key: key);
+ const ProxmoxTfaForm({
+ Key? key,
+ this.apiClient,
+ this.tfaType,
+ this.message,
+ }) : super(key: key);
@override
_ProxmoxTfaFormState createState() => _ProxmoxTfaFormState();
@@ -57,7 +65,7 @@ class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> {
fontWeight: FontWeight.bold),
),
Text(
- 'Check your second factor provider',
+ widget.message!, //'Check your second factor provider',
style: TextStyle(
color: Colors.white38, fontWeight: FontWeight.bold),
),
@@ -108,7 +116,10 @@ class _ProxmoxTfaFormState extends State<ProxmoxTfaForm> {
});
try {
final client =
- await widget.apiClient!.finishTfaChallenge(_codeController.text);
+ await widget.apiClient!.finishTfaChallenge(
+ widget.tfaType!,
+ _codeController.text,
+ );
Navigator.of(context).pop(client);
} on ProxmoxApiException catch (e) {
showDialog(
--
2.30.2
prev parent reply other threads:[~2021-12-13 12:24 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-13 12:24 [pve-devel] [PATCH dart-client] switch to new authentication API Wolfgang Bumiller
2021-12-13 12:24 ` Wolfgang Bumiller [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211213122404.84050-2-w.bumiller@proxmox.com \
--to=w.bumiller@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.