From c4a4e347600b0402a80cedc364144b78fcd7d83c Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Mon, 1 May 2023 10:41:35 +0200 Subject: [PATCH 1/5] FP-87: Split the build method into seperate private helpers --- example/lib/screens/login_screen.dart | 241 +++++++++++++------------- 1 file changed, 120 insertions(+), 121 deletions(-) diff --git a/example/lib/screens/login_screen.dart b/example/lib/screens/login_screen.dart index cb9d174b..03f4b6ea 100644 --- a/example/lib/screens/login_screen.dart +++ b/example/lib/screens/login_screen.dart @@ -181,136 +181,135 @@ class _LoginScreenState extends State { ), body: isLoading ? Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CircularProgressIndicator(), - SizedBox( - height: 20, - ), - ElevatedButton( - onPressed: () { - cancelRegistration(); - }, - child: Text('Cancel'), - ), - ], - ), + child: _buildCancelRegistrationWidget(), ) : Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox( - height: 20, - ), - FutureBuilder>( - //userProfiles - future: getUserProfiles(), - builder: (context, snapshot) { - final userProfileData = snapshot.data; - return (userProfileData != null && - userProfileData.length > 0) - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "──── Login ────", - style: TextStyle(fontSize: 30), - textAlign: TextAlign.center, - ), - _buildImplicitUserData( - userProfileData.first.profileId), - ElevatedButton( - onPressed: () { - authenticate( - userProfileData.first.profileId, - null); - }, - child: Text('Preferred authenticator'), - ), - Row( - mainAxisAlignment: - MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () { - authenticate( - userProfileData.first.profileId, - OWAuthenticatorType.pin); - }, - child: Text('Pin'), - ), - SizedBox(height: 10, width: 10), - ElevatedButton( - onPressed: () { - authenticate( - userProfileData.first.profileId, - OWAuthenticatorType.biometric); - }, - child: Text('Biometrics'), - ), - ], - ), - ]) - : SizedBox.shrink(); - }), - SizedBox( - height: 20, - ), - Text( - "──── Register ────", - style: TextStyle(fontSize: 30), - ), - SizedBox( - height: 20, - ), - ElevatedButton( - onPressed: () { - openWeb(); - }, - child: Text('Run WEB'), - ), - SizedBox( - height: 20, - ), - FutureBuilder>( - future: Onegini.instance.userClient.getIdentityProviders(), - builder: (BuildContext context, snapshot) { - final identityProviders = snapshot.data; - return identityProviders != null - ? PopupMenuButton( - child: Container( - padding: EdgeInsets.all(20), - color: Colors.blue, - child: Text( - "Run with providers", - style: TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.w700), - ), - ), - onSelected: (value) { - registrationWithIdentityProvider(value); - }, - itemBuilder: (context) { - return identityProviders - .map((e) => PopupMenuItem( - child: Text(e.name), - value: e.id, - )) - .toList(); - }) - : SizedBox.shrink(); - }, - ), + SizedBox(height: 20), + _buildLoginWidget(), + SizedBox(height: 20), + _buildRegisterWidget(), ], ), ), ); } + + FutureBuilder> _buildLoginWidget() { + return FutureBuilder>( + //userProfiles + future: getUserProfiles(), + builder: (context, snapshot) { + final userProfileData = snapshot.data; + return (userProfileData != null && userProfileData.length > 0) + ? Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "──── Login ────", + style: TextStyle(fontSize: 30), + textAlign: TextAlign.center, + ), + _buildImplicitUserData(userProfileData.first.profileId), + ElevatedButton( + onPressed: () { + authenticate(userProfileData.first.profileId, null); + }, + child: Text('Preferred authenticator'), + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + authenticate(userProfileData.first.profileId, + OWAuthenticatorType.pin); + }, + child: Text('Pin'), + ), + SizedBox(height: 10, width: 10), + ElevatedButton( + onPressed: () { + authenticate(userProfileData.first.profileId, + OWAuthenticatorType.biometric); + }, + child: Text('Biometrics'), + ), + ], + ), + ]) + : SizedBox.shrink(); + }); + } + + Column _buildRegisterWidget() { + return Column( + children: [ + Text( + "──── Register ────", + style: TextStyle(fontSize: 30), + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + openWeb(); + }, + child: Text('Run WEB'), + ), + SizedBox(height: 20), + FutureBuilder>( + future: Onegini.instance.userClient.getIdentityProviders(), + builder: (BuildContext context, snapshot) { + final identityProviders = snapshot.data; + return identityProviders != null + ? PopupMenuButton( + child: Container( + padding: EdgeInsets.all(20), + color: Colors.blue, + child: Text( + "Run with providers", + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.w700), + ), + ), + onSelected: (value) { + registrationWithIdentityProvider(value); + }, + itemBuilder: (context) { + return identityProviders + .map((e) => PopupMenuItem( + child: Text(e.name), + value: e.id, + )) + .toList(); + }) + : SizedBox.shrink(); + }, + ), + ], + ); + } + + Column _buildCancelRegistrationWidget() { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CircularProgressIndicator(), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + cancelRegistration(); + }, + child: Text('Cancel'), + ), + ], + ); + } } From 5754b77f15fb61f1bbb94acbb39ab0e39888da2e Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Mon, 1 May 2023 11:44:37 +0200 Subject: [PATCH 2/5] FP-87: Add a profileId selector on login screen --- example/lib/screens/login_screen.dart | 40 +++++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/example/lib/screens/login_screen.dart b/example/lib/screens/login_screen.dart index 03f4b6ea..5c25874a 100644 --- a/example/lib/screens/login_screen.dart +++ b/example/lib/screens/login_screen.dart @@ -11,6 +11,7 @@ import 'package:onegini/onegini.dart'; import 'package:onegini/onegini.gen.dart'; import 'package:onegini_example/ow_broadcast_helper.dart'; import 'package:onegini_example/screens/user_screen.dart'; +import 'package:collection/collection.dart'; import '../components/display_toast.dart'; @@ -23,6 +24,7 @@ class _LoginScreenState extends State { bool isLoading = false; List>? registrationSubscriptions; List>? authenticationSubscriptions; + String? selectedProfileId; @override initState() { @@ -31,7 +33,6 @@ class _LoginScreenState extends State { OWBroadcastHelper.initRegistrationSubscriptions(context); this.authenticationSubscriptions = OWBroadcastHelper.initAuthenticationSubscriptions(context); - super.initState(); } @@ -124,6 +125,9 @@ class _LoginScreenState extends State { Future> getUserProfiles() async { try { var profiles = await Onegini.instance.userClient.getUserProfiles(); + if (selectedProfileId == null) { + selectedProfileId = profiles.firstOrNull?.profileId; + } return profiles; } catch (err) { print("caught error in getUserProfiles: $err"); @@ -132,7 +136,6 @@ class _LoginScreenState extends State { } Future getImplicitUserDetails(String profileId) async { - var returnString = ""; try { await Onegini.instance.userClient .authenticateUserImplicitly(profileId, ["read"]); @@ -143,9 +146,7 @@ class _LoginScreenState extends State { var res = json.decode(response.body); - returnString = res["decorated_user_id"]; - - return returnString; + return res["decorated_user_id"]; } catch (err) { print("Caught error: $err"); return "Error occured check logs"; @@ -204,7 +205,10 @@ class _LoginScreenState extends State { future: getUserProfiles(), builder: (context, snapshot) { final userProfileData = snapshot.data; - return (userProfileData != null && userProfileData.length > 0) + final profileId = selectedProfileId; + return (userProfileData != null && + userProfileData.length > 0 && + profileId != null) ? Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, @@ -214,10 +218,11 @@ class _LoginScreenState extends State { style: TextStyle(fontSize: 30), textAlign: TextAlign.center, ), - _buildImplicitUserData(userProfileData.first.profileId), + _buildSelectUserProfile(userProfileData), + _buildImplicitUserData(profileId), ElevatedButton( onPressed: () { - authenticate(userProfileData.first.profileId, null); + authenticate(profileId, null); }, child: Text('Preferred authenticator'), ), @@ -226,16 +231,15 @@ class _LoginScreenState extends State { children: [ ElevatedButton( onPressed: () { - authenticate(userProfileData.first.profileId, - OWAuthenticatorType.pin); + authenticate(profileId, OWAuthenticatorType.pin); }, child: Text('Pin'), ), SizedBox(height: 10, width: 10), ElevatedButton( onPressed: () { - authenticate(userProfileData.first.profileId, - OWAuthenticatorType.biometric); + authenticate( + profileId, OWAuthenticatorType.biometric); }, child: Text('Biometrics'), ), @@ -246,6 +250,18 @@ class _LoginScreenState extends State { }); } + DropdownButton _buildSelectUserProfile(List profiles) { + return DropdownButton( + value: selectedProfileId, + items: profiles + .map((e) => + DropdownMenuItem(value: e.profileId, child: Text(e.profileId))) + .toList(), + onChanged: (profileId) => { + setState(() => {selectedProfileId = profileId}) + }); + } + Column _buildRegisterWidget() { return Column( children: [ From bd2b76c73e2a8da5c4c02149d28645b0d5e35462 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Mon, 1 May 2023 11:48:01 +0200 Subject: [PATCH 3/5] FP-87: Add a profileId menu item to the user_screen sidebar --- example/lib/screens/user_screen.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example/lib/screens/user_screen.dart b/example/lib/screens/user_screen.dart index 848d69f2..cdfd3426 100644 --- a/example/lib/screens/user_screen.dart +++ b/example/lib/screens/user_screen.dart @@ -227,6 +227,11 @@ class _UserScreenState extends State with RouteAware { DrawerHeader( child: Container(), ), + ListTile( + title: Text("ProfileId: ${profileId}"), + leading: Icon(Icons.person), + ), + Divider(), ListTile( title: Text("Authenticators"), leading: Icon(Icons.lock_rounded), From 7aebc0614f84935cbf9c704b95225a98e2357375 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Mon, 1 May 2023 12:13:47 +0200 Subject: [PATCH 4/5] FP-87: Improve state handling for userProfiles in login_screen --- example/lib/screens/login_screen.dart | 98 +++++++++++++-------------- 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/example/lib/screens/login_screen.dart b/example/lib/screens/login_screen.dart index 5c25874a..cbe4729c 100644 --- a/example/lib/screens/login_screen.dart +++ b/example/lib/screens/login_screen.dart @@ -24,6 +24,7 @@ class _LoginScreenState extends State { bool isLoading = false; List>? registrationSubscriptions; List>? authenticationSubscriptions; + List userProfiles = []; String? selectedProfileId; @override @@ -34,6 +35,7 @@ class _LoginScreenState extends State { this.authenticationSubscriptions = OWBroadcastHelper.initAuthenticationSubscriptions(context); super.initState(); + getUserProfiles(); } @override @@ -124,10 +126,13 @@ class _LoginScreenState extends State { Future> getUserProfiles() async { try { - var profiles = await Onegini.instance.userClient.getUserProfiles(); - if (selectedProfileId == null) { - selectedProfileId = profiles.firstOrNull?.profileId; - } + final profiles = await Onegini.instance.userClient.getUserProfiles(); + setState(() { + userProfiles = profiles; + if (selectedProfileId == null) { + selectedProfileId = profiles.firstOrNull?.profileId; + } + }); return profiles; } catch (err) { print("caught error in getUserProfiles: $err"); @@ -199,55 +204,46 @@ class _LoginScreenState extends State { ); } - FutureBuilder> _buildLoginWidget() { - return FutureBuilder>( - //userProfiles - future: getUserProfiles(), - builder: (context, snapshot) { - final userProfileData = snapshot.data; - final profileId = selectedProfileId; - return (userProfileData != null && - userProfileData.length > 0 && - profileId != null) - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, + Widget _buildLoginWidget() { + final profileId = selectedProfileId; + return (userProfiles.length > 0 && profileId != null) + ? Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "──── Login ────", + style: TextStyle(fontSize: 30), + textAlign: TextAlign.center, + ), + _buildSelectUserProfile(userProfiles), + _buildImplicitUserData(profileId), + ElevatedButton( + onPressed: () { + authenticate(profileId, null); + }, + child: Text('Preferred authenticator'), + ), + Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( - "──── Login ────", - style: TextStyle(fontSize: 30), - textAlign: TextAlign.center, - ), - _buildSelectUserProfile(userProfileData), - _buildImplicitUserData(profileId), - ElevatedButton( - onPressed: () { - authenticate(profileId, null); - }, - child: Text('Preferred authenticator'), - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () { - authenticate(profileId, OWAuthenticatorType.pin); - }, - child: Text('Pin'), - ), - SizedBox(height: 10, width: 10), - ElevatedButton( - onPressed: () { - authenticate( - profileId, OWAuthenticatorType.biometric); - }, - child: Text('Biometrics'), - ), - ], - ), - ]) - : SizedBox.shrink(); - }); + ElevatedButton( + onPressed: () { + authenticate(profileId, OWAuthenticatorType.pin); + }, + child: Text('Pin'), + ), + SizedBox(height: 10, width: 10), + ElevatedButton( + onPressed: () { + authenticate(profileId, OWAuthenticatorType.biometric); + }, + child: Text('Biometrics'), + ), + ], + ), + ]) + : SizedBox.shrink(); } DropdownButton _buildSelectUserProfile(List profiles) { From 2c6acaa8113514629ddb4e1735eadeeb576eca30 Mon Sep 17 00:00:00 2001 From: Michiel Vrins Date: Mon, 1 May 2023 12:18:58 +0200 Subject: [PATCH 5/5] FP-87: Fix device info not loading correctly --- example/lib/screens/user_screen.dart | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/example/lib/screens/user_screen.dart b/example/lib/screens/user_screen.dart index cdfd3426..7750e2dd 100644 --- a/example/lib/screens/user_screen.dart +++ b/example/lib/screens/user_screen.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -430,8 +429,7 @@ class _InfoState extends State { ResourceRequestType.anonymous, RequestDetails( path: "application-details", method: HttpRequestMethod.get)); - var res = json.decode(response.body); - return applicationDetailsFromJson(res); + return applicationDetailsFromJson(response.body); } Future getClientResource() async { @@ -470,11 +468,11 @@ class _InfoState extends State { children: [ Text( "application identifier => ", - style: TextStyle(fontSize: 18), + style: TextStyle(fontSize: 15), ), Text( snapshot.data?.applicationIdentifier ?? "", - style: TextStyle(fontSize: 18), + style: TextStyle(fontSize: 15), ) ], ), @@ -485,11 +483,11 @@ class _InfoState extends State { children: [ Text( "application platform => ", - style: TextStyle(fontSize: 18), + style: TextStyle(fontSize: 15), ), Text( snapshot.data?.applicationPlatform ?? "", - style: TextStyle(fontSize: 18), + style: TextStyle(fontSize: 15), ) ], ), @@ -500,11 +498,11 @@ class _InfoState extends State { children: [ Text( "application version => ", - style: TextStyle(fontSize: 18), + style: TextStyle(fontSize: 15), ), Text( snapshot.data?.applicationVersion ?? "", - style: TextStyle(fontSize: 18), + style: TextStyle(fontSize: 15), ) ], ),