From 5a88841ffde0a6af78dc0ea1ab75cbb64df1fadf Mon Sep 17 00:00:00 2001 From: fufesou Date: Wed, 14 Jun 2023 15:17:20 +0800 Subject: [PATCH] oidc buttons, depends on server options Signed-off-by: fufesou --- flutter/lib/common/widgets/login.dart | 65 +++++++++++++++++---------- flutter/lib/models/user_model.dart | 15 ++++++- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/flutter/lib/common/widgets/login.dart b/flutter/lib/common/widgets/login.dart index d083f6b81..122e69328 100644 --- a/flutter/lib/common/widgets/login.dart +++ b/flutter/lib/common/widgets/login.dart @@ -4,6 +4,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common/hbbs/hbbs.dart'; import 'package:flutter_hbb/models/platform_model.dart'; +import 'package:flutter_hbb/models/user_model.dart'; import 'package:get/get.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -362,6 +363,8 @@ class LoginWidgetUserPass extends StatelessWidget { } } +const kAuthReqTypeOidc = 'oidc/'; + /// common login dialog for desktop /// call this directly Future loginDialog() async { @@ -375,6 +378,8 @@ Future loginDialog() async { var isInProgress = false; final RxString curOP = ''.obs; + final loginOptions = await UserModel.queryLoginOptions(); + final res = await gFFI.dialogManager.show((setState, close, context) { username.addListener(() { if (usernameMsg != null) { @@ -446,6 +451,42 @@ Future loginDialog() async { setState(() => isInProgress = false); } + final oidcOptions = loginOptions + .where((opt) => opt.startsWith(kAuthReqTypeOidc)) + .map((opt) => opt.substring(kAuthReqTypeOidc.length)) + .toList(); + + thirdAuthWidget() => Offstage( + offstage: oidcOptions.isEmpty, + child: Column( + children: [ + const SizedBox( + height: 8.0, + ), + Center( + child: Text( + translate('or'), + style: TextStyle(fontSize: 16), + )), + const SizedBox( + height: 8.0, + ), + LoginWidgetOP( + ops: [ + ConfigOP(op: 'GitHub', iconWidth: 20), + ConfigOP(op: 'Google', iconWidth: 20), + ConfigOP(op: 'Okta', iconWidth: 38), + ].where((op) => oidcOptions.contains(op.op.toLowerCase())).toList(), + curOP: curOP, + cbLogin: (String username) { + gFFI.userModel.userName.value = username; + close(true); + }, + ), + ], + ), + ); + return CustomAlertDialog( title: Text(translate('Login')), contentBoxConstraints: BoxConstraints(minWidth: 400), @@ -465,29 +506,7 @@ Future loginDialog() async { onLogin: onLogin, userFocusNode: userFocusNode, ), - const SizedBox( - height: 8.0, - ), - Center( - child: Text( - translate('or'), - style: TextStyle(fontSize: 16), - )), - const SizedBox( - height: 8.0, - ), - LoginWidgetOP( - ops: [ - ConfigOP(op: 'GitHub', iconWidth: 20), - ConfigOP(op: 'Google', iconWidth: 20), - ConfigOP(op: 'Okta', iconWidth: 38), - ], - curOP: curOP, - cbLogin: (String username) { - gFFI.userModel.userName.value = username; - close(true); - }, - ), + thirdAuthWidget(), ], ), actions: [dialogButton('Close', onPressed: onDialogCancel)], diff --git a/flutter/lib/models/user_model.dart b/flutter/lib/models/user_model.dart index 7f40b3333..e9da856d4 100644 --- a/flutter/lib/models/user_model.dart +++ b/flutter/lib/models/user_model.dart @@ -109,7 +109,7 @@ class UserModel { try { body = jsonDecode(resp.body); } catch (e) { - print("jsonDecode resp body failed: ${e.toString()}"); + print("login: jsonDecode resp body failed: ${e.toString()}"); rethrow; } @@ -121,7 +121,7 @@ class UserModel { try { loginResponse = LoginResponse.fromJson(body); } catch (e) { - print("jsonDecode LoginResponse failed: ${e.toString()}"); + print("login: jsonDecode LoginResponse failed: ${e.toString()}"); rethrow; } @@ -131,4 +131,15 @@ class UserModel { return loginResponse; } + + static Future> queryLoginOptions() async { + final url = await bind.mainGetApiServer(); + final resp = await http.get(Uri.parse('$url/api/login-options')); + try { + return jsonDecode(resp.body); + } catch (e) { + print("queryLoginOptions: jsonDecode resp body failed: ${e.toString()}"); + return []; + } + } }