Changeset 244659 in webkit


Ignore:
Timestamp:
Apr 25, 2019 12:04:46 PM (5 years ago)
Author:
pvollan@apple.com
Message:

-[WKWebsiteDataStore fetchDataRecordsOfTypes:completionHandler:] never returns _WKWebsiteDataTypeCredentials
https://bugs.webkit.org/show_bug.cgi?id=196991
<rdar://problem/45507423>

Reviewed by Alex Christensen.

Source/WebCore:

Add method to get all origins with persistent credentials from credential storage.

API tests: WKWebsiteDataStore.FetchNonPersistentCredentials

WKWebsiteDataStore.FetchPersistentCredentials

  • platform/network/CredentialStorage.h:
  • platform/network/mac/CredentialStorageMac.mm:

(WebCore::CredentialStorage::originsWithPersistentCredentials):

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm:

(-[NavigationTestDelegate init]):
(-[NavigationTestDelegate waitForDidFinishNavigation]):
(-[NavigationTestDelegate webView:didFinishNavigation:]):
(-[NavigationTestDelegate webView:didReceiveAuthenticationChallenge:completionHandler:]):
(TestWebKitAPI::TEST):
(TEST): Deleted.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r244656 r244659  
     12019-04-25  Per Arne Vollan  <pvollan@apple.com>
     2
     3        -[WKWebsiteDataStore fetchDataRecordsOfTypes:completionHandler:] never returns _WKWebsiteDataTypeCredentials
     4        https://bugs.webkit.org/show_bug.cgi?id=196991
     5        <rdar://problem/45507423>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Add method to get all origins with persistent credentials from credential storage.
     10
     11        API tests: WKWebsiteDataStore.FetchNonPersistentCredentials
     12                   WKWebsiteDataStore.FetchPersistentCredentials
     13
     14        * platform/network/CredentialStorage.h:
     15        * platform/network/mac/CredentialStorageMac.mm:
     16        (WebCore::CredentialStorage::originsWithPersistentCredentials):
     17
    1182019-04-25  Alex Christensen  <achristensen@webkit.org>
    219
  • trunk/Source/WebCore/platform/network/CredentialStorage.h

    r240292 r244659  
    2828#include "Credential.h"
    2929#include "ProtectionSpaceHash.h"
     30#include "SecurityOriginData.h"
    3031#include <wtf/HashMap.h>
    3132#include <wtf/HashSet.h>
     
    4647    // OS persistent storage.
    4748    WEBCORE_EXPORT static Credential getFromPersistentStorage(const ProtectionSpace&);
     49    WEBCORE_EXPORT static Vector<SecurityOriginData> originsWithPersistentCredentials();
    4850
    4951    WEBCORE_EXPORT void clearCredentials();
  • trunk/Source/WebCore/platform/network/mac/CredentialStorageMac.mm

    r224846 r244659  
    3939}
    4040
     41Vector<WebCore::SecurityOriginData> CredentialStorage::originsWithPersistentCredentials()
     42{
     43    Vector<WebCore::SecurityOriginData> origins;
     44    auto allCredentials = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials];
     45    for (NSURLProtectionSpace* key in allCredentials.keyEnumerator)
     46        origins.append(WebCore::SecurityOriginData { String(key.protocol), String(key.host), key.port });
     47    return origins;
     48}
     49
    4150} // namespace WebCore
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp

    r244614 r244659  
    24882488}
    24892489
     2490void NetworkProcess::originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&& completionHandler)
     2491{
     2492    completionHandler(Vector<WebCore::SecurityOriginData>());
     2493}
     2494   
    24902495void NetworkProcess::initializeProcess(const AuxiliaryProcessInitializationParameters&)
    24912496{
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.h

    r244614 r244659  
    431431    void removeCredential(WebCore::Credential&&, WebCore::ProtectionSpace&&, CompletionHandler<void()>&&);
    432432
     433    void originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&&);
     434   
    433435    void registerURLSchemeAsSecure(const String&) const;
    434436    void registerURLSchemeAsBypassingContentSecurityPolicy(const String&) const;
  • trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in

    r244614 r244659  
    174174    MarkAdClickAttributionsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async
    175175    RemoveCredential(WebCore::Credential credential, WebCore::ProtectionSpace protectionSpace) -> () Async
     176    OriginsWithPersistentCredentials() -> (Vector<WebCore::SecurityOriginData> persistentCredentials) Async
    176177}
  • trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm

    r244521 r244659  
    218218}
    219219
     220void NetworkProcess::originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&& completionHandler)
     221{
     222    completionHandler(WebCore::CredentialStorage::originsWithPersistentCredentials());
     223}
     224
    220225#if PLATFORM(MAC)
    221226void NetworkProcess::setSharedHTTPCookieStorage(const Vector<uint8_t>& identifier)
  • trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp

    r244365 r244659  
    4545#include "WebsiteDataStoreParameters.h"
    4646#include <WebCore/ApplicationCacheStorage.h>
     47#include <WebCore/CredentialStorage.h>
    4748#include <WebCore/DatabaseTracker.h>
    4849#include <WebCore/HTMLMediaElement.h>
     
    239240    }
    240241
    241     if (dataTypes.contains(WebsiteDataType::Credentials) && !isNonPersistentStore)
    242         processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
     242    if (dataTypes.contains(WebsiteDataType::Credentials) && isNonPersistentStore)
     243        processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched);
    243244
    244245    if (dataTypes.contains(WebsiteDataType::DiskCache) && !isNonPersistentStore)
     
    357358
    358359            for (auto& origin : websiteData.originsWithCredentials) {
    359                 auto& record = m_websiteDataRecords.add(origin, WebsiteDataRecord { }).iterator->value;
    360                
     360                auto displayName = WebsiteDataRecord::displayNameForOrigin(WebCore::SecurityOriginData::fromURL(URL(URL(), origin)));
     361                ASSERT(!displayName.isEmpty());
     362
     363                auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
     364                if (!record.displayName)
     365                    record.displayName = WTFMove(displayName);
     366
    361367                record.addOriginWithCredential(origin);
    362368            }
     
    570576        });
    571577    }
     578
     579#if PLATFORM(COCOA)
     580    if (dataTypes.contains(WebsiteDataType::Credentials) && isPersistent()) {
     581        for (auto& processPool : processPools()) {
     582            if (!processPool->networkProcess())
     583                continue;
     584           
     585            callbackAggregator->addPendingCallback();
     586            WTF::CompletionHandler<void(Vector<WebCore::SecurityOriginData>&&)> completionHandler = [callbackAggregator](Vector<WebCore::SecurityOriginData>&& origins) mutable {
     587                WebsiteData websiteData;
     588                for (auto& origin : origins)
     589                    websiteData.entries.append(WebsiteData::Entry { origin, WebsiteDataType::Credentials, 0 });
     590                callbackAggregator->removePendingCallback(WTFMove(websiteData));
     591            };
     592            processPool->networkProcess()->sendWithAsyncReply(Messages::NetworkProcess::OriginsWithPersistentCredentials(), WTFMove(completionHandler));
     593        }
     594    }
     595#endif
    572596
    573597#if ENABLE(NETSCAPE_PLUGIN_API)
  • trunk/Tools/ChangeLog

    r244654 r244659  
     12019-04-25  Per Arne Vollan  <pvollan@apple.com>
     2
     3        -[WKWebsiteDataStore fetchDataRecordsOfTypes:completionHandler:] never returns _WKWebsiteDataTypeCredentials
     4        https://bugs.webkit.org/show_bug.cgi?id=196991
     5        <rdar://problem/45507423>
     6
     7        Reviewed by Alex Christensen.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm:
     10        (-[NavigationTestDelegate init]):
     11        (-[NavigationTestDelegate waitForDidFinishNavigation]):
     12        (-[NavigationTestDelegate webView:didFinishNavigation:]):
     13        (-[NavigationTestDelegate webView:didReceiveAuthenticationChallenge:completionHandler:]):
     14        (TestWebKitAPI::TEST):
     15        (TEST): Deleted.
     16
    1172019-04-25  Alex Christensen  <achristensen@webkit.org>
    218
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm

    r244364 r244659  
    11/*
    2  * Copyright (C) 2018 Apple Inc. All rights reserved.
     2 * Copyright (C) 2019 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727
    2828#import "PlatformUtilities.h"
     29#import "TCPServer.h"
    2930#import "Test.h"
    3031#import "TestWKWebView.h"
     32#import <WebKit/WKProcessPoolPrivate.h>
     33#import <WebKit/WKWebsiteDataRecordPrivate.h>
    3134#import <WebKit/WKWebsiteDataStorePrivate.h>
    3235#import <WebKit/WebKit.h>
     
    3437
    3538static bool readyToContinue;
     39
     40static RetainPtr<NSURLCredential> persistentCredential;
     41static bool usePersistentCredentialStorage = false;
     42
     43@interface NavigationTestDelegate : NSObject <WKNavigationDelegate>
     44@end
     45
     46@implementation NavigationTestDelegate {
     47    bool _hasFinishedNavigation;
     48}
     49
     50- (instancetype)init
     51{
     52    if (!(self = [super init]))
     53        return nil;
     54   
     55    _hasFinishedNavigation = false;
     56   
     57    return self;
     58}
     59
     60- (void)waitForDidFinishNavigation
     61{
     62    TestWebKitAPI::Util::run(&_hasFinishedNavigation);
     63}
     64
     65- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
     66{
     67    _hasFinishedNavigation = true;
     68}
     69
     70- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
     71{
     72    static bool firstChallenge = true;
     73    if (firstChallenge) {
     74        firstChallenge = false;
     75        persistentCredential = adoptNS([[NSURLCredential alloc] initWithUser:@"username" password:@"password" persistence:(usePersistentCredentialStorage ? NSURLCredentialPersistencePermanent: NSURLCredentialPersistenceForSession)]);
     76        return completionHandler(NSURLSessionAuthChallengeUseCredential, persistentCredential.get());
     77    }
     78    return completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
     79}
     80@end
     81
     82namespace TestWebKitAPI {
    3683
    3784TEST(WKWebsiteDataStore, RemoveAndFetchData)
     
    63110    TestWebKitAPI::Util::run(&done);
    64111}
     112
     113static void respondWithChallengeThenOK(int socket)
     114{
     115    char readBuffer[1000];
     116    auto bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
     117    EXPECT_GT(bytesRead, 0);
     118    EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
     119   
     120    const char* challengeHeader =
     121    "HTTP/1.1 401 Unauthorized\r\n"
     122    "Date: Sat, 23 Mar 2019 06:29:01 GMT\r\n"
     123    "Content-Length: 0\r\n"
     124    "WWW-Authenticate: Basic realm=\"testrealm\"\r\n\r\n";
     125    auto bytesWritten = ::write(socket, challengeHeader, strlen(challengeHeader));
     126    EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(challengeHeader));
     127   
     128    bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
     129    EXPECT_GT(bytesRead, 0);
     130    EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
     131   
     132    const char* responseHeader =
     133    "HTTP/1.1 200 OK\r\n"
     134    "Content-Length: 13\r\n\r\n"
     135    "Hello, World!";
     136    bytesWritten = ::write(socket, responseHeader, strlen(responseHeader));
     137    EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(responseHeader));
     138}
     139   
     140TEST(WKWebsiteDataStore, FetchNonPersistentCredentials)
     141{
     142    TCPServer server(respondWithChallengeThenOK);
     143   
     144    auto configuration = adoptNS([WKWebViewConfiguration new]);
     145    auto websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
     146    [configuration setWebsiteDataStore:websiteDataStore];
     147    auto navigationDelegate = adoptNS([[NavigationTestDelegate alloc] init]);
     148    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     149    [webView setNavigationDelegate:navigationDelegate.get()];
     150    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];
     151    [navigationDelegate waitForDidFinishNavigation];
     152
     153    __block bool done = false;
     154    [websiteDataStore fetchDataRecordsOfTypes:[NSSet setWithObject:_WKWebsiteDataTypeCredentials] completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
     155        int credentialCount = dataRecords.count;
     156        ASSERT_EQ(credentialCount, 1);
     157        for (WKWebsiteDataRecord *record in dataRecords)
     158            ASSERT_TRUE([[record displayName] isEqualToString:@"127.0.0.1"]);
     159        done = true;
     160    }];
     161    TestWebKitAPI::Util::run(&done);
     162}
     163
     164TEST(WKWebsiteDataStore, FetchPersistentCredentials)
     165{
     166    TCPServer server(respondWithChallengeThenOK);
     167   
     168    usePersistentCredentialStorage = true;
     169    auto websiteDataStore = [WKWebsiteDataStore defaultDataStore];
     170    auto navigationDelegate = adoptNS([[NavigationTestDelegate alloc] init]);
     171    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
     172    [webView setNavigationDelegate:navigationDelegate.get()];
     173    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];
     174    [navigationDelegate waitForDidFinishNavigation];
     175
     176    __block bool done = false;
     177    [websiteDataStore fetchDataRecordsOfTypes:[NSSet setWithObject:_WKWebsiteDataTypeCredentials] completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
     178        int credentialCount = dataRecords.count;
     179        ASSERT_GT(credentialCount, 0);
     180        bool foundExpectedRecord = false;
     181        for (WKWebsiteDataRecord *record in dataRecords) {
     182            auto name = [record displayName];
     183            if ([name isEqualToString:@"127.0.0.1"]) {
     184                foundExpectedRecord = true;
     185                break;
     186            }
     187        }
     188        EXPECT_TRUE(foundExpectedRecord);
     189        done = true;
     190    }];
     191    TestWebKitAPI::Util::run(&done);
     192   
     193    __block bool removedCredential = false;
     194    [[[webView configuration] processPool] _removeCredential:persistentCredential.get() forProtectionSpace:[[[NSURLProtectionSpace alloc] initWithHost:@"127.0.0.1" port:server.port() protocol:NSURLProtectionSpaceHTTP realm:@"testrealm" authenticationMethod:NSURLAuthenticationMethodHTTPBasic] autorelease] completionHandler:^{
     195        removedCredential = true;
     196    }];
     197    TestWebKitAPI::Util::run(&removedCredential);
     198}
     199
     200}
Note: See TracChangeset for help on using the changeset viewer.