API tests using permanent credentials should clear credentials left by previous tests
[WebKit-https.git] / Source / WebCore / platform / network / CredentialStorage.cpp
index 7f90efa..26a3b9e 100644 (file)
 #include "CredentialStorage.h"
 
 #include "NetworkStorageSession.h"
-#include "URL.h"
+#include <wtf/URL.h>
 
-#if PLATFORM(IOS)
+#if PLATFORM(IOS_FAMILY)
 #include "WebCoreThread.h"
 #endif
 
 namespace WebCore {
 
-CredentialStorage& CredentialStorage::defaultCredentialStorage()
-{
-    return NetworkStorageSession::defaultStorageSession().credentialStorage();
-}
-
 static String originStringFromURL(const URL& url)
 {
-    if (url.port())
-        return url.protocol() + "://" + url.host() + ':' + String::number(url.port()) + '/';
-
-    return url.protocol() + "://" + url.host() + '/';
+    return makeString(url.protocol(), "://", url.hostAndPort(), '/');
 }
 
 static String protectionSpaceMapKeyFromURL(const URL& url)
@@ -66,17 +58,12 @@ static String protectionSpaceMapKeyFromURL(const URL& url)
     return directoryURL;
 }
 
-void CredentialStorage::set(const Credential& credential, const ProtectionSpace& protectionSpace, const URL& url)
+void CredentialStorage::set(const String& partitionName, const Credential& credential, const ProtectionSpace& protectionSpace, const URL& url)
 {
     ASSERT(protectionSpace.isProxy() || protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeClientCertificateRequested || url.protocolIsInHTTPFamily());
     ASSERT(protectionSpace.isProxy() || protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeClientCertificateRequested || url.isValid());
 
-    m_protectionSpaceToCredentialMap.set(protectionSpace, credential);
-
-#if PLATFORM(IOS)
-    if (protectionSpace.authenticationScheme() != ProtectionSpaceAuthenticationSchemeClientCertificateRequested)
-        saveToPersistentStorage(protectionSpace, credential);
-#endif
+    m_protectionSpaceToCredentialMap.set(std::make_pair(partitionName, protectionSpace), credential);
 
     if (!protectionSpace.isProxy() && protectionSpace.authenticationScheme() != ProtectionSpaceAuthenticationSchemeClientCertificateRequested) {
         m_originsWithCredentials.add(originStringFromURL(url));
@@ -89,14 +76,62 @@ void CredentialStorage::set(const Credential& credential, const ProtectionSpace&
     }
 }
 
-Credential CredentialStorage::get(const ProtectionSpace& protectionSpace)
+Credential CredentialStorage::get(const String& partitionName, const ProtectionSpace& protectionSpace)
 {
-    return m_protectionSpaceToCredentialMap.get(protectionSpace);
+    return m_protectionSpaceToCredentialMap.get(std::make_pair(partitionName, protectionSpace));
+}
+
+void CredentialStorage::remove(const String& partitionName, const ProtectionSpace& protectionSpace)
+{
+    m_protectionSpaceToCredentialMap.remove(std::make_pair(partitionName, protectionSpace));
+}
+
+void CredentialStorage::removeCredentialsWithOrigin(const SecurityOriginData& origin)
+{
+    Vector<std::pair<String, ProtectionSpace>> keysToRemove;
+    for (auto& keyValuePair : m_protectionSpaceToCredentialMap) {
+        auto& protectionSpace = keyValuePair.key.second;
+        if (protectionSpace.host() == origin.host
+            && ((origin.port && protectionSpace.port() == *origin.port)
+                || (!origin.port && protectionSpace.port() == 80))
+            && ((protectionSpace.serverType() == ProtectionSpaceServerHTTP && origin.protocol == "http"_s)
+                || (protectionSpace.serverType() == ProtectionSpaceServerHTTPS && origin.protocol == "https"_s)))
+            keysToRemove.append(keyValuePair.key);
+    }
+    for (auto& key : keysToRemove)
+        remove(key.first, key.second);
 }
 
-void CredentialStorage::remove(const ProtectionSpace& protectionSpace)
+HashSet<SecurityOriginData> CredentialStorage::originsWithCredentials() const
 {
-    m_protectionSpaceToCredentialMap.remove(protectionSpace);
+    HashSet<SecurityOriginData> origins;
+    for (auto& keyValuePair : m_protectionSpaceToCredentialMap) {
+        auto& protectionSpace = keyValuePair.key.second;
+        if (protectionSpace.isProxy())
+            continue;
+        String protocol;
+        switch (protectionSpace.serverType()) {
+        case ProtectionSpaceServerHTTP:
+            protocol = "http"_s;
+            break;
+        case ProtectionSpaceServerHTTPS:
+            protocol = "https"_s;
+            break;
+        case ProtectionSpaceServerFTP:
+            protocol = "ftp"_s;
+            break;
+        case ProtectionSpaceServerFTPS:
+            protocol = "ftps"_s;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            continue;
+        }
+
+        SecurityOriginData origin { protocol, protectionSpace.host(), static_cast<uint16_t>(protectionSpace.port())};
+        origins.add(WTFMove(origin));
+    }
+    return origins;
 }
 
 HashMap<String, ProtectionSpace>::iterator CredentialStorage::findDefaultProtectionSpaceForURL(const URL& url)
@@ -125,7 +160,7 @@ HashMap<String, ProtectionSpace>::iterator CredentialStorage::findDefaultProtect
     }
 }
 
-bool CredentialStorage::set(const Credential& credential, const URL& url)
+bool CredentialStorage::set(const String& partitionName, const Credential& credential, const URL& url)
 {
     ASSERT(url.protocolIsInHTTPFamily());
     ASSERT(url.isValid());
@@ -133,16 +168,16 @@ bool CredentialStorage::set(const Credential& credential, const URL& url)
     if (iter == m_pathToDefaultProtectionSpaceMap.end())
         return false;
     ASSERT(m_originsWithCredentials.contains(originStringFromURL(url)));
-    m_protectionSpaceToCredentialMap.set(iter->value, credential);
+    m_protectionSpaceToCredentialMap.set(std::make_pair(partitionName, iter->value), credential);
     return true;
 }
 
-Credential CredentialStorage::get(const URL& url)
+Credential CredentialStorage::get(const String& partitionName, const URL& url)
 {
     PathToDefaultProtectionSpaceMap::iterator iter = findDefaultProtectionSpaceForURL(url);
     if (iter == m_pathToDefaultProtectionSpaceMap.end())
         return Credential();
-    return m_protectionSpaceToCredentialMap.get(iter->value);
+    return m_protectionSpaceToCredentialMap.get(std::make_pair(partitionName, iter->value));
 }
 
 void CredentialStorage::clearCredentials()
@@ -152,4 +187,19 @@ void CredentialStorage::clearCredentials()
     m_pathToDefaultProtectionSpaceMap.clear();
 }
 
+#if !PLATFORM(COCOA)
+HashSet<SecurityOriginData> CredentialStorage::originsWithSessionCredentials()
+{
+    return { };
+}
+
+void CredentialStorage::removeSessionCredentialsWithOrigins(const Vector<SecurityOriginData>&)
+{
+}
+
+void CredentialStorage::clearSessionCredentials()
+{
+}
+#endif
+
 } // namespace WebCore