Commit 02800af8 authored by jessing's avatar jessing Committed by Commit Bot

Reland "[system-web-apps] Add chrome-untrusted iframe to sample system web app"

This is a reland of d4838474

Previously in chromeos/components/sample_system_web_app_ui/BUILD.gn,
the build rule js_library("app") was causing build failures due to a
missing app.js file. This cl fixes the file path for the js files.

Original change's description:
> [system-web-apps] Add chrome-untrusted iframe to sample system web app
>
> An example of how to embed a chrome-untrusted iframe into a system web
> app.
>
> To do so, we need to add abstract methods in WebUI despite WebUIImpl
> being the only class to actually implement it. This is so the
> WebUIController can add requestable schemes so the WebUI can request
> the chrome-untrusted resource.
>
> Bug: 1048951
> Change-Id: Ia3152e21412845cf421df74bb00a16e0a8f264b8
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2037186
> Commit-Queue: Jessica Huang <jessing@google.com>
> Reviewed-by: calamity <calamity@chromium.org>
> Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
> Auto-Submit: Jessica Huang <jessing@google.com>
> Cr-Commit-Position: refs/heads/master@{#742999}

TBR=kinuko@chromium.org

Bug: 1048951
Change-Id: I38307ef0966813426e99e97ecf54403c54124917
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2066404Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarcalamity <calamity@chromium.org>
Commit-Queue: Giovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743414}
parent e396e5a9
......@@ -3,6 +3,7 @@
# found in the LICENSE file.
import("//chrome/test/base/js2gtest.gni")
import("//third_party/closure_compiler/compile_js.gni")
assert(is_chromeos, "Sample System Web App is Chrome OS only")
assert(!is_official_build,
......@@ -24,8 +25,15 @@ static_library("sample_system_web_app_ui") {
]
}
group("closure_compile") {
deps = [ "resources/js:closure_compile" ]
js_type_check("closure_compile") {
deps = [ ":app" ]
}
js_library("app") {
sources = [
"resources/app.js",
"resources/receiver.js",
]
}
js2gtest("browser_tests_js") {
......
......@@ -2,5 +2,6 @@ include_rules = [
# Do not add chrome here (use a delegate instead).
"+chromeos/grit/chromeos_sample_system_web_app_resources.h",
"+content/public/browser",
"+content/public/common",
"+ui/webui",
]
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Untrusted Sample System Web App</title>
<h1 id='untrusted-title'>Sample System Web App</h1>
<script src="receiver.js"></script>
\ No newline at end of file
......@@ -2,5 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var header = document.getElementById('header');
var header = document.getElementById('title');
header.textContent = 'Sample System Web App';
......@@ -4,6 +4,9 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Sample System Web App</title>
<h1 id="header">Sample System Web App</h1>
<header id='title'></header>
<br>
<a href="/sandbox.html"><button>Untrusted</button></a>
<!-- Below mojo script required to run browser tests -->
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
<script src='app.js'></script>
\ No newline at end of file
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/closure_compiler/compile_js.gni")
js_type_check("closure_compile") {
deps = [ ":app" ]
}
js_library("app") {
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var header = document.getElementById('untrusted-title');
header.textContent = 'Untrusted Sample System Web App';
// For testing purposes: notify the parent window the iframe has been embedded
// successfully.
window.addEventListener('message', event => {
if (event.origin.startsWith('chrome://sample-system-web-app')) {
window.parent.postMessage(
{'success': true}, 'chrome://sample-system-web-app');
}
});
\ No newline at end of file
......@@ -12,13 +12,18 @@
</outputs>
<release seq="1">
<includes>
<!-- Privileged app host contents. -->
<if expr="is_official_build == false">
<!-- Privileged app host contents. -->
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML" file="index.html" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_PWA_HTML" file="pwa.html" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_JS" file="js/app.js" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_SANDBOX_HTML" file="sandbox.html" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_JS" file="app.js" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_MANIFEST" file="manifest.json" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_ICON_192" file="app_icon_192.png" type="BINDATA" compress="gzip" />
<!-- Untrusted app contents. -->
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_APP_HTML" file="app.html" type="BINDATA" compress="gzip" />
<include name="IDR_SAMPLE_SYSTEM_WEB_APP_RECEIVER_JS" file="receiver.js" type="BINDATA" compress="gzip" />
</if>
</includes>
</release>
......
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Sample System Web App</title>
<iframe src="chrome-untrusted://sample-system-web-app/app.html"></iframe>
<!-- Below mojo script required to run browser tests -->
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
\ No newline at end of file
......@@ -11,32 +11,56 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/url_constants.h"
namespace chromeos {
content::WebUIDataSource* CreateUntrustedSampleSystemWebAppDataSource() {
content::WebUIDataSource* untrusted_source =
content::WebUIDataSource::Create(kChromeUIUntrustedSampleSystemWebAppURL);
untrusted_source->AddResourcePath("app.html",
IDR_SAMPLE_SYSTEM_WEB_APP_APP_HTML);
untrusted_source->AddResourcePath("receiver.js",
IDR_SAMPLE_SYSTEM_WEB_APP_RECEIVER_JS);
untrusted_source->AddFrameAncestor(GURL(kChromeUISampleSystemWebAppURL));
return untrusted_source;
}
SampleSystemWebAppUI::SampleSystemWebAppUI(content::WebUI* web_ui)
: ui::MojoWebUIController(web_ui) {
auto html_source = base::WrapUnique(
auto trusted_source = base::WrapUnique(
content::WebUIDataSource::Create(kChromeUISampleSystemWebAppHost));
html_source->AddResourcePath("", IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
html_source->AddResourcePath("pwa.html", IDR_SAMPLE_SYSTEM_WEB_APP_PWA_HTML);
html_source->AddResourcePath("app.js", IDR_SAMPLE_SYSTEM_WEB_APP_JS);
html_source->AddResourcePath("manifest.json",
IDR_SAMPLE_SYSTEM_WEB_APP_MANIFEST);
html_source->AddResourcePath("app_icon_192.png",
IDR_SAMPLE_SYSTEM_WEB_APP_ICON_192);
trusted_source->AddResourcePath("", IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
trusted_source->AddResourcePath("pwa.html",
IDR_SAMPLE_SYSTEM_WEB_APP_PWA_HTML);
trusted_source->AddResourcePath("sandbox.html",
IDR_SAMPLE_SYSTEM_WEB_APP_SANDBOX_HTML);
trusted_source->AddResourcePath("app.js", IDR_SAMPLE_SYSTEM_WEB_APP_JS);
trusted_source->AddResourcePath("manifest.json",
IDR_SAMPLE_SYSTEM_WEB_APP_MANIFEST);
trusted_source->AddResourcePath("app_icon_192.png",
IDR_SAMPLE_SYSTEM_WEB_APP_ICON_192);
#if !DCHECK_IS_ON()
// If a user goes to an invalid url and non-DCHECK mode (DHECK = debug mode)
// is set, serve a default page so the user sees your default page instead
// of an unexpected error. But if DCHECK is set, the user will be a
// developer and be able to identify an error occurred.
html_source->SetDefaultResource(IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
trusted_source->SetDefaultResource(IDR_SAMPLE_SYSTEM_WEB_APP_INDEX_HTML);
#endif // !DCHECK_IS_ON()
content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
html_source.release());
// We need a CSP override to use the chrome-untrusted:// scheme in the host.
std::string csp =
std::string("frame-src ") + kChromeUIUntrustedSampleSystemWebAppURL + ";";
trusted_source->OverrideContentSecurityPolicyChildSrc(csp);
auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
content::WebUIDataSource::Add(browser_context, trusted_source.release());
content::WebUIDataSource::Add(browser_context,
CreateUntrustedSampleSystemWebAppDataSource());
// Add ability to request chrome-untrusted: URLs
web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);
}
SampleSystemWebAppUI::~SampleSystemWebAppUI() = default;
......
......@@ -7,6 +7,7 @@
*/
const HOST_ORIGIN = 'chrome://sample-system-web-app';
const UNTRUSTED_HOST_ORIGIN = 'chrome-untrusted://sample-system-web-app';
var SampleSystemWebAppUIBrowserTest = class extends testing.Test {
/** @override */
......@@ -23,8 +24,40 @@ var SampleSystemWebAppUIBrowserTest = class extends testing.Test {
// Tests that chrome://sample-system-web-app runs js file and that it goes
// somewhere instead of 404ing or crashing.
TEST_F('SampleSystemWebAppUIBrowserTest', 'HasChromeSchemeURL', () => {
const header = document.querySelector('h1');
const header = document.querySelector('header');
assertEquals(header.innerText, 'Sample System Web App');
assertEquals(document.location.origin, HOST_ORIGIN);
});
var SampleSystemWebAppUIUntrustedBrowserTest = class extends testing.Test {
/** @override */
get browsePreload() {
return HOST_ORIGIN + '/sandbox.html';
}
/** @override */
get runAccessibilityChecks() {
return false;
}
/** @override */
get isAsync() {
return true;
}
};
// Tests that chrome://sample-system-web-app/sandbox.html embeds a
// chrome-untrusted:// iframe
TEST_F(
'SampleSystemWebAppUIUntrustedBrowserTest', 'HasChromeUntrustedIframe',
() => {
const iframe = document.querySelector('iframe');
window.onmessage =
(event) => {
assertEquals(event.origin, UNTRUSTED_HOST_ORIGIN);
assertEquals(event.data.success, true);
testDone();
};
iframe.contentWindow.postMessage('hello', UNTRUSTED_HOST_ORIGIN);
});
......@@ -8,5 +8,7 @@ namespace chromeos {
const char kChromeUISampleSystemWebAppHost[] = "sample-system-web-app";
const char kChromeUISampleSystemWebAppURL[] = "chrome://sample-system-web-app";
const char kChromeUIUntrustedSampleSystemWebAppURL[] =
"chrome-untrusted://sample-system-web-app/";
} // namespace chromeos
......@@ -9,6 +9,7 @@ namespace chromeos {
extern const char kChromeUISampleSystemWebAppHost[];
extern const char kChromeUISampleSystemWebAppURL[];
extern const char kChromeUIUntrustedSampleSystemWebAppURL[];
} // namespace chromeos
......
......@@ -51,8 +51,8 @@ class CONTENT_EXPORT WebUIImpl : public WebUI,
void OverrideTitle(const base::string16& title) override;
int GetBindings() override;
void SetBindings(int bindings) override;
const std::vector<std::string>& GetRequestableSchemes();
void AddRequestableScheme(const char* scheme);
const std::vector<std::string>& GetRequestableSchemes() override;
void AddRequestableScheme(const char* scheme) override;
void AddMessageHandler(std::unique_ptr<WebUIMessageHandler> handler) override;
void RegisterMessageCallback(base::StringPiece message,
const MessageCallback& callback) override;
......
......@@ -69,6 +69,10 @@ class CONTENT_EXPORT WebUI {
virtual int GetBindings() = 0;
virtual void SetBindings(int bindings) = 0;
// Allows a scheme to be requested which is provided by the WebUIController.
virtual const std::vector<std::string>& GetRequestableSchemes() = 0;
virtual void AddRequestableScheme(const char* scheme) = 0;
virtual void AddMessageHandler(
std::unique_ptr<WebUIMessageHandler> handler) = 0;
......
......@@ -67,6 +67,16 @@ void TestWebUI::SetBindings(int bindings) {
bindings_ = bindings;
}
const std::vector<std::string>& TestWebUI::GetRequestableSchemes() {
NOTIMPLEMENTED();
return std::move(std::vector<std::string>());
}
void TestWebUI::AddRequestableScheme(const char* scheme) {
NOTIMPLEMENTED();
return;
}
void TestWebUI::AddMessageHandler(
std::unique_ptr<WebUIMessageHandler> handler) {
handler->set_web_ui(this);
......
......@@ -37,6 +37,8 @@ class TestWebUI : public WebUI {
void OverrideTitle(const base::string16& title) override {}
int GetBindings() override;
void SetBindings(int bindings) override;
const std::vector<std::string>& GetRequestableSchemes() override;
void AddRequestableScheme(const char* scheme) override;
void AddMessageHandler(std::unique_ptr<WebUIMessageHandler> handler) override;
void RegisterMessageCallback(base::StringPiece message,
const MessageCallback& callback) override;
......
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