TestPrincipalSerialization.cpp (7235B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 #include "gtest/gtest.h" 5 #include "mozilla/Base64.h" 6 #include "mozilla/BasePrincipal.h" 7 #include "mozilla/ContentPrincipal.h" 8 #include "mozilla/NullPrincipal.h" 9 #include "mozilla/SystemPrincipal.h" 10 #include "mozilla/ExpandedPrincipal.h" 11 12 using mozilla::BasePrincipal; 13 using mozilla::ContentPrincipal; 14 using mozilla::NullPrincipal; 15 using mozilla::SystemPrincipal; 16 17 // None of these tests work in debug due to assert guards 18 #ifndef MOZ_DEBUG 19 20 // calling toJSON() twice with the same string arg 21 // (ensure that we truncate correctly where needed) 22 TEST(PrincipalSerialization, ReusedJSONArgument) 23 { 24 nsCOMPtr<nsIScriptSecurityManager> ssm = 25 nsScriptSecurityManager::GetScriptSecurityManager(); 26 27 nsAutoCString spec("https://mozilla.com"); 28 nsCOMPtr<nsIPrincipal> principal; 29 nsresult rv = 30 ssm->CreateContentPrincipalFromOrigin(spec, getter_AddRefs(principal)); 31 ASSERT_EQ(rv, NS_OK); 32 33 nsAutoCString JSON; 34 rv = BasePrincipal::Cast(principal)->ToJSON(JSON); 35 ASSERT_EQ(rv, NS_OK); 36 ASSERT_TRUE(JSON.EqualsLiteral("{\"1\":{\"0\":\"https://mozilla.com/\"}}")); 37 38 nsAutoCString spec2("https://example.com"); 39 nsCOMPtr<nsIPrincipal> principal2; 40 rv = ssm->CreateContentPrincipalFromOrigin(spec2, getter_AddRefs(principal2)); 41 ASSERT_EQ(rv, NS_OK); 42 43 // Reuse JSON without truncation to check the code is doing this 44 rv = BasePrincipal::Cast(principal2)->ToJSON(JSON); 45 ASSERT_EQ(rv, NS_OK); 46 ASSERT_TRUE(JSON.EqualsLiteral("{\"1\":{\"0\":\"https://example.com/\"}}")); 47 } 48 49 // Double check that if we have two valid principals in a serialized JSON that 50 // nullptr is returned 51 TEST(PrincipalSerialization, TwoKeys) 52 { 53 // Sanity check that this returns a system principal 54 nsCOMPtr<nsIPrincipal> systemPrincipal = 55 BasePrincipal::FromJSON("{\"3\":{}}"_ns); 56 ASSERT_EQ(BasePrincipal::Cast(systemPrincipal)->Kind(), 57 BasePrincipal::eSystemPrincipal); 58 59 // Sanity check that this returns a content principal 60 nsCOMPtr<nsIPrincipal> contentPrincipal = 61 BasePrincipal::FromJSON("{\"1\":{\"0\":\"https://mozilla.com\"}}"_ns); 62 ASSERT_EQ(BasePrincipal::Cast(contentPrincipal)->Kind(), 63 BasePrincipal::eContentPrincipal); 64 65 // Check both combined don't return a principal 66 nsCOMPtr<nsIPrincipal> combinedPrincipal = BasePrincipal::FromJSON( 67 "{\"1\":{\"0\":\"https://mozilla.com\"},\"3\":{}}"_ns); 68 ASSERT_EQ(nullptr, combinedPrincipal); 69 } 70 71 #endif // ifndef MOZ_DEBUG 72 73 TEST(PrincipalSerialization, ExpandedPrincipal) 74 { 75 // Check basic Expandedprincipal works without OA 76 nsCOMPtr<nsIScriptSecurityManager> ssm = 77 nsScriptSecurityManager::GetScriptSecurityManager(); 78 79 uint32_t length = 2; 80 nsTArray<nsCOMPtr<nsIPrincipal> > allowedDomains(length); 81 allowedDomains.SetLength(length); 82 83 nsAutoCString spec("https://mozilla.com"); 84 nsCOMPtr<nsIPrincipal> principal; 85 nsresult rv = 86 ssm->CreateContentPrincipalFromOrigin(spec, getter_AddRefs(principal)); 87 ASSERT_EQ(rv, NS_OK); 88 ASSERT_EQ(BasePrincipal::Cast(principal)->Kind(), 89 BasePrincipal::eContentPrincipal); 90 allowedDomains[0] = principal; 91 92 nsAutoCString spec2("https://mozilla.org"); 93 nsCOMPtr<nsIPrincipal> principal2; 94 rv = ssm->CreateContentPrincipalFromOrigin(spec2, getter_AddRefs(principal2)); 95 ASSERT_EQ(rv, NS_OK); 96 ASSERT_EQ(BasePrincipal::Cast(principal2)->Kind(), 97 BasePrincipal::eContentPrincipal); 98 allowedDomains[1] = principal2; 99 100 mozilla::OriginAttributes attrs; 101 RefPtr<ExpandedPrincipal> result = 102 ExpandedPrincipal::Create(allowedDomains, attrs); 103 ASSERT_EQ(BasePrincipal::Cast(result)->Kind(), 104 BasePrincipal::eExpandedPrincipal); 105 106 nsAutoCString JSON; 107 rv = BasePrincipal::Cast(result)->ToJSON(JSON); 108 ASSERT_EQ(rv, NS_OK); 109 ASSERT_STREQ(JSON.get(), 110 "{\"2\":{\"0\":[{\"1\":{\"0\":\"https://mozilla.com/" 111 "\"}},{\"1\":{\"0\":\"https://mozilla.org/\"}}]}}"); 112 113 nsCOMPtr<nsIPrincipal> returnedPrincipal = BasePrincipal::FromJSON(JSON); 114 auto outPrincipal = BasePrincipal::Cast(returnedPrincipal); 115 ASSERT_EQ(outPrincipal->Kind(), BasePrincipal::eExpandedPrincipal); 116 117 ASSERT_TRUE(outPrincipal->FastSubsumesIgnoringFPD(principal)); 118 ASSERT_TRUE(outPrincipal->FastSubsumesIgnoringFPD(principal2)); 119 120 nsAutoCString specDev("https://mozilla.dev"); 121 nsCOMPtr<nsIPrincipal> principalDev; 122 rv = ssm->CreateContentPrincipalFromOrigin(specDev, 123 getter_AddRefs(principalDev)); 124 ASSERT_EQ(rv, NS_OK); 125 ASSERT_EQ(BasePrincipal::Cast(principalDev)->Kind(), 126 BasePrincipal::eContentPrincipal); 127 128 ASSERT_FALSE(outPrincipal->FastSubsumesIgnoringFPD(principalDev)); 129 } 130 131 TEST(PrincipalSerialization, ExpandedPrincipalOA) 132 { 133 // Check Expandedprincipal works with top level OA 134 nsCOMPtr<nsIScriptSecurityManager> ssm = 135 nsScriptSecurityManager::GetScriptSecurityManager(); 136 137 uint32_t length = 2; 138 nsTArray<nsCOMPtr<nsIPrincipal> > allowedDomains(length); 139 allowedDomains.SetLength(length); 140 141 nsAutoCString spec("https://mozilla.com"); 142 nsCOMPtr<nsIPrincipal> principal; 143 nsresult rv = 144 ssm->CreateContentPrincipalFromOrigin(spec, getter_AddRefs(principal)); 145 ASSERT_EQ(rv, NS_OK); 146 ASSERT_EQ(BasePrincipal::Cast(principal)->Kind(), 147 BasePrincipal::eContentPrincipal); 148 allowedDomains[0] = principal; 149 150 nsAutoCString spec2("https://mozilla.org"); 151 nsCOMPtr<nsIPrincipal> principal2; 152 rv = ssm->CreateContentPrincipalFromOrigin(spec2, getter_AddRefs(principal2)); 153 ASSERT_EQ(rv, NS_OK); 154 ASSERT_EQ(BasePrincipal::Cast(principal2)->Kind(), 155 BasePrincipal::eContentPrincipal); 156 allowedDomains[1] = principal2; 157 158 mozilla::OriginAttributes attrs; 159 nsAutoCString suffix("^userContextId=1"); 160 bool ok = attrs.PopulateFromSuffix(suffix); 161 ASSERT_TRUE(ok); 162 163 RefPtr<ExpandedPrincipal> result = 164 ExpandedPrincipal::Create(allowedDomains, attrs); 165 ASSERT_EQ(BasePrincipal::Cast(result)->Kind(), 166 BasePrincipal::eExpandedPrincipal); 167 168 nsAutoCString JSON; 169 rv = BasePrincipal::Cast(result)->ToJSON(JSON); 170 ASSERT_EQ(rv, NS_OK); 171 ASSERT_STREQ(JSON.get(), 172 "{\"2\":{\"0\":[{\"1\":{\"0\":\"https://mozilla.com/" 173 "\"}},{\"1\":{\"0\":\"https://mozilla.org/" 174 "\"}}],\"1\":\"^userContextId=1\"}}"); 175 176 nsCOMPtr<nsIPrincipal> returnedPrincipal = BasePrincipal::FromJSON(JSON); 177 auto outPrincipal = BasePrincipal::Cast(returnedPrincipal); 178 ASSERT_EQ(outPrincipal->Kind(), BasePrincipal::eExpandedPrincipal); 179 180 ASSERT_TRUE(outPrincipal->FastSubsumesIgnoringFPD(principal)); 181 ASSERT_TRUE(outPrincipal->FastSubsumesIgnoringFPD(principal2)); 182 183 nsAutoCString specDev("https://mozilla.dev"); 184 nsCOMPtr<nsIPrincipal> principalDev; 185 rv = ssm->CreateContentPrincipalFromOrigin(specDev, 186 getter_AddRefs(principalDev)); 187 ASSERT_EQ(rv, NS_OK); 188 ASSERT_EQ(BasePrincipal::Cast(principalDev)->Kind(), 189 BasePrincipal::eContentPrincipal); 190 191 ASSERT_FALSE(outPrincipal->FastSubsumesIgnoringFPD(principalDev)); 192 }