Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsIChannel.h"
#include "nsIContentPolicy.h"
#include "nsICookieJarSettings.h"
#include "nsILoadInfo.h"
#include "nsIURI.h"
#include "nsNetUtil.h"
#include "nsStringFwd.h"
#include "mozilla/gtest/MozAssertions.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/Preferences.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StoragePrincipalHelper.h"
using mozilla::Preferences;
using namespace mozilla;
/**
* Creates a test channel with CookieJarSettings which have a partitionKey set.
*/
nsresult CreateMockChannel(nsIPrincipal* aPrincipal, bool isThirdParty,
const nsACString& aPartitionKey,
nsIChannel** aChannel,
nsICookieJarSettings** aCookieJarSettings) {
nsCOMPtr<nsIURI> mockUri;
nsresult rv = NS_NewURI(getter_AddRefs(mockUri), "http://example.com"_ns);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> mockChannel;
nsCOMPtr<nsIIOService> service = do_GetIOService(&rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = service->NewChannelFromURI(mockUri, nullptr, aPrincipal, aPrincipal, 0,
nsContentPolicyType::TYPE_OTHER,
getter_AddRefs(mockChannel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILoadInfo> mockLoadInfo = mockChannel->LoadInfo();
rv = mockLoadInfo->SetIsInThirdPartyContext(isThirdParty);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsICookieJarSettings> cjs;
rv = mockLoadInfo->GetCookieJarSettings(getter_AddRefs(cjs));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> partitionKeyUri;
rv = NS_NewURI(getter_AddRefs(partitionKeyUri), aPartitionKey);
NS_ENSURE_SUCCESS(rv, rv);
rv = cjs->InitWithURI(partitionKeyUri, false);
NS_ENSURE_SUCCESS(rv, rv);
cjs.forget(aCookieJarSettings);
mockChannel.forget(aChannel);
return NS_OK;
}
TEST(TestStoragePrincipalHelper, TestCreateContentPrincipal)
{
nsCOMPtr<nsIPrincipal> contentPrincipal =
BasePrincipal::CreateContentPrincipal("https://example.com"_ns);
EXPECT_TRUE(contentPrincipal);
nsCOMPtr<nsIChannel> mockChannel;
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
nsresult rv = CreateMockChannel(
contentPrincipal, false, "https://example.org"_ns,
getter_AddRefs(mockChannel), getter_AddRefs(cookieJarSettings));
ASSERT_EQ(rv, NS_OK) << "Could not create a mock channel";
nsCOMPtr<nsIPrincipal> storagePrincipal;
rv = StoragePrincipalHelper::Create(mockChannel, contentPrincipal, true,
getter_AddRefs(storagePrincipal));
ASSERT_EQ(rv, NS_OK) << "Should not fail for ContentPrincipal";
EXPECT_TRUE(storagePrincipal);
nsCOMPtr<nsIPrincipal> storagePrincipalSW;
rv = StoragePrincipalHelper::CreatePartitionedPrincipalForServiceWorker(
contentPrincipal, cookieJarSettings, getter_AddRefs(storagePrincipalSW));
ASSERT_EQ(rv, NS_OK) << "Should not fail for ContentPrincipal";
EXPECT_TRUE(storagePrincipalSW);
}
TEST(TestStoragePrincipalHelper, TestCreateNullPrincipal)
{
RefPtr<NullPrincipal> nullPrincipal =
NullPrincipal::CreateWithoutOriginAttributes();
EXPECT_TRUE(nullPrincipal);
nsCOMPtr<nsIChannel> mockChannel;
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
nsresult rv = CreateMockChannel(
nullPrincipal, false, "https://example.org"_ns,
getter_AddRefs(mockChannel), getter_AddRefs(cookieJarSettings));
ASSERT_EQ(rv, NS_OK) << "Could not create a mock channel";
nsCOMPtr<nsIPrincipal> storagePrincipal;
rv = StoragePrincipalHelper::Create(mockChannel, nullPrincipal, true,
getter_AddRefs(storagePrincipal));
EXPECT_NS_FAILED(rv) << "Should fail for NullPrincipal";
EXPECT_FALSE(storagePrincipal);
nsCOMPtr<nsIPrincipal> storagePrincipalSW;
rv = StoragePrincipalHelper::CreatePartitionedPrincipalForServiceWorker(
nullPrincipal, cookieJarSettings, getter_AddRefs(storagePrincipalSW));
EXPECT_NS_FAILED(rv) << "Should fail for NullPrincipal";
EXPECT_FALSE(storagePrincipal);
}
TEST(TestStoragePrincipalHelper, TestGetPrincipalCookieBehavior4)
{
Preferences::SetInt("network.cookie.cookieBehavior", 4);
nsCOMPtr<nsIPrincipal> contentPrincipal =
BasePrincipal::CreateContentPrincipal("https://example.com"_ns);
EXPECT_TRUE(contentPrincipal);
for (auto isThirdParty : {false, true}) {
nsCOMPtr<nsIChannel> mockChannel;
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
nsresult rv = CreateMockChannel(
contentPrincipal, isThirdParty, "https://example.org"_ns,
getter_AddRefs(mockChannel), getter_AddRefs(cookieJarSettings));
ASSERT_EQ(rv, NS_OK) << "Could not create a mock channel";
nsCOMPtr<nsIPrincipal> testPrincipal;
rv = StoragePrincipalHelper::GetPrincipal(
mockChannel, StoragePrincipalHelper::eRegularPrincipal,
getter_AddRefs(testPrincipal));
ASSERT_EQ(rv, NS_OK) << "Could not get regular principal";
EXPECT_TRUE(testPrincipal);
EXPECT_TRUE(testPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
rv = StoragePrincipalHelper::GetPrincipal(
mockChannel, StoragePrincipalHelper::ePartitionedPrincipal,
getter_AddRefs(testPrincipal));
ASSERT_EQ(rv, NS_OK) << "Could not get partitioned principal";
EXPECT_TRUE(testPrincipal);
EXPECT_TRUE(
testPrincipal->OriginAttributesRef().mPartitionKey.EqualsLiteral(
"(https,example.org)"));
// We should always get regular principal if the dFPI is disabled.
rv = StoragePrincipalHelper::GetPrincipal(
mockChannel, StoragePrincipalHelper::eForeignPartitionedPrincipal,
getter_AddRefs(testPrincipal));
ASSERT_EQ(rv, NS_OK) << "Could not get foreign partitioned principal";
EXPECT_TRUE(testPrincipal);
EXPECT_TRUE(testPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
// Note that we don't test eStorageAccessPrincipal here because it's hard to
// setup the right state for the storage access in gTest.
}
}
TEST(TestStoragePrincipalHelper, TestGetPrincipalCookieBehavior5)
{
Preferences::SetInt("network.cookie.cookieBehavior", 5);
nsCOMPtr<nsIPrincipal> contentPrincipal =
BasePrincipal::CreateContentPrincipal("https://example.com"_ns);
EXPECT_TRUE(contentPrincipal);
for (auto isThirdParty : {false, true}) {
nsCOMPtr<nsIChannel> mockChannel;
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
nsresult rv = CreateMockChannel(
contentPrincipal, isThirdParty, "https://example.org"_ns,
getter_AddRefs(mockChannel), getter_AddRefs(cookieJarSettings));
ASSERT_EQ(rv, NS_OK) << "Could not create a mock channel";
nsCOMPtr<nsIPrincipal> testPrincipal;
rv = StoragePrincipalHelper::GetPrincipal(
mockChannel, StoragePrincipalHelper::eRegularPrincipal,
getter_AddRefs(testPrincipal));
ASSERT_EQ(rv, NS_OK) << "Could not get regular principal";
EXPECT_TRUE(testPrincipal);
EXPECT_TRUE(testPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
rv = StoragePrincipalHelper::GetPrincipal(
mockChannel, StoragePrincipalHelper::ePartitionedPrincipal,
getter_AddRefs(testPrincipal));
ASSERT_EQ(rv, NS_OK) << "Could not get partitioned principal";
EXPECT_TRUE(testPrincipal);
EXPECT_TRUE(
testPrincipal->OriginAttributesRef().mPartitionKey.EqualsLiteral(
"(https,example.org)"));
// We should always get regular principal if the dFPI is disabled.
rv = StoragePrincipalHelper::GetPrincipal(
mockChannel, StoragePrincipalHelper::eForeignPartitionedPrincipal,
getter_AddRefs(testPrincipal));
ASSERT_EQ(rv, NS_OK) << "Could not get foreign partitioned principal";
EXPECT_TRUE(testPrincipal);
if (isThirdParty) {
EXPECT_TRUE(
testPrincipal->OriginAttributesRef().mPartitionKey.EqualsLiteral(
"(https,example.org)"));
} else {
EXPECT_TRUE(testPrincipal->OriginAttributesRef().mPartitionKey.IsEmpty());
}
// Note that we don't test eStorageAccessPrincipal here because it's hard to
// setup the right state for the storage access in gTest.
}
}