Commit e2c4a0bb authored by Jason Chase's avatar Jason Chase Committed by Commit Bot

Allow trials to be enabled in insecure contexts

Previously, origin trials could only be enabled in secure contexts. This
restriction makes sense for new, experimental features. However, for
trials to extend the use of deprecated features, this restriction is
less useful. See crbug.com/1027546 for details.

This CL removes the global restriction to secure contexts. Instead, it is
now possible to allow specific trials to be used in insecure contexts.
For now, only a single test trial is hard-coded to allow insecure
contexts. A follow-up CL will implement configuration for deprecation
trials to allow insecure contexts.

NOTE: All tokens will now be parsed and validated in insecure contexts.
Previously, the insecure context check happened first, and would exit
early before token validation. This means extra work is done for regular
trial tokens. That can't really be avoided, as the token has to be
parsed to get the trial name.

Bug: 1027546
Change-Id: Ia37422ade598561909006425464fad20775eb44a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1932241
Commit-Queue: Jason Chase <chasej@chromium.org>
Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarIan Clelland <iclelland@chromium.org>
Cr-Commit-Position: refs/heads/master@{#721877}
parent ea553f7a
...@@ -41,6 +41,13 @@ bool origin_trials::IsTrialValid(const String& trial_name) { ...@@ -41,6 +41,13 @@ bool origin_trials::IsTrialValid(const String& trial_name) {
return GetTrialToFeaturesMap().Contains(trial_name); return GetTrialToFeaturesMap().Contains(trial_name);
} }
bool origin_trials::IsTrialEnabledForInsecureContext(const String& trial_name) {
// TODO(crbug.com/1027546): Generate the contents from config in runtime_enabled_features.json5.
if (trial_name == "FrobulateDeprecation") {
return true;
}
return false;
}
const Vector<OriginTrialFeature>& origin_trials::FeaturesForTrial(const String& trial_name) { const Vector<OriginTrialFeature>& origin_trials::FeaturesForTrial(const String& trial_name) {
DCHECK(IsTrialValid(trial_name)); DCHECK(IsTrialValid(trial_name));
......
...@@ -272,7 +272,6 @@ void OriginTrialContext::AddFeature(OriginTrialFeature feature) { ...@@ -272,7 +272,6 @@ void OriginTrialContext::AddFeature(OriginTrialFeature feature) {
} }
bool OriginTrialContext::IsFeatureEnabled(OriginTrialFeature feature) const { bool OriginTrialContext::IsFeatureEnabled(OriginTrialFeature feature) const {
if (enabled_features_.Contains(feature) || if (enabled_features_.Contains(feature) ||
navigation_activated_features_.Contains(feature)) { navigation_activated_features_.Contains(feature)) {
return true; return true;
...@@ -305,19 +304,6 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin, ...@@ -305,19 +304,6 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
const String& token) { const String& token) {
DCHECK(!token.IsEmpty()); DCHECK(!token.IsEmpty());
// Origin trials are only enabled for secure origins
// - For worklets, they are currently spec'd to not be secure, given their
// scope has unique origin:
// https://drafts.css-houdini.org/worklets/#script-settings-for-worklets
// - For the purpose of origin trials, we consider worklets as running in the
// same context as the originating document. Thus, the special logic here
// to validate the token against the document context.
if (!is_secure) {
TokenValidationResultHistogram().Count(
static_cast<int>(OriginTrialTokenStatus::kInsecure));
return false;
}
if (!trial_token_validator_) { if (!trial_token_validator_) {
TokenValidationResultHistogram().Count( TokenValidationResultHistogram().Count(
static_cast<int>(OriginTrialTokenStatus::kNotSupported)); static_cast<int>(OriginTrialTokenStatus::kNotSupported));
...@@ -334,17 +320,25 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin, ...@@ -334,17 +320,25 @@ bool OriginTrialContext::EnableTrialFromToken(const SecurityOrigin* origin,
String trial_name = String trial_name =
String::FromUTF8(trial_name_str.data(), trial_name_str.size()); String::FromUTF8(trial_name_str.data(), trial_name_str.size());
if (origin_trials::IsTrialValid(trial_name)) { if (origin_trials::IsTrialValid(trial_name)) {
for (OriginTrialFeature feature : // Origin trials are only enabled for secure origins. The only exception
origin_trials::FeaturesForTrial(trial_name)) { // is for deprecation trials.
if (origin_trials::FeatureEnabledForOS(feature)) { if (is_secure ||
valid = true; origin_trials::IsTrialEnabledForInsecureContext(trial_name)) {
enabled_features_.insert(feature); for (OriginTrialFeature feature :
// Also enable any features implied by this feature. origin_trials::FeaturesForTrial(trial_name)) {
for (OriginTrialFeature implied_feature : if (origin_trials::FeatureEnabledForOS(feature)) {
origin_trials::GetImpliedFeatures(feature)) { valid = true;
enabled_features_.insert(implied_feature); enabled_features_.insert(feature);
// Also enable any features implied by this feature.
for (OriginTrialFeature implied_feature :
origin_trials::GetImpliedFeatures(feature)) {
enabled_features_.insert(implied_feature);
}
} }
} }
} else {
// Insecure origin and trial is restricted to secure origins.
token_result = OriginTrialTokenStatus::kInsecure;
} }
} }
} }
...@@ -360,6 +354,10 @@ void OriginTrialContext::Trace(blink::Visitor* visitor) { ...@@ -360,6 +354,10 @@ void OriginTrialContext::Trace(blink::Visitor* visitor) {
const SecurityOrigin* OriginTrialContext::GetSecurityOrigin() { const SecurityOrigin* OriginTrialContext::GetSecurityOrigin() {
const SecurityOrigin* origin; const SecurityOrigin* origin;
CHECK(context_); CHECK(context_);
// Determines the origin to be validated against tokens:
// - For the purpose of origin trials, we consider worklets as running in the
// same context as the originating document. Thus, the special logic here
// to use the origin from the document context.
if (auto* scope = DynamicTo<WorkletGlobalScope>(context_.Get())) if (auto* scope = DynamicTo<WorkletGlobalScope>(context_.Get()))
origin = scope->DocumentSecurityOrigin(); origin = scope->DocumentSecurityOrigin();
else else
...@@ -370,6 +368,13 @@ const SecurityOrigin* OriginTrialContext::GetSecurityOrigin() { ...@@ -370,6 +368,13 @@ const SecurityOrigin* OriginTrialContext::GetSecurityOrigin() {
bool OriginTrialContext::IsSecureContext() { bool OriginTrialContext::IsSecureContext() {
bool is_secure = false; bool is_secure = false;
CHECK(context_); CHECK(context_);
// Determines if this is a secure context:
// - For worklets, they are currently spec'd to not be secure, given their
// scope has unique origin:
// https://drafts.css-houdini.org/worklets/#script-settings-for-worklets
// - For the purpose of origin trials, we consider worklets as running in the
// same context as the originating document. Thus, the special logic here
// to check the secure status of the document context.
if (auto* scope = DynamicTo<WorkletGlobalScope>(context_.Get())) { if (auto* scope = DynamicTo<WorkletGlobalScope>(context_.Get())) {
is_secure = scope->DocumentSecureContext(); is_secure = scope->DocumentSecureContext();
} else { } else {
......
...@@ -28,6 +28,7 @@ namespace blink { ...@@ -28,6 +28,7 @@ namespace blink {
namespace { namespace {
const char kFrobulateTrialName[] = "Frobulate"; const char kFrobulateTrialName[] = "Frobulate";
const char kFrobulateDeprecationTrialName[] = "FrobulateDeprecation";
const char kFrobulateNavigationTrialName[] = "FrobulateNavigation"; const char kFrobulateNavigationTrialName[] = "FrobulateNavigation";
const char kFrobulateEnabledOrigin[] = "https://www.example.com"; const char kFrobulateEnabledOrigin[] = "https://www.example.com";
const char kFrobulateEnabledOriginUnsecure[] = "http://www.example.com"; const char kFrobulateEnabledOriginUnsecure[] = "http://www.example.com";
...@@ -72,7 +73,7 @@ class MockTokenValidator : public TrialTokenValidator { ...@@ -72,7 +73,7 @@ class MockTokenValidator : public TrialTokenValidator {
} // namespace } // namespace
class OriginTrialContextTest : public testing::Test{ class OriginTrialContextTest : public testing::Test {
protected: protected:
OriginTrialContextTest() OriginTrialContextTest()
: token_validator_(new MockTokenValidator), : token_validator_(new MockTokenValidator),
...@@ -154,6 +155,25 @@ TEST_F(OriginTrialContextTest, EnabledSecureRegisteredOrigin) { ...@@ -154,6 +155,25 @@ TEST_F(OriginTrialContextTest, EnabledSecureRegisteredOrigin) {
EXPECT_EQ(nullptr, GetEnabledNavigationFeatures()); EXPECT_EQ(nullptr, GetEnabledNavigationFeatures());
} }
// The feature should be enabled if a valid token for a deprecation trial for
// the origin is provided.
TEST_F(OriginTrialContextTest, EnabledSecureRegisteredOriginDeprecation) {
TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
kFrobulateDeprecationTrialName);
bool is_origin_enabled =
IsFeatureEnabled(kFrobulateEnabledOrigin,
OriginTrialFeature::kOriginTrialsSampleAPIDeprecation);
EXPECT_TRUE(is_origin_enabled);
EXPECT_EQ(1, TokenValidator()->CallCount());
// Status metric should be updated.
ExpectStatusUniqueMetric(OriginTrialTokenStatus::kSuccess, 1);
// kOriginTrialsSampleAPIDeprecation is not a navigation feature, so shouldn't
// be included in GetEnabledNavigationFeatures().
EXPECT_EQ(nullptr, GetEnabledNavigationFeatures());
}
// ... but if the browser says it's invalid for any reason, that's enough to // ... but if the browser says it's invalid for any reason, that's enough to
// reject. // reject.
TEST_F(OriginTrialContextTest, InvalidTokenResponseFromPlatform) { TEST_F(OriginTrialContextTest, InvalidTokenResponseFromPlatform) {
...@@ -177,10 +197,36 @@ TEST_F(OriginTrialContextTest, EnabledNonSecureRegisteredOrigin) { ...@@ -177,10 +197,36 @@ TEST_F(OriginTrialContextTest, EnabledNonSecureRegisteredOrigin) {
IsFeatureEnabled(kFrobulateEnabledOriginUnsecure, IsFeatureEnabled(kFrobulateEnabledOriginUnsecure,
OriginTrialFeature::kOriginTrialsSampleAPI); OriginTrialFeature::kOriginTrialsSampleAPI);
EXPECT_FALSE(is_origin_enabled); EXPECT_FALSE(is_origin_enabled);
EXPECT_EQ(0, TokenValidator()->CallCount()); EXPECT_EQ(1, TokenValidator()->CallCount());
ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1); ExpectStatusUniqueMetric(OriginTrialTokenStatus::kInsecure, 1);
} }
// The feature should be enabled if the origin is insecure, for a valid token
// for a deprecation trial.
TEST_F(OriginTrialContextTest,
EnabledNonSecureRegisteredOriginDeprecationWithToken) {
TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
kFrobulateDeprecationTrialName);
bool is_origin_enabled =
IsFeatureEnabled(kFrobulateEnabledOriginUnsecure,
OriginTrialFeature::kOriginTrialsSampleAPIDeprecation);
EXPECT_TRUE(is_origin_enabled);
EXPECT_EQ(1, TokenValidator()->CallCount());
ExpectStatusUniqueMetric(OriginTrialTokenStatus::kSuccess, 1);
}
// The feature should not be enabled if the origin is insecure, without a valid
// token for a deprecation trial.
TEST_F(OriginTrialContextTest,
EnabledNonSecureRegisteredOriginDeprecationNoToken) {
TokenValidator()->SetResponse(OriginTrialTokenStatus::kSuccess,
kFrobulateTrialName);
bool is_origin_enabled =
IsFeatureEnabled(kFrobulateEnabledOriginUnsecure,
OriginTrialFeature::kOriginTrialsSampleAPIDeprecation);
EXPECT_FALSE(is_origin_enabled);
}
TEST_F(OriginTrialContextTest, ParseHeaderValue) { TEST_F(OriginTrialContextTest, ParseHeaderValue) {
std::unique_ptr<Vector<String>> tokens; std::unique_ptr<Vector<String>> tokens;
ASSERT_TRUE(tokens = OriginTrialContext::ParseHeaderValue(" foo\t ")); ASSERT_TRUE(tokens = OriginTrialContext::ParseHeaderValue(" foo\t "));
......
...@@ -22,6 +22,9 @@ namespace origin_trials { ...@@ -22,6 +22,9 @@ namespace origin_trials {
// Return true if there is a feature with the passed |trial_name|. // Return true if there is a feature with the passed |trial_name|.
CORE_EXPORT bool IsTrialValid(const String& trial_name); CORE_EXPORT bool IsTrialValid(const String& trial_name);
// Return true if |trial_name| can be enabled in an insecure context.
CORE_EXPORT bool IsTrialEnabledForInsecureContext(const String& trial_name);
// Return origin trials features that are enabled by the passed |trial_name|. // Return origin trials features that are enabled by the passed |trial_name|.
// The trial name MUST be valid (call IsTrialValid() before calling this // The trial name MUST be valid (call IsTrialValid() before calling this
// function). // function).
......
...@@ -54,6 +54,8 @@ class OriginTrialsTest : public ScriptWrappable { ...@@ -54,6 +54,8 @@ class OriginTrialsTest : public ScriptWrappable {
bool secureMethod() { return true; } bool secureMethod() { return true; }
static bool secureStaticMethod() { return true; } static bool secureStaticMethod() { return true; }
bool deprecationAttribute() { return true; }
bool impliedAttribute() { return true; } bool impliedAttribute() { return true; }
bool invalidOSAttribute() { return true; } bool invalidOSAttribute() { return true; }
......
...@@ -14,11 +14,11 @@ interface OriginTrialsTest { ...@@ -14,11 +14,11 @@ interface OriginTrialsTest {
[CallWith=ScriptState, RaisesException] readonly attribute boolean throwingAttribute; [CallWith=ScriptState, RaisesException] readonly attribute boolean throwingAttribute;
// This method returns a dictionary, to allow inspection of trial-controlled // This method returns a dictionary, to allow inspection of trial-controlled
// members // members.
OriginTrialsTestDictionary getDictionaryMethod(); OriginTrialsTestDictionary getDictionaryMethod();
// This method takes a dictionary as input, to test if trial-controlled // This method takes a dictionary as input, to test if trial-controlled
// members are accessed // members are accessed.
void checkDictionaryMethod(OriginTrialsTestDictionary dict); void checkDictionaryMethod(OriginTrialsTestDictionary dict);
// These are available whether or not the trial is enabled. // These are available whether or not the trial is enabled.
...@@ -30,7 +30,7 @@ interface OriginTrialsTest { ...@@ -30,7 +30,7 @@ interface OriginTrialsTest {
const unsigned short UNCONDITIONAL_CONSTANT = 99; const unsigned short UNCONDITIONAL_CONSTANT = 99;
// These are available whether or not the trial is enabled, but only in a // These are available whether or not the trial is enabled, but only in a
// secure context // secure context.
[SecureContext] readonly attribute boolean secureUnconditionalAttribute; [SecureContext] readonly attribute boolean secureUnconditionalAttribute;
// TODO(chasej): Add [SecureContext] when that attribute is fixed to work on // TODO(chasej): Add [SecureContext] when that attribute is fixed to work on
// static attributes. That problem is not related to [RuntimeEnabled]. // static attributes. That problem is not related to [RuntimeEnabled].
...@@ -45,8 +45,12 @@ interface OriginTrialsTest { ...@@ -45,8 +45,12 @@ interface OriginTrialsTest {
[SecureContext, RuntimeEnabled=OriginTrialsSampleAPI] boolean secureMethod(); [SecureContext, RuntimeEnabled=OriginTrialsSampleAPI] boolean secureMethod();
[SecureContext, RuntimeEnabled=OriginTrialsSampleAPI] static boolean secureStaticMethod(); [SecureContext, RuntimeEnabled=OriginTrialsSampleAPI] static boolean secureStaticMethod();
// These are available if the associated deprecation trial is available,
// even for insecure contexts.
[RuntimeEnabled=OriginTrialsSampleAPIDeprecation] readonly attribute boolean deprecationAttribute;
// These are available if the specified trial is available, and also if the // These are available if the specified trial is available, and also if the
// implied by trial is enabled // implied by trial is enabled.
[RuntimeEnabled=OriginTrialsSampleAPIImplied] readonly attribute boolean impliedAttribute; [RuntimeEnabled=OriginTrialsSampleAPIImplied] readonly attribute boolean impliedAttribute;
// These are not available even with the token present. // These are not available even with the token present.
......
...@@ -100,6 +100,12 @@ void InstallOriginTrialFeaturesForTesting( ...@@ -100,6 +100,12 @@ void InstallOriginTrialFeaturesForTesting(
script_state->GetIsolate(), script_state->World(), script_state->GetIsolate(), script_state->World(),
v8::Local<v8::Object>(), prototype_object, interface_object); v8::Local<v8::Object>(), prototype_object, interface_object);
} }
if (RuntimeEnabledFeatures::OriginTrialsSampleAPIDeprecationEnabled(
execution_context)) {
V8OriginTrialsTest::InstallOriginTrialsSampleAPIDeprecation(
script_state->GetIsolate(), script_state->World(),
v8::Local<v8::Object>(), prototype_object, interface_object);
}
if (RuntimeEnabledFeatures::OriginTrialsSampleAPIImpliedEnabled( if (RuntimeEnabledFeatures::OriginTrialsSampleAPIImpliedEnabled(
execution_context)) { execution_context)) {
V8OriginTrialsTest::InstallOriginTrialsSampleAPIImplied( V8OriginTrialsTest::InstallOriginTrialsSampleAPIImplied(
...@@ -154,6 +160,17 @@ void InstallPendingOriginTrialFeatureForTesting( ...@@ -154,6 +160,17 @@ void InstallPendingOriginTrialFeatureForTesting(
} }
break; break;
} }
case OriginTrialFeature::kOriginTrialsSampleAPIDeprecation: {
if (script_state->PerContextData()
->GetExistingConstructorAndPrototypeForType(
V8OriginTrialsTest::GetWrapperTypeInfo(), &prototype_object,
&interface_object)) {
V8OriginTrialsTest::InstallOriginTrialsSampleAPIDeprecation(
script_state->GetIsolate(), script_state->World(),
v8::Local<v8::Object>(), prototype_object, interface_object);
}
break;
}
case OriginTrialFeature::kOriginTrialsSampleAPIImplied: { case OriginTrialFeature::kOriginTrialsSampleAPIImplied: {
if (script_state->PerContextData() if (script_state->PerContextData()
->GetExistingConstructorAndPrototypeForType( ->GetExistingConstructorAndPrototypeForType(
......
...@@ -1154,25 +1154,35 @@ ...@@ -1154,25 +1154,35 @@
name: "OriginTrialsSampleAPI", name: "OriginTrialsSampleAPI",
origin_trial_feature_name: "Frobulate", origin_trial_feature_name: "Frobulate",
}, },
// As above. Do not change this flag to stable, as it exists solely to
// generate code used by the origin trials sample API implementation.
// TODO(yashard): Add tests for this feature. // TODO(yashard): Add tests for this feature.
{ {
name: "OriginTrialsSampleAPIDependent", name: "OriginTrialsSampleAPIDependent",
depends_on: ["OriginTrialsSampleAPI"], depends_on: ["OriginTrialsSampleAPI"],
}, },
// Define a sample API for testing integration with the Origin Trials // As above. Do not change this flag to stable, as it exists solely to
// Framework. The sample API is used in both unit and web tests for the // generate code used by the origin trials sample API implementation.
// Origin Trials Framework. Do not change this flag to stable, as it exists {
// solely to generate code used by the sample API implementation. name: "OriginTrialsSampleAPIDeprecation",
origin_trial_feature_name: "FrobulateDeprecation",
},
// As above. Do not change this flag to stable, as it exists solely to
// generate code used by the origin trials sample API implementation.
{ {
name: "OriginTrialsSampleAPIImplied", name: "OriginTrialsSampleAPIImplied",
origin_trial_feature_name: "FrobulateImplied", origin_trial_feature_name: "FrobulateImplied",
implied_by: ["OriginTrialsSampleAPI", "OriginTrialsSampleAPIInvalidOS"], implied_by: ["OriginTrialsSampleAPI", "OriginTrialsSampleAPIInvalidOS"],
}, },
// As above. Do not change this flag to stable, as it exists solely to
// generate code used by the origin trials sample API implementation.
{ {
name: "OriginTrialsSampleAPIInvalidOS", name: "OriginTrialsSampleAPIInvalidOS",
origin_trial_feature_name: "FrobulateInvalidOS", origin_trial_feature_name: "FrobulateInvalidOS",
origin_trial_os: ["invalid"], origin_trial_os: ["invalid"],
}, },
// As above. Do not change this flag to stable, as it exists solely to
// generate code used by the origin trials sample API implementation.
{ {
name: "OriginTrialsSampleAPINavigation", name: "OriginTrialsSampleAPINavigation",
origin_trial_feature_name: "FrobulateNavigation", origin_trial_feature_name: "FrobulateNavigation",
......
This directory contains tests to ensure that the origin trials framework
correctly handles enables/disables trials based on combinations of:
- Tokens missing or invalid
- Tokens provided via header, <meta> tag, and injected via script
- Secure and insecure contexts
- JS exposure via bindings for various IDL constructs
The conventions for test file naming:
- If the name contains "enabled", it generally means that a valid token is
provided, regardless if the trial actually ends up being enabled.
- If the name contains "disabled", it generally means that no token is provided.
TODO(chasej): Rename the test files for clarity, so we don't need to explain
the naming convention. e.g. "has-token", "valid-token" vs "no-token". Then
can use "enabled" or "disabled" to reflect expected status.
importScripts('origintrials-worker.js');
expect_failure_worker_deprecation();
importScripts('origintrials-worker.js');
expect_success_worker_deprecation();
...@@ -45,6 +45,20 @@ expect_failure_worker = () => { ...@@ -45,6 +45,20 @@ expect_failure_worker = () => {
done(); done();
} }
// Test whether the origin-trial-enabled attributes are *NOT* attached in a
// worker where the deprecation trial is not enabled.
expect_failure_worker_deprecation = () => {
// Use |worker_type| to make the test descriptions unique when multiple
// workers are created in a single test file.
var worker_type = get_worker_type();
test(() => {
var testObject = self.internals.originTrialsTest();
assert_false('deprecationAttribute' in testObject);
assert_equals(testObject.deprecationAttribute, undefined);
}, 'Deprecation attribute should not exist in ' + worker_type + ' worker');
done();
}
// Test whether the origin-trial-enabled attributes are *NOT* attached in a // Test whether the origin-trial-enabled attributes are *NOT* attached in a
// worker where the implied trial is not enabled. // worker where the implied trial is not enabled.
expect_failure_worker_implied = () => { expect_failure_worker_implied = () => {
...@@ -105,6 +119,21 @@ expect_success_worker = () => { ...@@ -105,6 +119,21 @@ expect_success_worker = () => {
done(); done();
} }
// Test whether the origin-trial-enabled attributes are attached in a worker
// where the deprecation trial is enabled, either directly or by the related
// trial.
expect_success_worker_deprecation = () => {
// Use |worker_type| to make the test descriptions unique when multiple
// workers are created in a single test file.
var worker_type = get_worker_type();
test(() => {
var testObject = self.internals.originTrialsTest();
assert_idl_attribute(testObject, 'deprecationAttribute');
assert_true(testObject.deprecationAttribute, 'Attribute should return boolean value');
}, 'Deprecation attribute should exist and return value in ' + worker_type + ' worker');
done();
}
// Test whether the origin-trial-enabled attributes are attached in a worker // Test whether the origin-trial-enabled attributes are attached in a worker
// where the implied trial is enabled, either directly or by the related trial. // where the implied trial is enabled, either directly or by the related trial.
expect_success_worker_implied = () => { expect_success_worker_implied = () => {
......
...@@ -135,6 +135,19 @@ expect_failure = (skip_worker) => { ...@@ -135,6 +135,19 @@ expect_failure = (skip_worker) => {
} }
}; };
// These tests verify that any gated parts of the API are not available for a
// deprecation trial.
expect_failure_deprecation = (skip_worker) => {
test(() => {
expect_member_fails('deprecationAttribute');
}, 'Deprecation attribute should not exist, with trial disabled');
if (!skip_worker) {
fetch_tests_from_worker(new Worker('resources/deprecation-disabled-worker.js'));
}
};
// These tests verify that any gated parts of the API are not available for an // These tests verify that any gated parts of the API are not available for an
// implied trial. // implied trial.
expect_failure_implied = (skip_worker) => { expect_failure_implied = (skip_worker) => {
...@@ -185,6 +198,22 @@ expect_success = () => { ...@@ -185,6 +198,22 @@ expect_success = () => {
fetch_tests_from_worker(new Worker('resources/enabled-worker.js')); fetch_tests_from_worker(new Worker('resources/enabled-worker.js'));
}; };
// These tests verify that the API functions correctly with a deprecation trial
// that is enabled.
expect_success_deprecation = (opt_description_suffix, skip_worker) => {
var description_suffix = opt_description_suffix || '';
test(() => {
expect_member('deprecationAttribute', (testObject) => {
return testObject.deprecationAttribute;
});
}, 'Deprecation attribute should exist on object and return value' + description_suffix);
if (!skip_worker) {
fetch_tests_from_worker(new Worker('resources/deprecation-enabled-worker.js'));
}
};
// These tests verify that the API functions correctly with an implied trial // These tests verify that the API functions correctly with an implied trial
// that is enabled. // that is enabled.
expect_success_implied = (opt_description_suffix, skip_worker) => { expect_success_implied = (opt_description_suffix, skip_worker) => {
...@@ -301,6 +330,10 @@ expect_success_bindings = (insecure_context) => { ...@@ -301,6 +330,10 @@ expect_success_bindings = (insecure_context) => {
// between [RuntimeEnabled] or [SecureContext] preventing exposure of // between [RuntimeEnabled] or [SecureContext] preventing exposure of
// IDL members. These tests at least ensure IDL members are not exposed in // IDL members. These tests at least ensure IDL members are not exposed in
// insecure contexts, regardless of reason. // insecure contexts, regardless of reason.
test(() => {
expect_member_fails('normalAttribute');
}, 'Attribute should not exist in insecure context');
test(() => { test(() => {
expect_member_fails('secureAttribute'); expect_member_fails('secureAttribute');
}, 'Secure attribute should not exist'); }, 'Secure attribute should not exist');
......
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test Sample API when deprecation trial is disabled, in insecure context</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/get-host-info.js"></script>
<script src="resources/origintrials.js"></script>
<script>
if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) {
window.location = get_host_info().UNAUTHENTICATED_ORIGIN +
window.location.pathname;
} else {
// The deprecation trial is not enabled, as no token is provided for any
// trial.
expect_failure_deprecation();
}
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test Sample API when deprecation trial is disabled (no token)</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/origintrials.js"></script>
<script>
// The deprecation trial is not enabled, as no token is provided for any trial.
expect_failure_deprecation();
</script>
<?php
// TODO(iclelland): Generate this sample token during the build. The token
// below will expire in 2033, but it would be better to always have a token which
// is guaranteed to be valid when the tests are run.
// NOTE: The token must match the UNAUTHENTICATED_ORIGIN used in the test.
// Generate this token with the command:
// generate_token.py http://example.test:8000 FrobulateDeprecation --expire-timestamp=2000000000
header("Origin-Trial: AtHDu5WEwzV/VLWdacwA3ntxuSyMdzBNC0cGuSV5hEPh1EqKt3PUsHW70/R5t3kUO1nlpd4edKHvwoMWeXYg3AoAAABfeyJvcmlnaW4iOiAiaHR0cDovL2V4YW1wbGUudGVzdDo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlRGVwcmVjYXRpb24iLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=");
?>
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test Sample API when deprecation trial is enabled, in insecure context</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/get-host-info.js"></script>
<script src="resources/origintrials.js"></script>
<script>
if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) {
window.location = get_host_info().UNAUTHENTICATED_ORIGIN +
window.location.pathname;
} else {
// The trial is enabled by the token above in the header.
expect_success_deprecation();
}
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test Sample API when deprecation trial is enabled, in insecure context</title>
<!-- TODO(iclelland): Generate this sample token during the build. The token
below will expire in 2033, but it would be better to always have a token which
is guaranteed to be valid when the tests are run. -->
<!-- NOTE: The token must match the UNAUTHENTICATED_ORIGIN used in the test.
Generate this token with the command:
generate_token.py http://example.test:8000 FrobulateDeprecation --expire-timestamp=2000000000
-->
<meta http-equiv="origin-trial"
content="AtHDu5WEwzV/VLWdacwA3ntxuSyMdzBNC0cGuSV5hEPh1EqKt3PUsHW70/R5t3kUO1nlpd4edKHvwoMWeXYg3AoAAABfeyJvcmlnaW4iOiAiaHR0cDovL2V4YW1wbGUudGVzdDo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlRGVwcmVjYXRpb24iLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=" />
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/get-host-info.js"></script>
<script src="resources/origintrials.js"></script>
<script>
if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) {
window.location = get_host_info().UNAUTHENTICATED_ORIGIN +
window.location.pathname;
} else {
// The trial is enabled by the token above in the meta tag.
expect_success_deprecation();
}
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<!-- TODO(iclelland): Generate this sample token during the build. The token
below will expire in 2033, but it would be better to always have a token which
is guaranteed to be valid when the tests are run. -->
<!-- Generate this token with the command:
generate_token.py http://127.0.0.1:8000 FrobulateDeprecation --expire-timestamp=2000000000
-->
<meta http-equiv="origin-trial" content="AvbKrs0bY/tHSwFK2lAKvf1yeXX/iQYYIedyDhtbuTkg9dQc3hJttUa2yP/YY6ojBXSZ6mJnd75H4v+T9YiJIg0AAABceyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlRGVwcmVjYXRpb24iLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=" />
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="resources/origintrials.js"></script>
<script>
// The trial is enabled by the token above in the meta tag.
expect_success_deprecation();
</script>
<?php
// TODO(iclelland): Generate this sample token during the build. The token
// below will expire in 2033, but it would be better to always have a token which
// is guaranteed to be valid when the tests are run.
// NOTE: The token must match the UNAUTHENTICATED_ORIGIN used in the test.
// Generate this token with the command:
// generate_token.py http://example.test:8000 Frobulate -expire-timestamp=2000000000
header("Origin-Trial: AssYG8Dct5/L5padhnjY6g63QMKaEchk64tb7jpY54iNXQdEKSKB5f1w2dR+6sFB1Flxp/xni7S1HOpe8Wh9VwcAAABUeyJvcmlnaW4iOiAiaHR0cDovL2V4YW1wbGUudGVzdDo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9");
?>
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test Sample API when trial is enabled, in insecure context</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/get-host-info.js"></script>
<script src="resources/origintrials.js"></script>
<script>
if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) {
window.location = get_host_info().UNAUTHENTICATED_ORIGIN +
window.location.pathname;
} else {
// The trial is enabled by the token above in the meta tag.
expect_success_bindings_insecure_context();
}
</script>
...@@ -4,10 +4,11 @@ ...@@ -4,10 +4,11 @@
<!-- TODO(iclelland): Generate this sample token during the build. The token <!-- TODO(iclelland): Generate this sample token during the build. The token
below will expire in 2033, but it would be better to always have a token which below will expire in 2033, but it would be better to always have a token which
is guaranteed to be valid when the tests are run. --> is guaranteed to be valid when the tests are run. -->
<!-- Generate this token with the command: <!-- NOTE: The token must match the UNAUTHENTICATED_ORIGIN used in the test.
generate_token.py http://127.0.0.1:8000 Frobulate -expire-timestamp=2000000000 Generate this token with the command:
generate_token.py http://example.test:8000 Frobulate -expire-timestamp=2000000000
--> -->
<meta http-equiv="origin-trial" content="AlCoOPbezqtrGMzSzbLQC4c+oPqO6yuioemcBPjgcXajF8jtmZr4B8tJRPAARPbsX6hDeVyXCKHzEJfpBXvZgQEAAABReyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" /> <meta http-equiv="origin-trial" content="AssYG8Dct5/L5padhnjY6g63QMKaEchk64tb7jpY54iNXQdEKSKB5f1w2dR+6sFB1Flxp/xni7S1HOpe8Wh9VwcAAABUeyJvcmlnaW4iOiAiaHR0cDovL2V4YW1wbGUudGVzdDo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9" />
<script src="../resources/testharness.js"></script> <script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script src="../resources/get-host-info.js"></script> <script src="../resources/get-host-info.js"></script>
......
...@@ -10,9 +10,12 @@ ...@@ -10,9 +10,12 @@
// TODO(iclelland): Generate this sample token during the build. The token // TODO(iclelland): Generate this sample token during the build. The token
// below will expire in 2033, but it would be better to always have a token which // below will expire in 2033, but it would be better to always have a token which
// is guaranteed to be valid when the tests are run. --> // is guaranteed to be valid when the tests are run. -->
// Generate this token with the command: // Generate these tokens with the given commands:
// generate_token.py http://127.0.0.1:8000 Frobulate --expire-timestamp=2000000000 // generate_token.py http://127.0.0.1:8000 Frobulate --expire-timestamp=2000000000
var token = "AlCoOPbezqtrGMzSzbLQC4c+oPqO6yuioemcBPjgcXajF8jtmZr4B8tJRPAARPbsX6hDeVyXCKHzEJfpBXvZgQEAAABReyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9"; var token = "AlCoOPbezqtrGMzSzbLQC4c+oPqO6yuioemcBPjgcXajF8jtmZr4B8tJRPAARPbsX6hDeVyXCKHzEJfpBXvZgQEAAABReyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9";
// generate_token.py http://127.0.0.1:8000 FrobulateDeprecation --expire-timestamp=2000000000
var deprecation_token = "AvbKrs0bY/tHSwFK2lAKvf1yeXX/iQYYIedyDhtbuTkg9dQc3hJttUa2yP/YY6ojBXSZ6mJnd75H4v+T9YiJIg0AAABceyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlRGVwcmVjYXRpb24iLCAiZXhwaXJ5IjogMjAwMDAwMDAwMH0=";
// generate_token.py http://127.0.0.1:8000 FrobulateInvalidOS --expire-timestamp=2000000000
var invalid_os_token = "AtU8M1FWS2TbBCuG6ArIzseD6TBqls4fru1tJp4GyEMrvd+BgE14uWvstXek2Aw+iUjrl6QM5l/HZgpqEssvjgcAAABaeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlSW52YWxpZE9TIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9"; var invalid_os_token = "AtU8M1FWS2TbBCuG6ArIzseD6TBqls4fru1tJp4GyEMrvd+BgE14uWvstXek2Aw+iUjrl6QM5l/HZgpqEssvjgcAAABaeyJvcmlnaW4iOiAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlSW52YWxpZE9TIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB9";
// The trial is not enabled, as no token is provided. // The trial is not enabled, as no token is provided.
...@@ -21,16 +24,20 @@ var invalid_os_token = "AtU8M1FWS2TbBCuG6ArIzseD6TBqls4fru1tJp4GyEMrvd+BgE14uWvs ...@@ -21,16 +24,20 @@ var invalid_os_token = "AtU8M1FWS2TbBCuG6ArIzseD6TBqls4fru1tJp4GyEMrvd+BgE14uWvs
var skip_worker = true; var skip_worker = true;
expect_failure(skip_worker); expect_failure(skip_worker);
expect_failure_bindings(' [disabled]'); expect_failure_bindings(' [disabled]');
expect_failure_deprecation(skip_worker);
expect_failure_implied(skip_worker); expect_failure_implied(skip_worker);
// Add the token to enable the trial // Add the token to enable the trial.
OriginTrialsHelper.add_token(token); OriginTrialsHelper.add_token(token);
// Add the token for the trial with invalid os // Add the token to enable the deprecation trial.
OriginTrialsHelper.add_token(deprecation_token);
// Add the token for the trial with invalid OS.
OriginTrialsHelper.add_token(invalid_os_token); OriginTrialsHelper.add_token(invalid_os_token);
// The trial is now enabled, by the token added via script. // The trial is now enabled, by the token added via script.
expect_success(); expect_success();
expect_success_bindings(); expect_success_bindings();
expect_success_deprecation();
expect_success_implied(); expect_success_implied();
// The trial should not be enabled for |FrobulateInvalidOS| // The trial should not be enabled for |FrobulateInvalidOS|
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment