From c5443ad7e7e07d128f7560ace5a0d870654674bc Mon Sep 17 00:00:00 2001 From: Jeroen Weener Date: Mon, 20 Nov 2023 11:49:08 +0100 Subject: [PATCH] [webview_flutter] Support for handling basic authentication requests (Platform Interface) (#5362) Adds the platform interface implementation for basic http authentication. This PR is part of a series of PRs that aim to close https://github.com/flutter/flutter/issues/83556. The PR that contains all changes can be found at https://github.com/flutter/packages/pull/4140. --- .../CHANGELOG.md | 3 +- .../lib/src/platform_navigation_delegate.dart | 11 +++ .../lib/src/platform_webview_controller.dart | 4 +- .../lib/src/types/http_auth_request.dart | 68 +++++++++++++++++++ .../lib/src/types/types.dart | 2 + .../lib/src/types/webview_credential.dart | 24 +++++++ .../pubspec.yaml | 2 +- .../platform_navigation_delegate_test.dart | 13 ++++ ...latform_webview_controller_test.mocks.dart | 11 +++ 9 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/http_auth_request.dart create mode 100644 packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/webview_credential.dart diff --git a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md index 7e0bfbcb11..63074b81e4 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_platform_interface/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 2.7.0 +* Adds support for handling HTTP basic authentication requests. See `PlatformNavigationDelegate.setOnHttpAuthRequest`. * Updates minimum supported SDK version to Flutter 3.10/Dart 3.0. ## 2.6.0 diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_navigation_delegate.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_navigation_delegate.dart index dc3fefbb51..38cf7c19a2 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_navigation_delegate.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_navigation_delegate.dart @@ -30,6 +30,10 @@ typedef WebResourceErrorCallback = void Function(WebResourceError error); /// url of the web view. typedef UrlChangeCallback = void Function(UrlChange change); +/// Signature for callbacks that notify the host application of an +/// authentication request. +typedef HttpAuthRequestCallback = void Function(HttpAuthRequest request); + /// An interface defining navigation events that occur on the native platform. /// /// The [PlatformWebViewController] is notifying this delegate on events that @@ -132,4 +136,11 @@ abstract class PlatformNavigationDelegate extends PlatformInterface { 'setOnUrlChange is not implemented on the current platform.', ); } + + /// Invoked when the web view is requesting authentication. + Future setOnHttpAuthRequest(HttpAuthRequestCallback onHttpAuthRequest) { + throw UnimplementedError( + 'setOnHttpAuthRequest is not implemented on the current platform.', + ); + } } diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart index 806d2a7a6b..d81cdaf235 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/platform_webview_controller.dart @@ -17,7 +17,7 @@ import 'webview_platform.dart' show WebViewPlatform; /// changes. Extending this class (using `extends`) ensures that the subclass /// will get the default implementation, while platform implementations that /// `implements` this interface will be broken by newly added -/// [PlatformWebViewCookieManager] methods. +/// [PlatformWebViewController] methods. abstract class PlatformWebViewController extends PlatformInterface { /// Creates a new [PlatformWebViewController] factory PlatformWebViewController( @@ -267,7 +267,7 @@ abstract class PlatformWebViewController extends PlatformInterface { void Function(PlatformWebViewPermissionRequest request) onPermissionRequest, ) { throw UnimplementedError( - 'setOnPermissionRequest is not implemented on the current platform', + 'setOnPlatformPermissionRequest is not implemented on the current platform', ); } diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/http_auth_request.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/http_auth_request.dart new file mode 100644 index 0000000000..a4a2f1fdd5 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/http_auth_request.dart @@ -0,0 +1,68 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; +import 'webview_credential.dart'; + +/// Defines the parameters of a pending HTTP authentication request received by +/// the webview through a [HttpAuthRequestCallback]. +/// +/// Platform specific implementations can add additional fields by extending +/// this class and providing a factory method that takes the [HttpAuthRequest] +/// as a parameter. +/// +/// This example demonstrates how to extend the [HttpAuthRequest] to provide +/// additional platform specific parameters. +/// +/// When extending [HttpAuthRequest], additional parameters should always accept +/// `null` or have a default value to prevent breaking changes. +/// +/// ```dart +/// @immutable +/// class WKWebViewHttpAuthRequest extends HttpAuthRequest { +/// WKWebViewHttpAuthRequest._( +/// HttpAuthRequest authRequest, +/// this.extraData, +/// ) : super( +/// onProceed: authRequest.onProceed, +/// onCancel: authRequest.onCancel, +/// host: authRequest.host, +/// realm: authRequest.realm, +/// ); +/// +/// factory WKWebViewHttpAuthRequest.fromHttpAuthRequest( +/// HttpAuthRequest authRequest, { +/// String? extraData, +/// }) { +/// return WKWebViewHttpAuthRequest._( +/// authRequest, +/// extraData: extraData, +/// ); +/// } +/// +/// final String? extraData; +/// } +/// ``` +@immutable +class HttpAuthRequest { + /// Creates a [HttpAuthRequest]. + const HttpAuthRequest({ + required this.onProceed, + required this.onCancel, + required this.host, + this.realm, + }); + + /// The callback to authenticate. + final void Function(WebViewCredential credential) onProceed; + + /// The callback to cancel authentication. + final void Function() onCancel; + + /// The host requiring authentication. + final String host; + + /// The realm requiring authentication. + final String? realm; +} diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart index c6cbe6967a..d1a074f792 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/types.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +export 'http_auth_request.dart'; export 'http_response_error.dart'; export 'javascript_console_message.dart'; export 'javascript_log_level.dart'; @@ -18,3 +19,4 @@ export 'platform_webview_widget_creation_params.dart'; export 'url_change.dart'; export 'web_resource_error.dart'; export 'webview_cookie.dart'; +export 'webview_credential.dart'; diff --git a/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/webview_credential.dart b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/webview_credential.dart new file mode 100644 index 0000000000..8c109e9484 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_platform_interface/lib/src/types/webview_credential.dart @@ -0,0 +1,24 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:meta/meta.dart'; + +import '../types/http_auth_request.dart'; + +/// Defines the response parameters of a pending [HttpAuthRequest] received by +/// the webview. +@immutable +class WebViewCredential { + /// Creates a [WebViewCredential]. + const WebViewCredential({ + required this.user, + required this.password, + }); + + /// The user name. + final String user; + + /// The password. + final String password; +} diff --git a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml index e31c90a3a8..1508743dd4 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/webview_flutt issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview_flutter%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.6.0 +version: 2.7.0 environment: sdk: ">=3.0.0 <4.0.0" diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_navigation_delegate_test.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_navigation_delegate_test.dart index ac9f065e2b..2d6d40e70a 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_navigation_delegate_test.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_navigation_delegate_test.dart @@ -142,6 +142,19 @@ void main() { throwsUnimplementedError, ); }); + + test( + 'Default implementation of setOnHttpAuthRequest should throw unimplemented error', + () { + final PlatformNavigationDelegate callbackDelegate = + ExtendsPlatformNavigationDelegate( + const PlatformNavigationDelegateCreationParams()); + + expect( + () => callbackDelegate.setOnHttpAuthRequest((HttpAuthRequest request) {}), + throwsUnimplementedError, + ); + }); } class MockWebViewPlatformWithMixin extends MockWebViewPlatform diff --git a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart index 3ab612ee8c..88d5af24ed 100644 --- a/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_platform_interface/test/platform_webview_controller_test.mocks.dart @@ -124,4 +124,15 @@ class MockPlatformNavigationDelegate extends _i1.Mock returnValue: _i4.Future.value(), returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override + _i4.Future setOnHttpAuthRequest( + _i3.HttpAuthRequestCallback? onHttpAuthRequest) => + (super.noSuchMethod( + Invocation.method( + #setOnHttpAuthRequest, + [onHttpAuthRequest], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); }