From 520fd6bc38de8e1fd1cd5d835eabda035134f4b7 Mon Sep 17 00:00:00 2001 From: Yegor Vialov Date: Sun, 20 Oct 2019 16:45:44 +0000 Subject: [PATCH] Migrate athentication from webview to deep linking --- android/app/src/main/AndroidManifest.xml | 8 ++++ lib/main.dart | 19 +--------- lib/managers/auth_manager.class.dart | 38 ++++++++++++------- lib/managers/connection_manager.class.dart | 6 +-- .../startup_user_messages_manager.class.dart | 2 +- lib/pages/main.page.dart | 7 ++-- pubspec.yaml | 1 + 7 files changed, 41 insertions(+), 40 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6a160c4..624403e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -52,6 +52,14 @@ + + + + + + LogViewPage(title: "Log"), "/whats-new": (context) => WhatsNewPage(), - "/login": (context) => WebviewScaffold( - url: "${ConnectionManager().oauthUrl}", - appBar: new AppBar( - leading: IconButton( - icon: Icon(Icons.help), - onPressed: () => Launcher.launchURLInCustomTab(context: context, url: "http://ha-client.homemade.systems/docs#authentication") - ), - title: new Text("Login with HA"), - actions: [ - FlatButton( - child: Text("Manual", style: TextStyle(color: Colors.white)), - onPressed: () { - eventBus.fire(ShowPageEvent(path: "/connection-settings", goBackFirst: true)); - }, - ) - ], - ), - ), "/webview": (context) => WebviewScaffold( url: "${(ModalRoute.of(context).settings.arguments as Map)['url']}", appBar: new AppBar( diff --git a/lib/managers/auth_manager.class.dart b/lib/managers/auth_manager.class.dart index bb361fb..909df97 100644 --- a/lib/managers/auth_manager.class.dart +++ b/lib/managers/auth_manager.class.dart @@ -9,24 +9,38 @@ class AuthManager { } AuthManager._internal(); + StreamSubscription deepLinksSubscription; - Future getTempToken({String oauthUrl}) { + Future start({String oauthUrl}) { Completer completer = Completer(); - final flutterWebviewPlugin = new FlutterWebviewPlugin(); - flutterWebviewPlugin.onUrlChanged.listen((String url) { - if (url.startsWith("http://ha-client.homemade.systems/service/auth_callback.html")) { - String authCode = url.split("=")[1]; - Logger.d("We have auth code. Getting temporary access token..."); - ConnectionManager().sendHTTPPost( + deepLinksSubscription?.cancel(); + deepLinksSubscription = getUriLinksStream().listen((Uri uri) { + Logger.d("[LINKED AUTH] We got something private: $uri"); + Logger.d("[LINKED AUTH] code=${uri.queryParameters["code"]}"); + _getTempToken(oauthUrl, uri.queryParameters["code"]) + .then((tempToken) => completer.complete(tempToken)) + .catchError((_){ + completer.completeError(HAError("Auth error")); + }); + }, onError: (err) { + Logger.e("[LINKED AUTH] Error handling linked auth: $e"); + completer.completeError(HAError("Auth error")); + }); + Logger.d("Launching OAuth"); + eventBus.fire(StartAuthEvent(oauthUrl, true)); + return completer.future; + } + + Future _getTempToken(String oauthUrl,String authCode) { + Completer completer = Completer(); + ConnectionManager().sendHTTPPost( endPoint: "/auth/token", contentType: "application/x-www-form-urlencoded", includeAuthHeader: false, - data: "grant_type=authorization_code&code=$authCode&client_id=${Uri.encodeComponent('http://ha-client.homemade.systems/')}" + data: "grant_type=authorization_code&code=$authCode&client_id=${Uri.encodeComponent('http://ha-client.homemade.systems')}" ).then((response) { Logger.d("Got temp token"); String tempToken = json.decode(response)['access_token']; - Logger.d("Closing webview..."); - //flutterWebviewPlugin.close(); eventBus.fire(StartAuthEvent(oauthUrl, false)); completer.complete(tempToken); }).catchError((e) { @@ -35,10 +49,6 @@ class AuthManager { eventBus.fire(StartAuthEvent(oauthUrl, false)); completer.completeError(HAError("Error getting temp token")); }); - } - }); - Logger.d("Launching OAuth"); - eventBus.fire(StartAuthEvent(oauthUrl, true)); return completer.future; } diff --git a/lib/managers/connection_manager.class.dart b/lib/managers/connection_manager.class.dart index eb06438..b3a2765 100644 --- a/lib/managers/connection_manager.class.dart +++ b/lib/managers/connection_manager.class.dart @@ -59,9 +59,9 @@ class ConnectionManager { _token = await storage.read(key: "hacl_llt"); Logger.e("Long-lived token read successful"); oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent( - 'http://ha-client.homemade.systems/')}&redirect_uri=${Uri + 'http://ha-client.homemade.systems')}&redirect_uri=${Uri .encodeComponent( - 'http://ha-client.homemade.systems/service/auth_callback.html')}"; + 'haclient://auth')}"; settingsLoaded = true; } catch (e) { completer.completeError(HAError("Error reading login details", actions: [HAErrorAction.tryAgain(type: HAErrorActionType.FULL_RELOAD), HAErrorAction.loginAgain()])); @@ -79,7 +79,7 @@ class ConnectionManager { if (!stopInit) { if (_token == null) { - AuthManager().getTempToken( + AuthManager().start( oauthUrl: oauthUrl ).then((token) { Logger.d("Token from AuthManager recived"); diff --git a/lib/managers/startup_user_messages_manager.class.dart b/lib/managers/startup_user_messages_manager.class.dart index cdcf766..a21882c 100644 --- a/lib/managers/startup_user_messages_manager.class.dart +++ b/lib/managers/startup_user_messages_manager.class.dart @@ -14,7 +14,7 @@ class StartupUserMessagesManager { bool _supportAppDevelopmentMessageShown; bool _whatsNewMessageShown; static final _supportAppDevelopmentMessageKey = "user-message-shown-support-development_3"; - static final _whatsNewMessageKey = "user-message-shown-whats-new-673"; + static final _whatsNewMessageKey = "user-message-shown-whats-new-675"; void checkMessagesToShow() async { SharedPreferences prefs = await SharedPreferences.getInstance(); diff --git a/lib/pages/main.page.dart b/lib/pages/main.page.dart index b057162..43c6381 100644 --- a/lib/pages/main.page.dart +++ b/lib/pages/main.page.dart @@ -75,8 +75,6 @@ class _MainPageState extends ReceiveShareState with WidgetsBindingObse }); _fullLoad(); - - } @override void receiveShare(Share shared) { @@ -254,7 +252,6 @@ class _MainPageState extends ReceiveShareState with WidgetsBindingObse _showOAuth(); } else { _preventAppRefresh = false; - Navigator.of(context).pop(); } }); } @@ -268,7 +265,9 @@ class _MainPageState extends ReceiveShareState with WidgetsBindingObse void _showOAuth() { _preventAppRefresh = true; - Navigator.of(context).pushNamed('/login'); + Launcher.launchURLInCustomTab( + url: ConnectionManager().oauthUrl + ); } _setErrorState(HAError e) { diff --git a/pubspec.yaml b/pubspec.yaml index 5a4de48..53b5f3d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,7 @@ dependencies: # flutter_svg: ^0.10.3 flutter_custom_tabs: ^0.6.0 firebase_messaging: ^5.1.6 + uni_links: ^0.2.0 flutter_webview_plugin: ^0.3.8 flutter_secure_storage: ^3.3.1+1 device_info: ^0.4.0+3