Changeset 251498 in webkit


Ignore:
Timestamp:
Oct 23, 2019 1:59:52 PM (4 years ago)
Author:
jiewen_tan@apple.com
Message:

[WebAuthn] Add more information to _WKWebAuthenticationPanel
https://bugs.webkit.org/show_bug.cgi?id=202561
<rdar://problem/55973910>

Reviewed by Youenn Fablet.

Source/WebCore:

Covered by new tests within existing test files.

  • Modules/webauthn/AuthenticatorCoordinator.cpp:
  • Modules/webauthn/WebAuthenticationConstants.h:

Source/WebKit:

This change adds transports and type to _WKWebAuthenticationPanel such that
clients can know what transport the current ceremony demands and the type of
the current ceremony. These extra information allow clients to give users
more specific instructions to interact with authenticators.

To pass transports to client, the way how them is collected is changed significantly:
1) The timing is moved to runPanel before the client delegate call.
2) NfcService::isAvailable is added for AuthenticatorManager to determine if NFC
is available in the current device.
3) AuthenticatorManager::filterTransports is added to filter transports requested
by RP to ones that are available. This process is handled by each service naturally
before.
4) AuthenticatorManager::startRequest is now being splitted into AuthenticatorManager::handleRequest,
AuthenticatorManager::runPanel and AuthenticatorManager::getTransports.

To pass type to _WKWebAuthenticationPanel, ClientDataType is moved from
WebCore::AuthenticatorCoordinator to WebCore::WebAuthenticationConstants in
order to be reused to indicate the ceremony type.

  • UIProcess/API/APIWebAuthenticationPanel.cpp:

(API::WebAuthenticationPanel::create):
(API::WebAuthenticationPanel::WebAuthenticationPanel):

  • UIProcess/API/APIWebAuthenticationPanel.h:
  • UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
  • UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:

(-[_WKWebAuthenticationPanel relyingPartyID]):
(wkWebAuthenticationTransport):
(-[_WKWebAuthenticationPanel transports]):
(wkWebAuthenticationType):
(-[_WKWebAuthenticationPanel type]):

  • UIProcess/WebAuthentication/AuthenticatorManager.cpp:

(WebKit::WebCore::collectTransports):
(WebKit::WebCore::getClientDataType):
(WebKit::AuthenticatorManager::handleRequest):
(WebKit::AuthenticatorManager::filterTransports const):
(WebKit::AuthenticatorManager::startDiscovery):
(WebKit::AuthenticatorManager::initTimeOutTimer):
(WebKit::AuthenticatorManager::runPanel):
(WebKit::AuthenticatorManager::getTransports const):
(WebKit::AuthenticatorManager::respondReceivedInternal): Deleted.
(WebKit::AuthenticatorManager::startRequest): Deleted.

  • UIProcess/WebAuthentication/AuthenticatorManager.h:

(WebKit::AuthenticatorManager::respondReceivedInternal):

  • UIProcess/WebAuthentication/Cocoa/NfcService.h:
  • UIProcess/WebAuthentication/Cocoa/NfcService.mm:

(WebKit::NfcService::isAvailable):
(WebKit::NfcService::platformStartDiscovery):

  • UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp:

(WebKit::MockAuthenticatorManager::filterTransports const):

  • UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.h:

Tools:

Adds new API tests.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:

(-[TestWebAuthenticationPanelUIDelegate _webView:runWebAuthenticationPanel:initiatedByFrame:completionHandler:]):
(-[TestWebAuthenticationPanelUIDelegate panel]):
(TestWebKitAPI::TEST):

  • TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid.html: Added.
