Diff
Modified: trunk/Source/WebCore/ChangeLog (244658 => 244659)
--- trunk/Source/WebCore/ChangeLog 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebCore/ChangeLog 2019-04-25 19:04:46 UTC (rev 244659)
@@ -1,3 +1,20 @@
+2019-04-25 Per Arne Vollan <pvol...@apple.com>
+
+ -[WKWebsiteDataStore fetchDataRecordsOfTypes:completionHandler:] never returns _WKWebsiteDataTypeCredentials
+ https://bugs.webkit.org/show_bug.cgi?id=196991
+ <rdar://problem/45507423>
+
+ Reviewed by Alex Christensen.
+
+ 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):
+
2019-04-25 Alex Christensen <achristen...@webkit.org>
Fix MSVC build after r244653
Modified: trunk/Source/WebCore/platform/network/CredentialStorage.h (244658 => 244659)
--- trunk/Source/WebCore/platform/network/CredentialStorage.h 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebCore/platform/network/CredentialStorage.h 2019-04-25 19:04:46 UTC (rev 244659)
@@ -27,6 +27,7 @@
#include "Credential.h"
#include "ProtectionSpaceHash.h"
+#include "SecurityOriginData.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/text/StringHash.h>
@@ -45,6 +46,7 @@
// OS persistent storage.
WEBCORE_EXPORT static Credential getFromPersistentStorage(const ProtectionSpace&);
+ WEBCORE_EXPORT static Vector<SecurityOriginData> originsWithPersistentCredentials();
WEBCORE_EXPORT void clearCredentials();
Modified: trunk/Source/WebCore/platform/network/mac/CredentialStorageMac.mm (244658 => 244659)
--- trunk/Source/WebCore/platform/network/mac/CredentialStorageMac.mm 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebCore/platform/network/mac/CredentialStorageMac.mm 2019-04-25 19:04:46 UTC (rev 244659)
@@ -38,4 +38,13 @@
return credential ? Credential(credential) : Credential();
}
+Vector<WebCore::SecurityOriginData> CredentialStorage::originsWithPersistentCredentials()
+{
+ Vector<WebCore::SecurityOriginData> origins;
+ auto allCredentials = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials];
+ for (NSURLProtectionSpace* key in allCredentials.keyEnumerator)
+ origins.append(WebCore::SecurityOriginData { String(key.protocol), String(key.host), key.port });
+ return origins;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp (244658 => 244659)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp 2019-04-25 19:04:46 UTC (rev 244659)
@@ -2487,6 +2487,11 @@
completionHandler();
}
+void NetworkProcess::originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&& completionHandler)
+{
+ completionHandler(Vector<WebCore::SecurityOriginData>());
+}
+
void NetworkProcess::initializeProcess(const AuxiliaryProcessInitializationParameters&)
{
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.h (244658 => 244659)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.h 2019-04-25 19:04:46 UTC (rev 244659)
@@ -430,6 +430,8 @@
void removeCredential(WebCore::Credential&&, WebCore::ProtectionSpace&&, CompletionHandler<void()>&&);
+ void originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&&);
+
void registerURLSchemeAsSecure(const String&) const;
void registerURLSchemeAsBypassingContentSecurityPolicy(const String&) const;
void registerURLSchemeAsLocal(const String&) const;
Modified: trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in (244658 => 244659)
--- trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in 2019-04-25 19:04:46 UTC (rev 244659)
@@ -173,4 +173,5 @@
SetAdClickAttributionConversionURLForTesting(PAL::SessionID sessionID, URL url) -> () Async
MarkAdClickAttributionsAsExpiredForTesting(PAL::SessionID sessionID) -> () Async
RemoveCredential(WebCore::Credential credential, WebCore::ProtectionSpace protectionSpace) -> () Async
+ OriginsWithPersistentCredentials() -> (Vector<WebCore::SecurityOriginData> persistentCredentials) Async
}
Modified: trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm (244658 => 244659)
--- trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebKit/NetworkProcess/cocoa/NetworkProcessCocoa.mm 2019-04-25 19:04:46 UTC (rev 244659)
@@ -217,6 +217,11 @@
completionHandler();
}
+void NetworkProcess::originsWithPersistentCredentials(CompletionHandler<void(Vector<WebCore::SecurityOriginData>)>&& completionHandler)
+{
+ completionHandler(WebCore::CredentialStorage::originsWithPersistentCredentials());
+}
+
#if PLATFORM(MAC)
void NetworkProcess::setSharedHTTPCookieStorage(const Vector<uint8_t>& identifier)
{
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (244658 => 244659)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-04-25 19:04:46 UTC (rev 244659)
@@ -44,6 +44,7 @@
#include "WebsiteDataStoreClient.h"
#include "WebsiteDataStoreParameters.h"
#include <WebCore/ApplicationCacheStorage.h>
+#include <WebCore/CredentialStorage.h>
#include <WebCore/DatabaseTracker.h>
#include <WebCore/HTMLMediaElement.h>
#include <WebCore/OriginLock.h>
@@ -238,8 +239,8 @@
processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
}
- if (dataTypes.contains(WebsiteDataType::Credentials) && !isNonPersistentStore)
- processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
+ if (dataTypes.contains(WebsiteDataType::Credentials) && isNonPersistentStore)
+ processAccessType = std::max(processAccessType, ProcessAccessType::OnlyIfLaunched);
if (dataTypes.contains(WebsiteDataType::DiskCache) && !isNonPersistentStore)
processAccessType = std::max(processAccessType, ProcessAccessType::Launch);
@@ -356,8 +357,13 @@
#endif
for (auto& origin : websiteData.originsWithCredentials) {
- auto& record = m_websiteDataRecords.add(origin, WebsiteDataRecord { }).iterator->value;
-
+ auto displayName = WebsiteDataRecord::displayNameForOrigin(WebCore::SecurityOriginData::fromURL(URL(URL(), origin)));
+ ASSERT(!displayName.isEmpty());
+
+ auto& record = m_websiteDataRecords.add(displayName, WebsiteDataRecord { }).iterator->value;
+ if (!record.displayName)
+ record.displayName = WTFMove(displayName);
+
record.addOriginWithCredential(origin);
}
@@ -570,6 +576,24 @@
});
}
+#if PLATFORM(COCOA)
+ if (dataTypes.contains(WebsiteDataType::Credentials) && isPersistent()) {
+ for (auto& processPool : processPools()) {
+ if (!processPool->networkProcess())
+ continue;
+
+ callbackAggregator->addPendingCallback();
+ WTF::CompletionHandler<void(Vector<WebCore::SecurityOriginData>&&)> completionHandler = [callbackAggregator](Vector<WebCore::SecurityOriginData>&& origins) mutable {
+ WebsiteData websiteData;
+ for (auto& origin : origins)
+ websiteData.entries.append(WebsiteData::Entry { origin, WebsiteDataType::Credentials, 0 });
+ callbackAggregator->removePendingCallback(WTFMove(websiteData));
+ };
+ processPool->networkProcess()->sendWithAsyncReply(Messages::NetworkProcess::OriginsWithPersistentCredentials(), WTFMove(completionHandler));
+ }
+ }
+#endif
+
#if ENABLE(NETSCAPE_PLUGIN_API)
if (dataTypes.contains(WebsiteDataType::PlugInData) && isPersistent()) {
class State {
Modified: trunk/Tools/ChangeLog (244658 => 244659)
--- trunk/Tools/ChangeLog 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Tools/ChangeLog 2019-04-25 19:04:46 UTC (rev 244659)
@@ -1,3 +1,19 @@
+2019-04-25 Per Arne Vollan <pvol...@apple.com>
+
+ -[WKWebsiteDataStore fetchDataRecordsOfTypes:completionHandler:] never returns _WKWebsiteDataTypeCredentials
+ https://bugs.webkit.org/show_bug.cgi?id=196991
+ <rdar://problem/45507423>
+
+ Reviewed by Alex Christensen.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm:
+ (-[NavigationTestDelegate init]):
+ (-[NavigationTestDelegate waitForDidFinishNavigation]):
+ (-[NavigationTestDelegate webView:didFinishNavigation:]):
+ (-[NavigationTestDelegate webView:didReceiveAuthenticationChallenge:completionHandler:]):
+ (TestWebKitAPI::TEST):
+ (TEST): Deleted.
+
2019-04-25 Alex Christensen <achristen...@webkit.org>
Revert some code accidentally committed with r244653
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm (244658 => 244659)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm 2019-04-25 18:59:51 UTC (rev 244658)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WKWebsiteDatastore.mm 2019-04-25 19:04:46 UTC (rev 244659)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,8 +26,11 @@
#import "config.h"
#import "PlatformUtilities.h"
+#import "TCPServer.h"
#import "Test.h"
#import "TestWKWebView.h"
+#import <WebKit/WKProcessPoolPrivate.h>
+#import <WebKit/WKWebsiteDataRecordPrivate.h>
#import <WebKit/WKWebsiteDataStorePrivate.h>
#import <WebKit/WebKit.h>
#import <wtf/text/WTFString.h>
@@ -34,6 +37,50 @@
static bool readyToContinue;
+static RetainPtr<NSURLCredential> persistentCredential;
+static bool usePersistentCredentialStorage = false;
+
+@interface NavigationTestDelegate : NSObject <WKNavigationDelegate>
+@end
+
+@implementation NavigationTestDelegate {
+ bool _hasFinishedNavigation;
+}
+
+- (instancetype)init
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _hasFinishedNavigation = false;
+
+ return self;
+}
+
+- (void)waitForDidFinishNavigation
+{
+ TestWebKitAPI::Util::run(&_hasFinishedNavigation);
+}
+
+- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
+{
+ _hasFinishedNavigation = true;
+}
+
+- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler
+{
+ static bool firstChallenge = true;
+ if (firstChallenge) {
+ firstChallenge = false;
+ persistentCredential = adoptNS([[NSURLCredential alloc] initWithUser:@"username" password:@"password" persistence:(usePersistentCredentialStorage ? NSURLCredentialPersistencePermanent: NSURLCredentialPersistenceForSession)]);
+ return completionHandler(NSURLSessionAuthChallengeUseCredential, persistentCredential.get());
+ }
+ return completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
+}
+@end
+
+namespace TestWebKitAPI {
+
TEST(WKWebsiteDataStore, RemoveAndFetchData)
{
readyToContinue = false;
@@ -62,3 +109,92 @@
}];
TestWebKitAPI::Util::run(&done);
}
+
+static void respondWithChallengeThenOK(int socket)
+{
+ char readBuffer[1000];
+ auto bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
+ EXPECT_GT(bytesRead, 0);
+ EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
+
+ const char* challengeHeader =
+ "HTTP/1.1 401 Unauthorized\r\n"
+ "Date: Sat, 23 Mar 2019 06:29:01 GMT\r\n"
+ "Content-Length: 0\r\n"
+ "WWW-Authenticate: Basic realm=\"testrealm\"\r\n\r\n";
+ auto bytesWritten = ::write(socket, challengeHeader, strlen(challengeHeader));
+ EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(challengeHeader));
+
+ bytesRead = ::read(socket, readBuffer, sizeof(readBuffer));
+ EXPECT_GT(bytesRead, 0);
+ EXPECT_TRUE(static_cast<size_t>(bytesRead) < sizeof(readBuffer));
+
+ const char* responseHeader =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 13\r\n\r\n"
+ "Hello, World!";
+ bytesWritten = ::write(socket, responseHeader, strlen(responseHeader));
+ EXPECT_EQ(static_cast<size_t>(bytesWritten), strlen(responseHeader));
+}
+
+TEST(WKWebsiteDataStore, FetchNonPersistentCredentials)
+{
+ TCPServer server(respondWithChallengeThenOK);
+
+ auto configuration = adoptNS([WKWebViewConfiguration new]);
+ auto websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
+ [configuration setWebsiteDataStore:websiteDataStore];
+ auto navigationDelegate = adoptNS([[NavigationTestDelegate alloc] init]);
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];
+ [navigationDelegate waitForDidFinishNavigation];
+
+ __block bool done = false;
+ [websiteDataStore fetchDataRecordsOfTypes:[NSSet setWithObject:_WKWebsiteDataTypeCredentials] completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+ int credentialCount = dataRecords.count;
+ ASSERT_EQ(credentialCount, 1);
+ for (WKWebsiteDataRecord *record in dataRecords)
+ ASSERT_TRUE([[record displayName] isEqualToString:@"127.0.0.1"]);
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+}
+
+TEST(WKWebsiteDataStore, FetchPersistentCredentials)
+{
+ TCPServer server(respondWithChallengeThenOK);
+
+ usePersistentCredentialStorage = true;
+ auto websiteDataStore = [WKWebsiteDataStore defaultDataStore];
+ auto navigationDelegate = adoptNS([[NavigationTestDelegate alloc] init]);
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/", server.port()]]]];
+ [navigationDelegate waitForDidFinishNavigation];
+
+ __block bool done = false;
+ [websiteDataStore fetchDataRecordsOfTypes:[NSSet setWithObject:_WKWebsiteDataTypeCredentials] completionHandler:^(NSArray<WKWebsiteDataRecord *> *dataRecords) {
+ int credentialCount = dataRecords.count;
+ ASSERT_GT(credentialCount, 0);
+ bool foundExpectedRecord = false;
+ for (WKWebsiteDataRecord *record in dataRecords) {
+ auto name = [record displayName];
+ if ([name isEqualToString:@"127.0.0.1"]) {
+ foundExpectedRecord = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(foundExpectedRecord);
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ __block bool removedCredential = false;
+ [[[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:^{
+ removedCredential = true;
+ }];
+ TestWebKitAPI::Util::run(&removedCredential);
+}
+
+}