Location:
trunk
Files:
1 added
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r251495 r251498  
     12019-10-22  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Add more information to _WKWebAuthenticationPanel
     4        https://bugs.webkit.org/show_bug.cgi?id=202561
     5        <rdar://problem/55973910>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        Covered by new tests within existing test files.
     10
     11        * Modules/webauthn/AuthenticatorCoordinator.cpp:
     12        * Modules/webauthn/WebAuthenticationConstants.h:
     13
    1142019-10-23  Chris Dumez  <cdumez@apple.com>
    215
  • trunk/Source/WebCore/Modules/webauthn/AuthenticatorCoordinator.cpp

    r251489 r251498  
    4343#include "LegacySchemeRegistry.h"
    4444#include "SecurityOrigin.h"
     45#include "WebAuthenticationConstants.h"
    4546#include <pal/crypto/CryptoDigest.h>
    4647#include <wtf/JSONValues.h>
     
    5152
    5253namespace AuthenticatorCoordinatorInternal {
    53 
    54 enum class ClientDataType {
    55     Create,
    56     Get
    57 };
    5854
    5955// FIXME(181948): Add token binding ID.
  • trunk/Source/WebCore/Modules/webauthn/WebAuthenticationConstants.h

    r245638 r251498  
    7171const char noneAttestationValue[] = "none";
    7272
     73// https://www.w3.org/TR/webauthn-1/#dom-collectedclientdata-type
     74enum class ClientDataType : bool {
     75    Create,
     76    Get
     77};
     78
    7379} // namespace WebCore
  • trunk/Source/WebKit/ChangeLog

    r251494 r251498  
     12019-10-22  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Add more information to _WKWebAuthenticationPanel
     4        https://bugs.webkit.org/show_bug.cgi?id=202561
     5        <rdar://problem/55973910>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        This change adds transports and type to _WKWebAuthenticationPanel such that
     10        clients can know what transport the current ceremony demands and the type of
     11        the current ceremony. These extra information allow clients to give users
     12        more specific instructions to interact with authenticators.
     13
     14        To pass transports to client, the way how them is collected is changed significantly:
     15        1) The timing is moved to runPanel before the client delegate call.
     16        2) NfcService::isAvailable is added for AuthenticatorManager to determine if NFC
     17        is available in the current device.
     18        3) AuthenticatorManager::filterTransports is added to filter transports requested
     19        by RP to ones that are available. This process is handled by each service naturally
     20        before.
     21        4) AuthenticatorManager::startRequest is now being splitted into AuthenticatorManager::handleRequest,
     22        AuthenticatorManager::runPanel and AuthenticatorManager::getTransports.
     23
     24        To pass type to _WKWebAuthenticationPanel, ClientDataType is moved from
     25        WebCore::AuthenticatorCoordinator to WebCore::WebAuthenticationConstants in
     26        order to be reused to indicate the ceremony type.
     27
     28        * UIProcess/API/APIWebAuthenticationPanel.cpp:
     29        (API::WebAuthenticationPanel::create):
     30        (API::WebAuthenticationPanel::WebAuthenticationPanel):
     31        * UIProcess/API/APIWebAuthenticationPanel.h:
     32        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h:
     33        * UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm:
     34        (-[_WKWebAuthenticationPanel relyingPartyID]):
     35        (wkWebAuthenticationTransport):
     36        (-[_WKWebAuthenticationPanel transports]):
     37        (wkWebAuthenticationType):
     38        (-[_WKWebAuthenticationPanel type]):
     39        * UIProcess/WebAuthentication/AuthenticatorManager.cpp:
     40        (WebKit::WebCore::collectTransports):
     41        (WebKit::WebCore::getClientDataType):
     42        (WebKit::AuthenticatorManager::handleRequest):
     43        (WebKit::AuthenticatorManager::filterTransports const):
     44        (WebKit::AuthenticatorManager::startDiscovery):
     45        (WebKit::AuthenticatorManager::initTimeOutTimer):
     46        (WebKit::AuthenticatorManager::runPanel):
     47        (WebKit::AuthenticatorManager::getTransports const):
     48        (WebKit::AuthenticatorManager::respondReceivedInternal): Deleted.
     49        (WebKit::AuthenticatorManager::startRequest): Deleted.
     50        * UIProcess/WebAuthentication/AuthenticatorManager.h:
     51        (WebKit::AuthenticatorManager::respondReceivedInternal):
     52        * UIProcess/WebAuthentication/Cocoa/NfcService.h:
     53        * UIProcess/WebAuthentication/Cocoa/NfcService.mm:
     54        (WebKit::NfcService::isAvailable):
     55        (WebKit::NfcService::platformStartDiscovery):
     56        * UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp:
     57        (WebKit::MockAuthenticatorManager::filterTransports const):
     58        * UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.h:
     59
    1602019-10-23  Yury Semikhatsky  <yurys@chromium.org>
    261
  • trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanel.cpp

    r251494 r251498  
    3131#include "APIWebAuthenticationPanelClient.h"
    3232#include "AuthenticatorManager.h"
     33#include <WebCore/WebAuthenticationConstants.h>
    3334
    3435namespace API {
     36using namespace WebCore;
    3537using namespace WebKit;
    3638
    37 Ref<WebAuthenticationPanel> WebAuthenticationPanel::create(const AuthenticatorManager& manager, const WTF::String& rpId)
     39Ref<WebAuthenticationPanel> WebAuthenticationPanel::create(const AuthenticatorManager& manager, const WTF::String& rpId, const TransportSet& transports, ClientDataType type)
    3840{
    39     return adoptRef(*new WebAuthenticationPanel(manager, rpId));
     41    return adoptRef(*new WebAuthenticationPanel(manager, rpId, transports, type));
    4042}
    4143
    42 WebAuthenticationPanel::WebAuthenticationPanel(const AuthenticatorManager& manager, const WTF::String& rpId)
     44WebAuthenticationPanel::WebAuthenticationPanel(const AuthenticatorManager& manager, const WTF::String& rpId, const TransportSet& transports, ClientDataType type)
    4345    : m_manager(makeWeakPtr(manager))
    4446    , m_rpId(rpId)
    4547    , m_client(WTF::makeUniqueRef<WebAuthenticationPanelClient>())
     48    , m_clientDataType(type)
    4649{
     50    m_transports = Vector<AuthenticatorTransport>();
     51    m_transports.reserveInitialCapacity(AuthenticatorManager::maxTransportNumber);
     52    if (transports.contains(AuthenticatorTransport::Usb))
     53        m_transports.uncheckedAppend(AuthenticatorTransport::Usb);
     54    if (transports.contains(AuthenticatorTransport::Nfc))
     55        m_transports.uncheckedAppend(AuthenticatorTransport::Nfc);
    4756}
    4857
  • trunk/Source/WebKit/UIProcess/API/APIWebAuthenticationPanel.h

    r251494 r251498  
    2929
    3030#include "APIObject.h"
     31#include <WebCore/AuthenticatorTransport.h>
    3132#include <wtf/UniqueRef.h>
    3233#include <wtf/WeakPtr.h>
    3334#include <wtf/text/WTFString.h>
     35
     36namespace WebCore {
     37enum class ClientDataType : bool;
     38}
    3439
    3540namespace WebKit {
     
    4348class WebAuthenticationPanel final : public ObjectImpl<Object::Type::WebAuthenticationPanel>, public CanMakeWeakPtr<WebAuthenticationPanel> {
    4449public:
    45     static Ref<WebAuthenticationPanel> create(const WebKit::AuthenticatorManager&, const WTF::String& rpId);
     50    using TransportSet = HashSet<WebCore::AuthenticatorTransport, WTF::IntHash<WebCore::AuthenticatorTransport>, WTF::StrongEnumHashTraits<WebCore::AuthenticatorTransport>>;
     51
     52    static Ref<WebAuthenticationPanel> create(const WebKit::AuthenticatorManager&, const WTF::String& rpId, const TransportSet&, WebCore::ClientDataType);
    4653    ~WebAuthenticationPanel();
    4754
    4855    WTF::String rpId() const { return m_rpId; }
     56    const Vector<WebCore::AuthenticatorTransport>& transports() const { return m_transports; }
     57    WebCore::ClientDataType clientDataType() const { return m_clientDataType; }
    4958    void cancel() const;
    5059
     
    5362
    5463private:
    55     WebAuthenticationPanel(const WebKit::AuthenticatorManager&, const WTF::String& rpId);
     64    WebAuthenticationPanel(const WebKit::AuthenticatorManager&, const WTF::String& rpId, const TransportSet&, WebCore::ClientDataType);
    5665
    5766    WeakPtr<WebKit::AuthenticatorManager> m_manager;
    5867    WTF::String m_rpId;
    5968    UniqueRef<WebAuthenticationPanelClient> m_client;
     69    Vector<WebCore::AuthenticatorTransport> m_transports;
     70    WebCore::ClientDataType m_clientDataType;
    6071};
    6172
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.h

    r250658 r251498  
    5050} WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
    5151
     52typedef NS_ENUM(NSInteger, _WKWebAuthenticationTransport) {
     53    _WKWebAuthenticationTransportUSB,
     54    _WKWebAuthenticationTransportNFC,
     55} WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     56
     57typedef NS_ENUM(NSInteger, _WKWebAuthenticationType) {
     58    _WKWebAuthenticationTypeCreate,
     59    _WKWebAuthenticationTypeGet,
     60} WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     61
    5262@protocol _WKWebAuthenticationPanelDelegate <NSObject>
    5363
     
    6474@property (nullable, nonatomic, weak) id <_WKWebAuthenticationPanelDelegate> delegate;
    6575@property (nonatomic, readonly, copy) NSString *relyingPartyID;
     76@property (nonatomic, readonly, copy) NSArray *transports;
     77@property (nonatomic, readonly) _WKWebAuthenticationType type;
    6678
    6779- (void)cancel;
  • trunk/Source/WebKit/UIProcess/API/Cocoa/_WKWebAuthenticationPanel.mm

    r251295 r251498  
    2727#import "WebAuthenticationPanelClient.h"
    2828#import "_WKWebAuthenticationPanelInternal.h"
     29#import <WebCore/WebAuthenticationConstants.h>
    2930
    3031#import <wtf/RetainPtr.h>
     
    3435    WeakPtr<WebKit::WebAuthenticationPanelClient> _client;
    3536#endif
     37    RetainPtr<NSMutableArray> _transports;
    3638}
    3739
     
    4345
    4446    [super dealloc];
    45 }
    46 
    47 - (NSString *)relyingPartyID
    48 {
    49     return _panel->rpId();
    5047}
    5148
     
    6259    _client = makeWeakPtr(client.get());
    6360    _panel->setClient(WTFMove(client));
     61}
     62
     63
     64- (NSString *)relyingPartyID
     65{
     66    return _panel->rpId();
     67}
     68
     69static _WKWebAuthenticationTransport wkWebAuthenticationTransport(WebCore::AuthenticatorTransport transport)
     70{
     71    switch (transport) {
     72    case WebCore::AuthenticatorTransport::Usb:
     73        return _WKWebAuthenticationTransportUSB;
     74    case WebCore::AuthenticatorTransport::Nfc:
     75        return _WKWebAuthenticationTransportNFC;
     76    default:
     77        ASSERT_NOT_REACHED();
     78        return _WKWebAuthenticationTransportUSB;
     79    }
     80}
     81
     82- (NSArray *)transports
     83{
     84    if (_transports)
     85        return _transports.get();
     86
     87    auto& transports = _panel->transports();
     88    _transports = [[NSMutableArray alloc] initWithCapacity:transports.size()];
     89    for (auto& transport : transports)
     90        [_transports addObject:adoptNS([[NSNumber alloc] initWithInt:wkWebAuthenticationTransport(transport)]).get()];
     91    return _transports.get();
     92}
     93
     94static _WKWebAuthenticationType wkWebAuthenticationType(WebCore::ClientDataType type)
     95{
     96    switch (type) {
     97    case WebCore::ClientDataType::Create:
     98        return _WKWebAuthenticationTypeCreate;
     99    case WebCore::ClientDataType::Get:
     100        return _WKWebAuthenticationTypeGet;
     101    default:
     102        ASSERT_NOT_REACHED();
     103        return _WKWebAuthenticationTypeCreate;
     104    }
     105}
     106
     107- (_WKWebAuthenticationType)type
     108{
     109    return wkWebAuthenticationType(_panel->clientDataType());
    64110}
    65111
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.cpp

    r251489 r251498  
    3232#include "APIWebAuthenticationPanel.h"
    3333#include "APIWebAuthenticationPanelClient.h"
     34#include "LocalService.h"
     35#include "NfcService.h"
    3436#include "WebPageProxy.h"
    3537#include "WebPreferencesKeys.h"
    3638#include <WebCore/AuthenticatorTransport.h>
    3739#include <WebCore/PublicKeyCredentialCreationOptions.h>
     40#include <WebCore/WebAuthenticationConstants.h>
    3841#include <wtf/MonotonicTime.h>
    3942
     
    4245
    4346namespace {
    44 
    45 const size_t maxTransportNumber = 3;
    4647
    4748// Suggested by WebAuthN spec as of 7 August 2018.
     
    109110                continue;
    110111            result.add(transport);
    111             if (result.size() >= maxTransportNumber)
     112            if (result.size() >= AuthenticatorManager::maxTransportNumber)
    112113                return result;
    113114        }
    114115    }
    115116
    116     ASSERT(result.size() < maxTransportNumber);
     117    ASSERT(result.size() < AuthenticatorManager::maxTransportNumber);
    117118    return result;
    118119}
     
    142143}
    143144
     145static ClientDataType getClientDataType(const Variant<PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions>& options)
     146{
     147    if (WTF::holds_alternative<PublicKeyCredentialCreationOptions>(options))
     148        return ClientDataType::Create;
     149    return ClientDataType::Get;
     150}
     151
    144152} // namespace
     153
     154const size_t AuthenticatorManager::maxTransportNumber = 3;
    145155
    146156AuthenticatorManager::AuthenticatorManager()
     
    162172
    163173    // 2. Ask clients to show appropriate UI if any and then start the request.
     174    initTimeOutTimer();
    164175    runPanel();
    165176}
     
    255266}
    256267
    257 void AuthenticatorManager::respondReceivedInternal(Respond&&)
    258 {
     268void AuthenticatorManager::filterTransports(TransportSet& transports) const
     269{
     270    if (!NfcService::isAvailable())
     271        transports.remove(AuthenticatorTransport::Nfc);
     272    if (!LocalService::isAvailable())
     273        transports.remove(AuthenticatorTransport::Internal);
    259274}
    260275
    261276void AuthenticatorManager::startDiscovery(const TransportSet& transports)
    262277{
     278    ASSERT(RunLoop::isMain());
    263279    ASSERT(m_services.isEmpty() && transports.size() <= maxTransportNumber);
    264280    for (auto& transport : transports) {
    265         if (transport == AuthenticatorTransport::Internal && !isFeatureEnabled(m_pendingRequestData.page.get(), WebPreferencesKey::webAuthenticationLocalAuthenticatorEnabledKey()))
    266             continue;
    267281        // Only allow USB authenticators when clients don't have dedicated UI.
    268282        if (transport != AuthenticatorTransport::Usb && (m_pendingRequestData.panelResult == WebAuthenticationPanelResult::Unavailable))
     
    274288}
    275289
    276 void AuthenticatorManager::initTimeOutTimer(const Optional<unsigned>& timeOutInMs)
    277 {
     290void AuthenticatorManager::initTimeOutTimer()
     291{
     292    Optional<unsigned> timeOutInMs;
     293    WTF::switchOn(m_pendingRequestData.options, [&](const PublicKeyCredentialCreationOptions& options) {
     294        timeOutInMs = options.timeout;
     295    }, [&](const PublicKeyCredentialRequestOptions& options) {
     296        timeOutInMs = options.timeout;
     297    });
     298
    278299    unsigned timeOutInMsValue = std::min(maxTimeOutValue, timeOutInMs.valueOr(maxTimeOutValue));
    279300    m_requestTimeOutTimer.startOneShot(Seconds::fromMilliseconds(timeOutInMsValue));
     
    297318        return;
    298319
    299     m_pendingRequestData.panel = API::WebAuthenticationPanel::create(*this, getRpId(m_pendingRequestData.options));
     320    // Get available transports and start discovering authenticators on them.
     321    auto& options = m_pendingRequestData.options;
     322    auto transports = getTransports();
     323    m_pendingRequestData.panel = API::WebAuthenticationPanel::create(*this, getRpId(options), transports, getClientDataType(options));
    300324    auto& panel = *m_pendingRequestData.panel;
    301     page->uiClient().runWebAuthenticationPanel(*page, panel, *frame, m_pendingRequestData.origin, [weakPanel = makeWeakPtr(panel), weakThis = makeWeakPtr(*this), this] (WebAuthenticationPanelResult result) {
     325    page->uiClient().runWebAuthenticationPanel(*page, panel, *frame, m_pendingRequestData.origin, [transports = WTFMove(transports), weakPanel = makeWeakPtr(panel), weakThis = makeWeakPtr(*this), this] (WebAuthenticationPanelResult result) {
    302326        // The panel address is used to determine if the current pending request is still the same.
    303327        if (!weakThis || !weakPanel
     
    306330            return;
    307331        m_pendingRequestData.panelResult = result;
    308         startRequest();
    309     });
    310 }
    311 
    312 void AuthenticatorManager::startRequest()
    313 {
    314     ASSERT(RunLoop::isMain());
    315     // Get available transports and start discovering authenticators on them.
    316     WTF::switchOn(m_pendingRequestData.options, [&](const PublicKeyCredentialCreationOptions& options) {
    317         initTimeOutTimer(options.timeout);
    318 
    319         auto transports = collectTransports(options.authenticatorSelection);
    320         processGoogleLegacyAppIdSupportExtension(options.extensions, transports);
    321         startDiscovery(collectTransports(options.authenticatorSelection));
    322     }, [&](const  PublicKeyCredentialRequestOptions& options) {
    323         initTimeOutTimer(options.timeout);
    324         startDiscovery(collectTransports(options.allowCredentials));
     332        startDiscovery(transports);
    325333    });
    326334}
     
    331339        WTF::switchOn(respond, [&](const WebCore::PublicKeyCredentialData&) {
    332340            panel->client().dismissPanel(WebAuthenticationResult::Succeeded);
    333         }, [&](const  WebCore::ExceptionData&) {
     341        }, [&](const WebCore::ExceptionData&) {
    334342            panel->client().dismissPanel(WebAuthenticationResult::Failed);
    335343        });
     
    346354}
    347355
     356auto AuthenticatorManager::getTransports() const -> TransportSet
     357{
     358    TransportSet transports;
     359    WTF::switchOn(m_pendingRequestData.options, [&](const PublicKeyCredentialCreationOptions& options) {
     360        transports = collectTransports(options.authenticatorSelection);
     361        processGoogleLegacyAppIdSupportExtension(options.extensions, transports);
     362    }, [&](const PublicKeyCredentialRequestOptions& options) {
     363        transports = collectTransports(options.allowCredentials);
     364    });
     365    if (!isFeatureEnabled(m_pendingRequestData.page.get(), WebPreferencesKey::webAuthenticationLocalAuthenticatorEnabledKey()))
     366        transports.remove(AuthenticatorTransport::Internal);
     367    filterTransports(transports);
     368    return transports;
     369}
     370
    348371} // namespace WebKit
    349372
  • trunk/Source/WebKit/UIProcess/WebAuthentication/AuthenticatorManager.h

    r251317 r251498  
    5656    using WeakValueType = AuthenticatorTransportService::Observer::WeakValueType;
    5757
     58    const static size_t maxTransportNumber;
     59
    5860    AuthenticatorManager();
    5961    virtual ~AuthenticatorManager() = default;
     
    8385    virtual UniqueRef<AuthenticatorTransportService> createService(WebCore::AuthenticatorTransport, AuthenticatorTransportService::Observer&) const;
    8486    // Overriden to return every exception for tests to confirm.
    85     virtual void respondReceivedInternal(Respond&&);
     87    virtual void respondReceivedInternal(Respond&&) { }
     88    virtual void filterTransports(TransportSet&) const;
    8689
    8790    void startDiscovery(const TransportSet&);
    88     void initTimeOutTimer(const Optional<unsigned>& timeOutInMs);
     91    void initTimeOutTimer();
    8992    void timeOutTimerFired();
    9093    void runPanel();
    91     void startRequest();
    9294    void resetState();
     95    TransportSet getTransports() const;
    9396
    9497    // Request: We only allow one request per time. A new request will cancel any pending ones.
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.h

    r249059 r251498  
    4141    ~NfcService();
    4242
     43    static bool isAvailable();
     44
    4345    // For NfcConnection.
    4446    void didConnectTag();
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Cocoa/NfcService.mm

    r250729 r251498  
    4949}
    5050
     51bool NfcService::isAvailable()
     52{
     53#if HAVE(NEAR_FIELD)
     54    return [[getNFHardwareManagerClass() sharedHardwareManager] areFeaturesSupported:NFFeatureReaderMode outError:nil];
     55#else
     56    return false;
     57#endif
     58}
     59
    5160void NfcService::didConnectTag()
    5261{
     
    7180{
    7281#if HAVE(NEAR_FIELD)
    73     if (![[getNFHardwareManagerClass() sharedHardwareManager] areFeaturesSupported:NFFeatureReaderMode outError:nil])
     82    if (!isAvailable())
    7483        return;
    7584
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.cpp

    r250940 r251498  
    5151}
    5252
     53void MockAuthenticatorManager::filterTransports(TransportSet& transports) const
     54{
     55    if (!m_testConfiguration.nfc)
     56        transports.remove(AuthenticatorTransport::Nfc);
     57    if (!m_testConfiguration.local)
     58        transports.remove(AuthenticatorTransport::Internal);
     59}
     60
    5361} // namespace WebKit
    5462
  • trunk/Source/WebKit/UIProcess/WebAuthentication/Mock/MockAuthenticatorManager.h

    r250940 r251498  
    4343    UniqueRef<AuthenticatorTransportService> createService(WebCore::AuthenticatorTransport, AuthenticatorTransportService::Observer&) const final;
    4444    void respondReceivedInternal(Respond&&) final;
     45    void filterTransports(TransportSet&) const;
    4546
    4647    WebCore::MockWebAuthenticationConfiguration m_testConfiguration;
  • trunk/Tools/ChangeLog

    r251497 r251498  
     12019-10-22  Jiewen Tan  <jiewen_tan@apple.com>
     2
     3        [WebAuthn] Add more information to _WKWebAuthenticationPanel
     4        https://bugs.webkit.org/show_bug.cgi?id=202561
     5        <rdar://problem/55973910>
     6
     7        Reviewed by Youenn Fablet.
     8
     9        Adds new API tests.
     10
     11        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     12        * TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm:
     13        (-[TestWebAuthenticationPanelUIDelegate _webView:runWebAuthenticationPanel:initiatedByFrame:completionHandler:]):
     14        (-[TestWebAuthenticationPanelUIDelegate panel]):
     15        (TestWebKitAPI::TEST):
     16        * TestWebKitAPI/Tests/WebKitCocoa/web-authentication-make-credential-hid.html: Added.
     17
    1182019-10-23  Aakash Jain  <aakash_jain@apple.com>
    219
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r251384 r251498  
    351351                5797FE311EB15A6800B2F4A0 /* NavigationClientDefaultCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5797FE2F1EB15A5F00B2F4A0 /* NavigationClientDefaultCrypto.cpp */; };
    352352                5797FE331EB15AB100B2F4A0 /* navigation-client-default-crypto.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */; };
     353                5798337E236019A4008E5547 /* web-authentication-make-credential-hid.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5798337D2360196D008E5547 /* web-authentication-make-credential-hid.html */; };
    353354                57A79857224AB34E00A7F6F1 /* WebCryptoMasterKey.mm in Sources */ = {isa = PBXBuildFile; fileRef = 57A79856224AB34E00A7F6F1 /* WebCryptoMasterKey.mm */; };
    354355                57C3FA661F7C248F009D4B80 /* WeakPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1CB9BC371A67482300FE5678 /* WeakPtr.cpp */; };
     
    11271128                        dstSubfolderSpec = 7;
    11281129                        files = (
     1130                                5798337E236019A4008E5547 /* web-authentication-make-credential-hid.html in Copy Resources */,
    11291131                                55A817FF2181021A0004A39A /* 100x100-red.tga in Copy Resources */,
    11301132                                1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */,
     
    18881890                5797FE2F1EB15A5F00B2F4A0 /* NavigationClientDefaultCrypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NavigationClientDefaultCrypto.cpp; sourceTree = "<group>"; };
    18891891                5797FE321EB15A8900B2F4A0 /* navigation-client-default-crypto.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "navigation-client-default-crypto.html"; sourceTree = "<group>"; };
     1892                5798337D2360196D008E5547 /* web-authentication-make-credential-hid.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "web-authentication-make-credential-hid.html"; sourceTree = "<group>"; };
    18901893                5798E2AF1CAF5C2800C5CBA0 /* ProvisionalURLNotChange.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ProvisionalURLNotChange.mm; sourceTree = "<group>"; };
    18911894                57A79856224AB34E00A7F6F1 /* WebCryptoMasterKey.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = WebCryptoMasterKey.mm; sourceTree = "<group>"; };
     
    34123415                                577454D12359BAD5008E1ED7 /* web-authentication-get-assertion-u2f-no-credentials.html */,
    34133416                                57C6244F2346C1EC00383FE7 /* web-authentication-get-assertion.html */,
     3417                                5798337D2360196D008E5547 /* web-authentication-make-credential-hid.html */,
    34143418                                51714EB21CF8C761004723C4 /* WebProcessKillIDBCleanup-1.html */,
    34153419                                51714EB31CF8C761004723C4 /* WebProcessKillIDBCleanup-2.html */,
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKWebAuthenticationPanel.mm

    r251489 r251498  
    4444static bool webAuthenticationPanelSucceded = false;
    4545static bool webAuthenticationPanelUpdateNoCredentialsFound = false;
    46 static RetainPtr<_WKWebAuthenticationPanel> gPanel;
    4746
    4847@interface TestWebAuthenticationPanelDelegate : NSObject <_WKWebAuthenticationPanelDelegate>
     
    9190    BlockPtr<void(_WKWebAuthenticationPanelResult)> _callback;
    9291    RetainPtr<WKFrameInfo> _frameInfo;
     92    RetainPtr<_WKWebAuthenticationPanel> _panel;
    9393}
    9494
     
    115115    }
    116116    ASSERT_NE(panel, nil);
    117     gPanel = panel;
    118     [gPanel setDelegate:_delegate.get()];
    119 
    120     EXPECT_TRUE([[gPanel relyingPartyID] isEqual:@""] || [[gPanel relyingPartyID] isEqual:@"localhost"]);
     117    _panel = panel;
     118    [_panel setDelegate:_delegate.get()];
    121119
    122120    if (_isRacy) {
     
    133131{
    134132    return _frameInfo.get();
     133}
     134
     135- (_WKWebAuthenticationPanel *)panel
     136{
     137    return _panel.get();
    135138}
    136139
     
    180183    webAuthenticationPanelFailed = false;
    181184    webAuthenticationPanelSucceded = false;
    182     gPanel = nullptr;
     185}
     186
     187static void checkPanel(_WKWebAuthenticationPanel *panel, NSString *relyingPartyID, NSArray *transports, _WKWebAuthenticationType type)
     188{
     189    EXPECT_WK_STREQ(panel.relyingPartyID, relyingPartyID);
     190
     191    // Brute force given the maximum size of the array is 4.
     192    auto *theTransports = panel.transports;
     193    EXPECT_EQ(theTransports.count, transports.count);
     194    size_t count = 0;
     195    for (NSNumber *transport : transports) {
     196        for (NSNumber *theTransport : theTransports) {
     197            if (transport == theTransport) {
     198                count++;
     199                break;
     200            }
     201        }
     202    }
     203    EXPECT_EQ(count, transports.count);
     204
     205    EXPECT_EQ(panel.type, type);
    183206}
    184207
     
    238261}
    239262
    240 TEST(WebAuthenticationPanel, PanelHidSuccess)
     263TEST(WebAuthenticationPanel, PanelHidSuccess1)
    241264{
    242265    reset();
     
    256279    // A bit of extra checks.
    257280    checkFrameInfo([delegate frame], true, [testURL absoluteString], @"file", @"", 0, webView.get());
     281    checkPanel([delegate panel], @"", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportUSB]).get()], _WKWebAuthenticationTypeGet);
     282}
     283
     284TEST(WebAuthenticationPanel, PanelHidSuccess2)
     285{
     286    reset();
     287    RetainPtr<NSURL> testURL = [[NSBundle mainBundle] URLForResource:@"web-authentication-make-credential-hid" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     288
     289    auto *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
     290    [[configuration preferences] _setEnabled:YES forExperimentalFeature:webAuthenticationExperimentalFeature()];
     291
     292    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSZeroRect configuration:configuration]);
     293    auto delegate = adoptNS([[TestWebAuthenticationPanelUIDelegate alloc] init]);
     294    [webView setUIDelegate:delegate.get()];
     295
     296    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
     297    Util::run(&webAuthenticationPanelRan);
     298    Util::run(&webAuthenticationPanelSucceded);
     299
     300    // A bit of extra checks.
     301    checkPanel([delegate panel], @"", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportUSB]).get()], _WKWebAuthenticationTypeCreate);
    258302}
    259303
     
    280324    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
    281325    [webView waitForMessage:@"Succeeded!"];
     326
     327    // A bit of extra checks.
     328    checkPanel([delegate panel], @"", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportNFC]).get()], _WKWebAuthenticationTypeGet);
    282329}
    283330
     
    442489    // A bit of extra checks.
    443490    checkFrameInfo([delegate frame], false, (id)makeString(url, "/iFrame.html"), @"http", @"localhost", port, webView.get());
     491    checkPanel([delegate panel], @"localhost", @[adoptNS([[NSNumber alloc] initWithInt:_WKWebAuthenticationTransportUSB]).get()], _WKWebAuthenticationTypeGet);
    444492}
    445493
     
    495543    [webView loadRequest:[NSURLRequest requestWithURL:testURL.get()]];
    496544    Util::run(&webAuthenticationPanelRan);
    497     [gPanel cancel];
     545    [[delegate panel] cancel];
    498546    [webView waitForMessage:@"Operation timed out."];
    499547    EXPECT_FALSE(webAuthenticationPanelFailed);
Note: See TracChangeset for help on using the changeset viewer.