From a5190449da29790b1d69b31154c1c7e3f1f2bfed Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 6 Jun 2018 16:05:52 +0800 Subject: [PATCH] Remove UI related settings from CLI (#8783) * Remove all ui reference in dapps interface * Pass primary cli build * Add back parity wallet dapp as builtin * Clean up ui settings * Fix all tests in cli * Missed ui files to commit * Add parity-utils endpoint back * Fix non-dapp feature compiling * Inline styles * Remove parity-utils endpoint * Remove ui precompiled crate * Remove parity-ui alltogether * Remove ui feature flags * Move errors to static methods * Fix tests * Remove all reference to utils endpoint and remove server side injection According to https://github.com/paritytech/parity/pull/8539, inject.js is already handled by Parity UI. --- Cargo.lock | 56 ------- Cargo.toml | 11 +- dapps/Cargo.toml | 6 - dapps/src/apps/fetcher/installers.rs | 8 +- dapps/src/apps/fetcher/mod.rs | 33 ++--- dapps/src/apps/fs.rs | 9 +- dapps/src/apps/mod.rs | 51 +------ dapps/src/apps/ui.rs | 57 ------- dapps/src/error_tpl.html | 83 ++++++++++- dapps/src/handlers/content.rs | 19 +-- dapps/src/handlers/echo.rs | 2 +- dapps/src/handlers/errors.rs | 66 +++++++++ dapps/src/handlers/fetch.rs | 83 +---------- dapps/src/handlers/mod.rs | 46 +----- dapps/src/handlers/streaming.rs | 7 +- dapps/src/lib.rs | 125 +--------------- dapps/src/page/builtin.rs | 21 +-- dapps/src/page/handler.rs | 6 +- dapps/src/page/local.rs | 8 +- dapps/src/proxypac.rs | 11 +- dapps/src/router.rs | 43 +----- dapps/src/tests/fetch.rs | 30 ++-- dapps/src/tests/helpers/mod.rs | 43 +----- dapps/src/tests/home.rs | 62 -------- dapps/src/tests/mod.rs | 2 - dapps/src/tests/redirection.rs | 206 -------------------------- dapps/src/tests/validation.rs | 43 +----- dapps/src/web.rs | 19 +-- dapps/ui-deprecation/Cargo.toml | 18 --- dapps/ui-deprecation/build.rs | 21 --- dapps/ui-deprecation/build/index.html | 119 --------------- dapps/ui-deprecation/src/lib.rs | 21 --- dapps/ui-deprecation/src/lib.rs.in | 55 ------- dapps/ui/Cargo.toml | 20 --- dapps/ui/src/lib.rs | 45 ------ parity/cli/mod.rs | 88 ++++++----- parity/configuration.rs | 196 +----------------------- parity/dapps.rs | 48 ------ parity/lib.rs | 37 +---- parity/rpc.rs | 64 +------- parity/run.rs | 19 +-- parity/signer.rs | 38 ++--- 42 files changed, 306 insertions(+), 1639 deletions(-) delete mode 100644 dapps/src/apps/ui.rs create mode 100644 dapps/src/handlers/errors.rs delete mode 100644 dapps/src/tests/home.rs delete mode 100644 dapps/src/tests/redirection.rs delete mode 100644 dapps/ui-deprecation/Cargo.toml delete mode 100644 dapps/ui-deprecation/build.rs delete mode 100644 dapps/ui-deprecation/build/index.html delete mode 100644 dapps/ui-deprecation/src/lib.rs delete mode 100644 dapps/ui-deprecation/src/lib.rs.in delete mode 100644 dapps/ui/Cargo.toml delete mode 100644 dapps/ui/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a9d9ab7d1..a22012300 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2071,8 +2071,6 @@ dependencies = [ "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-hash-fetch 1.12.0", "parity-reactor 0.1.0", - "parity-ui 1.12.0", - "parity-ui-deprecation 1.10.0", "parity-version 1.12.0", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2283,56 +2281,6 @@ dependencies = [ "tokio-uds 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parity-ui" -version = "1.12.0" -dependencies = [ - "parity-ui-dev 1.9.0 (git+https://github.com/parity-js/shell.git?rev=eecaadcb9e421bce31e91680d14a20bbd38f92a2)", - "parity-ui-old-dev 1.9.0 (git+https://github.com/parity-js/dapp-wallet.git?rev=65deb02e7c007a0fd8aab0c089c93e3fd1de6f87)", - "parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git?rev=4b6f112412716cd05123d32eeb7fda448288a6c6)", - "parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-shell.git?rev=bd25b41cd642c6b822d820dded3aa601a29aa079)", - "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-deprecation" -version = "1.10.0" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-dev" -version = "1.9.0" -source = "git+https://github.com/parity-js/shell.git?rev=eecaadcb9e421bce31e91680d14a20bbd38f92a2#eecaadcb9e421bce31e91680d14a20bbd38f92a2" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-old-dev" -version = "1.9.0" -source = "git+https://github.com/parity-js/dapp-wallet.git?rev=65deb02e7c007a0fd8aab0c089c93e3fd1de6f87#65deb02e7c007a0fd8aab0c089c93e3fd1de6f87" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-old-precompiled" -version = "1.9.0" -source = "git+https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git?rev=4b6f112412716cd05123d32eeb7fda448288a6c6#4b6f112412716cd05123d32eeb7fda448288a6c6" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "parity-ui-precompiled" -version = "1.9.0" -source = "git+https://github.com/js-dist-paritytech/parity-master-1-10-shell.git?rev=bd25b41cd642c6b822d820dded3aa601a29aa079#bd25b41cd642c6b822d820dded3aa601a29aa079" -dependencies = [ - "parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parity-updater" version = "1.12.0" @@ -3970,10 +3918,6 @@ dependencies = [ "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" "checksum parity-dapps-glue 1.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "261c025c67ba416e9fe63aa9b3236520ce3c74cfbe43590c9cdcec4ccc8180e4" "checksum parity-tokio-ipc 0.1.5 (git+https://github.com/nikvolf/parity-tokio-ipc)" = "" -"checksum parity-ui-dev 1.9.0 (git+https://github.com/parity-js/shell.git?rev=eecaadcb9e421bce31e91680d14a20bbd38f92a2)" = "" -"checksum parity-ui-old-dev 1.9.0 (git+https://github.com/parity-js/dapp-wallet.git?rev=65deb02e7c007a0fd8aab0c089c93e3fd1de6f87)" = "" -"checksum parity-ui-old-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git?rev=4b6f112412716cd05123d32eeb7fda448288a6c6)" = "" -"checksum parity-ui-precompiled 1.9.0 (git+https://github.com/js-dist-paritytech/parity-master-1-10-shell.git?rev=bd25b41cd642c6b822d820dded3aa601a29aa079)" = "" "checksum parity-wasm 0.27.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a93ad771f67ce8a6af64c6444a99c07b15f4674203657496fc31244ffb1de2c3" "checksum parity-wordlist 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d0dec124478845b142f68b446cbee953d14d4b41f1bc0425024417720dce693" "checksum parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd9d732f2de194336fb02fe11f9eed13d9e76f13f4315b4d88a14ca411750cd" diff --git a/Cargo.toml b/Cargo.toml index 24649eff4..7795fb3b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,16 +88,7 @@ winapi = { version = "0.3.4", features = ["winsock2", "winuser", "shellapi"] } daemonize = { git = "https://github.com/paritytech/daemonize" } [features] -default = ["ui-precompiled"] -ui = [ - "ui-enabled", - "parity-dapps/ui", -] -ui-precompiled = [ - "ui-enabled", - "parity-dapps/ui-precompiled", -] -ui-enabled = ["dapps"] +default = ["dapps"] dapps = ["parity-dapps"] json-tests = ["ethcore/json-tests"] test-heavy = ["ethcore/test-heavy"] diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index a7ce5a548..c3fd75ddc 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -34,8 +34,6 @@ fetch = { path = "../util/fetch" } node-health = { path = "./node-health" } parity-hash-fetch = { path = "../hash-fetch" } parity-reactor = { path = "../util/reactor" } -parity-ui = { path = "./ui" } -parity-ui-deprecation = { path = "./ui-deprecation" } keccak-hash = { path = "../util/hash" } parity-version = { path = "../util/version" } registrar = { path = "../registrar" } @@ -43,7 +41,3 @@ registrar = { path = "../registrar" } [dev-dependencies] env_logger = "0.4" ethcore-devtools = { path = "../devtools" } - -[features] -ui = ["parity-ui/no-precompiled-js"] -ui-precompiled = ["parity-ui/use-precompiled-js"] diff --git a/dapps/src/apps/fetcher/installers.rs b/dapps/src/apps/fetcher/installers.rs index 99b6be218..9fba80aab 100644 --- a/dapps/src/apps/fetcher/installers.rs +++ b/dapps/src/apps/fetcher/installers.rs @@ -27,7 +27,6 @@ use mime_guess::Mime; use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest, serialize_manifest, Manifest}; use handlers::{ContentValidator, ValidatorResponse}; use page::{local, PageCache}; -use Embeddable; type OnDone = Box) + Send>; @@ -124,17 +123,15 @@ pub struct Dapp { id: String, dapps_path: PathBuf, on_done: OnDone, - embeddable_on: Embeddable, pool: CpuPool, } impl Dapp { - pub fn new(id: String, dapps_path: PathBuf, on_done: OnDone, embeddable_on: Embeddable, pool: CpuPool) -> Self { + pub fn new(id: String, dapps_path: PathBuf, on_done: OnDone, pool: CpuPool) -> Self { Dapp { id, dapps_path, on_done, - embeddable_on, pool, } } @@ -170,7 +167,6 @@ impl ContentValidator for Dapp { fn validate_and_install(self, response: fetch::Response) -> Result { let id = self.id.clone(); let pool = self.pool; - let embeddable_on = self.embeddable_on; let validate = move |dapp_path: PathBuf| { let (file, zip_path) = write_response_and_check_hash(&id, dapp_path.clone(), &format!("{}.zip", id), response)?; trace!(target: "dapps", "Opening dapp bundle at {:?}", zip_path); @@ -210,7 +206,7 @@ impl ContentValidator for Dapp { let mut manifest_file = fs::File::create(manifest_path)?; manifest_file.write_all(manifest_str.as_bytes())?; // Create endpoint - let endpoint = local::Dapp::new(pool, dapp_path, manifest.into(), PageCache::Enabled, embeddable_on); + let endpoint = local::Dapp::new(pool, dapp_path, manifest.into(), PageCache::Enabled); Ok(endpoint) }; diff --git a/dapps/src/apps/fetcher/mod.rs b/dapps/src/apps/fetcher/mod.rs index 78be4f4cb..a7afd91ee 100644 --- a/dapps/src/apps/fetcher/mod.rs +++ b/dapps/src/apps/fetcher/mod.rs @@ -31,7 +31,7 @@ use hash_fetch::urlhint::{URLHintContract, URLHint, URLHintResult}; use hyper::StatusCode; use ethereum_types::H256; -use {Embeddable, SyncStatus, random_filename}; +use {SyncStatus, random_filename}; use parking_lot::Mutex; use page::local; use handlers::{ContentHandler, ContentFetcherHandler}; @@ -50,7 +50,6 @@ pub struct ContentFetcher>, sync: Arc, - embeddable_on: Embeddable, fetch: F, pool: CpuPool, only_content: bool, @@ -78,7 +77,6 @@ impl ContentFetcher { resolver, sync, cache: Arc::new(Mutex::new(ContentCache::default())), - embeddable_on: None, fetch, pool, only_content: true, @@ -90,38 +88,30 @@ impl ContentFetcher { self } - pub fn embeddable_on(mut self, embeddable_on: Embeddable) -> Self { - self.embeddable_on = embeddable_on; - self - } - - fn not_found(embeddable: Embeddable) -> endpoint::Response { + fn not_found() -> endpoint::Response { Box::new(future::ok(ContentHandler::error( StatusCode::NotFound, "Resource Not Found", "Requested resource was not found.", None, - embeddable, ).into())) } - fn still_syncing(embeddable: Embeddable) -> endpoint::Response { + fn still_syncing() -> endpoint::Response { Box::new(future::ok(ContentHandler::error( StatusCode::ServiceUnavailable, "Sync In Progress", "Your node is still syncing. We cannot resolve any content before it's fully synced.", Some("Refresh"), - embeddable, ).into())) } - fn dapps_disabled(address: Embeddable) -> endpoint::Response { + fn dapps_disabled() -> endpoint::Response { Box::new(future::ok(ContentHandler::error( StatusCode::ServiceUnavailable, "Network Dapps Not Available", "This interface doesn't support network dapps for security reasons.", None, - address, ).into())) } @@ -195,10 +185,10 @@ impl Endpoint for ContentFetcher { match content { // Don't serve dapps if we are still syncing (but serve content) Some(URLHintResult::Dapp(_)) if self.sync.is_major_importing() => { - (None, Self::still_syncing(self.embeddable_on.clone())) + (None, Self::still_syncing()) }, Some(URLHintResult::Dapp(_)) if self.only_content => { - (None, Self::dapps_disabled(self.embeddable_on.clone())) + (None, Self::dapps_disabled()) }, Some(content) => { let handler = match content { @@ -211,10 +201,8 @@ impl Endpoint for ContentFetcher { content_id.clone(), self.cache_path.clone(), Box::new(on_done), - self.embeddable_on.clone(), self.pool.clone(), ), - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), ) @@ -228,10 +216,8 @@ impl Endpoint for ContentFetcher { content_id.clone(), self.cache_path.clone(), Box::new(on_done), - self.embeddable_on.clone(), self.pool.clone(), ), - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), ) @@ -248,7 +234,6 @@ impl Endpoint for ContentFetcher { Box::new(on_done), self.pool.clone(), ), - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), ) @@ -258,12 +243,12 @@ impl Endpoint for ContentFetcher { (Some(ContentStatus::Fetching(handler.fetch_control())), Box::new(handler) as endpoint::Response) }, None if self.sync.is_major_importing() => { - (None, Self::still_syncing(self.embeddable_on.clone())) + (None, Self::still_syncing()) }, None => { // This may happen when sync status changes in between // `contains` and `to_handler` - (None, Self::not_found(self.embeddable_on.clone())) + (None, Self::not_found()) }, } }, @@ -330,7 +315,7 @@ mod tests { icon_url: "".into(), local_url: Some("".into()), allow_js_eval: None, - }, Default::default(), None); + }, Default::default()); // when fetcher.set_status("test", ContentStatus::Ready(handler)); diff --git a/dapps/src/apps/fs.rs b/dapps/src/apps/fs.rs index 0139e0ec5..975f3067e 100644 --- a/dapps/src/apps/fs.rs +++ b/dapps/src/apps/fs.rs @@ -24,7 +24,6 @@ use futures_cpupool::CpuPool; use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest}; use endpoint::{Endpoint, EndpointInfo}; use page::{local, PageCache}; -use Embeddable; struct LocalDapp { id: String, @@ -65,14 +64,14 @@ fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo { /// Returns Dapp Id and Local Dapp Endpoint for given filesystem path. /// Parses the path to extract last component (for name). /// `None` is returned when path is invalid or non-existent. -pub fn local_endpoint>(path: P, embeddable: Embeddable, pool: CpuPool) -> Option<(String, Box)> { +pub fn local_endpoint>(path: P, pool: CpuPool) -> Option<(String, Box)> { let path = path.as_ref().to_owned(); path.canonicalize().ok().and_then(|path| { let name = path.file_name().and_then(|name| name.to_str()); name.map(|name| { let dapp = local_dapp(name.into(), path.clone()); (dapp.id, Box::new(local::Dapp::new( - pool.clone(), dapp.path, dapp.info, PageCache::Disabled, embeddable.clone()) + pool.clone(), dapp.path, dapp.info, PageCache::Disabled) )) }) }) @@ -90,12 +89,12 @@ fn local_dapp(name: String, path: PathBuf) -> LocalDapp { /// Returns endpoints for Local Dapps found for given filesystem path. /// Scans the directory and collects `local::Dapp`. -pub fn local_endpoints>(dapps_path: P, embeddable: Embeddable, pool: CpuPool) -> BTreeMap> { +pub fn local_endpoints>(dapps_path: P, pool: CpuPool) -> BTreeMap> { let mut pages = BTreeMap::>::new(); for dapp in local_dapps(dapps_path.as_ref()) { pages.insert( dapp.id, - Box::new(local::Dapp::new(pool.clone(), dapp.path, dapp.info, PageCache::Disabled, embeddable.clone())) + Box::new(local::Dapp::new(pool.clone(), dapp.path, dapp.info, PageCache::Disabled)) ); } pages diff --git a/dapps/src/apps/mod.rs b/dapps/src/apps/mod.rs index 32bd7ee0f..3fe394b6d 100644 --- a/dapps/src/apps/mod.rs +++ b/dapps/src/apps/mod.rs @@ -17,17 +17,15 @@ use std::path::PathBuf; use std::sync::Arc; -use endpoint::{Endpoints, Endpoint}; +use endpoint::Endpoints; use futures_cpupool::CpuPool; -use page; use proxypac::ProxyPac; use web::Web; use fetch::Fetch; -use {WebProxyTokens, ParentFrameSettings}; +use WebProxyTokens; mod app; mod cache; -mod ui; pub mod fs; pub mod fetcher; pub mod manifest; @@ -35,70 +33,37 @@ pub mod manifest; pub use self::app::App; pub const HOME_PAGE: &'static str = "home"; -pub const RPC_PATH: &'static str = "rpc"; -pub const API_PATH: &'static str = "api"; -pub const UTILS_PATH: &'static str = "parity-utils"; +pub const RPC_PATH: &'static str = "rpc"; +pub const API_PATH: &'static str = "api"; pub const WEB_PATH: &'static str = "web"; pub const URL_REFERER: &'static str = "__referer="; -pub fn utils(pool: CpuPool) -> Box { - Box::new(page::builtin::Dapp::new(pool, ::parity_ui::App::default())) -} - -pub fn ui(pool: CpuPool) -> Box { - Box::new(page::builtin::Dapp::with_fallback_to_index(pool, ::parity_ui::App::default())) -} - -pub fn ui_deprecation(pool: CpuPool) -> Box { - Box::new(page::builtin::Dapp::with_fallback_to_index(pool, ::parity_ui_deprecation::App::default())) -} - -pub fn ui_redirection(embeddable: Option) -> Box { - Box::new(ui::Redirection::new(embeddable)) -} - pub fn all_endpoints( dapps_path: PathBuf, extra_dapps: Vec, dapps_domain: &str, - embeddable: Option, web_proxy_tokens: Arc, fetch: F, pool: CpuPool, ) -> (Vec, Endpoints) { // fetch fs dapps at first to avoid overwriting builtins - let mut pages = fs::local_endpoints(dapps_path.clone(), embeddable.clone(), pool.clone()); + let mut pages = fs::local_endpoints(dapps_path.clone(), pool.clone()); let local_endpoints: Vec = pages.keys().cloned().collect(); for path in extra_dapps { - if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), embeddable.clone(), pool.clone()) { + if let Some((id, endpoint)) = fs::local_endpoint(path.clone(), pool.clone()) { pages.insert(id, endpoint); } else { warn!(target: "dapps", "Ignoring invalid dapp at {}", path.display()); } } - // NOTE [ToDr] Dapps will be currently embeded on 8180 - pages.insert( - "ui".into(), - Box::new(page::builtin::Dapp::new_safe_to_embed(pool.clone(), ::parity_ui::App::default(), embeddable.clone())) - ); - // old version - pages.insert( - "v1".into(), - Box::new({ - let mut page = page::builtin::Dapp::new_safe_to_embed(pool.clone(), ::parity_ui::old::App::default(), embeddable.clone()); - // allow JS eval on old Wallet - page.allow_js_eval(); - page - }) - ); pages.insert( "proxy".into(), - ProxyPac::boxed(embeddable.clone(), dapps_domain.to_owned()) + ProxyPac::boxed(dapps_domain.to_owned()) ); pages.insert( WEB_PATH.into(), - Web::boxed(embeddable.clone(), web_proxy_tokens.clone(), fetch.clone(), pool.clone()) + Web::boxed(web_proxy_tokens.clone(), fetch.clone(), pool.clone()) ); (local_endpoints, pages) diff --git a/dapps/src/apps/ui.rs b/dapps/src/apps/ui.rs deleted file mode 100644 index 696ed2523..000000000 --- a/dapps/src/apps/ui.rs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -//! UI redirections - -use hyper::StatusCode; -use futures::future; - -use endpoint::{Endpoint, Request, Response, EndpointPath}; -use {handlers, Embeddable}; - -/// Redirection to UI server. -pub struct Redirection { - embeddable_on: Embeddable, -} - -impl Redirection { - pub fn new( - embeddable_on: Embeddable, - ) -> Self { - Redirection { - embeddable_on, - } - } -} - -impl Endpoint for Redirection { - fn respond(&self, _path: EndpointPath, req: Request) -> Response { - Box::new(future::ok(if let Some(ref frame) = self.embeddable_on { - trace!(target: "dapps", "Redirecting to signer interface."); - let protocol = req.uri().scheme().unwrap_or("http"); - handlers::Redirection::new(format!("{}://{}:{}", protocol, &frame.host, frame.port)).into() - } else { - trace!(target: "dapps", "Signer disabled, returning 404."); - handlers::ContentHandler::error( - StatusCode::NotFound, - "404 Not Found", - "Your homepage is not available when Trusted Signer is disabled.", - Some("You can still access dapps by writing a correct address, though. Re-enable Signer to get your homepage back."), - None, - ).into() - })) - } -} diff --git a/dapps/src/error_tpl.html b/dapps/src/error_tpl.html index c6b4db0e7..4b155cf35 100644 --- a/dapps/src/error_tpl.html +++ b/dapps/src/error_tpl.html @@ -4,7 +4,88 @@ {title} - +
diff --git a/dapps/src/handlers/content.rs b/dapps/src/handlers/content.rs index ec4d4f2ef..9449f0f79 100644 --- a/dapps/src/handlers/content.rs +++ b/dapps/src/handlers/content.rs @@ -22,14 +22,12 @@ use hyper::StatusCode; use parity_version::version; use handlers::add_security_headers; -use Embeddable; #[derive(Debug, Clone)] pub struct ContentHandler { code: StatusCode, content: String, mimetype: mime::Mime, - safe_to_embed_on: Embeddable, } impl ContentHandler { @@ -37,8 +35,8 @@ impl ContentHandler { Self::new(StatusCode::Ok, content, mimetype) } - pub fn html(code: StatusCode, content: String, embeddable_on: Embeddable) -> Self { - Self::new_embeddable(code, content, mime::TEXT_HTML, embeddable_on) + pub fn html(code: StatusCode, content: String) -> Self { + Self::new(code, content, mime::TEXT_HTML) } pub fn error( @@ -46,7 +44,6 @@ impl ContentHandler { title: &str, message: &str, details: Option<&str>, - embeddable_on: Embeddable, ) -> Self { Self::html(code, format!( include_str!("../error_tpl.html"), @@ -54,24 +51,18 @@ impl ContentHandler { message=message, details=details.unwrap_or_else(|| ""), version=version(), - ), embeddable_on) + )) } - pub fn new(code: StatusCode, content: String, mimetype: mime::Mime) -> Self { - Self::new_embeddable(code, content, mimetype, None) - } - - pub fn new_embeddable( + pub fn new( code: StatusCode, content: String, mimetype: mime::Mime, - safe_to_embed_on: Embeddable, ) -> Self { ContentHandler { code, content, mimetype, - safe_to_embed_on, } } } @@ -82,7 +73,7 @@ impl Into for ContentHandler { .with_status(self.code) .with_header(header::ContentType(self.mimetype)) .with_body(self.content); - add_security_headers(&mut res.headers_mut(), self.safe_to_embed_on, false); + add_security_headers(&mut res.headers_mut(), false); res } } diff --git a/dapps/src/handlers/echo.rs b/dapps/src/handlers/echo.rs index d7484b6d1..03dfd1c97 100644 --- a/dapps/src/handlers/echo.rs +++ b/dapps/src/handlers/echo.rs @@ -40,7 +40,7 @@ impl Into for EchoHandler { .with_header(content_type.unwrap_or(header::ContentType::json())) .with_body(self.request.body()); - add_security_headers(res.headers_mut(), None, false); + add_security_headers(res.headers_mut(), false); res } } diff --git a/dapps/src/handlers/errors.rs b/dapps/src/handlers/errors.rs new file mode 100644 index 000000000..5261dc3c1 --- /dev/null +++ b/dapps/src/handlers/errors.rs @@ -0,0 +1,66 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +//! Handler errors. + +use handlers::{ContentHandler, FETCH_TIMEOUT}; +use hyper::StatusCode; +use std::fmt; + +pub fn streaming() -> ContentHandler { + ContentHandler::error( + StatusCode::BadGateway, + "Streaming Error", + "This content is being streamed in other place.", + None, + ) +} + +pub fn download_error(e: E) -> ContentHandler { + ContentHandler::error( + StatusCode::BadGateway, + "Download Error", + "There was an error when fetching the content.", + Some(&format!("{:?}", e)), + ) +} + +pub fn invalid_content(e: E) -> ContentHandler { + ContentHandler::error( + StatusCode::BadGateway, + "Invalid Dapp", + "Downloaded bundle does not contain a valid content.", + Some(&format!("{:?}", e)), + ) +} + +pub fn timeout_error() -> ContentHandler { + ContentHandler::error( + StatusCode::GatewayTimeout, + "Download Timeout", + &format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT.as_secs()), + None, + ) +} + +pub fn method_not_allowed() -> ContentHandler { + ContentHandler::error( + StatusCode::MethodNotAllowed, + "Method Not Allowed", + "Only GET requests are allowed.", + None, + ) +} diff --git a/dapps/src/handlers/fetch.rs b/dapps/src/handlers/fetch.rs index 860fe998c..3fee3b1fe 100644 --- a/dapps/src/handlers/fetch.rs +++ b/dapps/src/handlers/fetch.rs @@ -19,20 +19,17 @@ use std::{fmt, mem}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; -use std::time::{Instant, Duration}; +use std::time::Instant; use fetch::{self, Fetch}; use futures::sync::oneshot; use futures::{self, Future}; use futures_cpupool::CpuPool; -use hyper::{self, StatusCode}; +use hyper; use parking_lot::Mutex; use endpoint::{self, EndpointPath}; -use handlers::{ContentHandler, StreamingHandler}; +use handlers::{ContentHandler, StreamingHandler, FETCH_TIMEOUT, errors}; use page::local; -use {Embeddable}; - -const FETCH_TIMEOUT: Duration = Duration::from_secs(300); pub enum ValidatorResponse { Local(local::Dapp), @@ -134,8 +131,7 @@ impl Future for WaitingHandler { return Ok(futures::Async::Ready(handler.into())); }, WaitResult::NonAwaitable => { - let errors = Errors { embeddable_on: None }; - return Ok(futures::Async::Ready(errors.streaming().into())); + return Ok(futures::Async::Ready(errors::streaming().into())); }, WaitResult::Done(endpoint) => { WaitState::Done(endpoint.to_response(&self.path).into()) @@ -152,63 +148,6 @@ impl Future for WaitingHandler { } } -#[derive(Debug, Clone)] -struct Errors { - embeddable_on: Embeddable, -} - -impl Errors { - fn streaming(&self) -> ContentHandler { - ContentHandler::error( - StatusCode::BadGateway, - "Streaming Error", - "This content is being streamed in other place.", - None, - self.embeddable_on.clone(), - ) - } - - fn download_error(&self, e: E) -> ContentHandler { - ContentHandler::error( - StatusCode::BadGateway, - "Download Error", - "There was an error when fetching the content.", - Some(&format!("{:?}", e)), - self.embeddable_on.clone(), - ) - } - - fn invalid_content(&self, e: E) -> ContentHandler { - ContentHandler::error( - StatusCode::BadGateway, - "Invalid Dapp", - "Downloaded bundle does not contain a valid content.", - Some(&format!("{:?}", e)), - self.embeddable_on.clone(), - ) - } - - fn timeout_error(&self) -> ContentHandler { - ContentHandler::error( - StatusCode::GatewayTimeout, - "Download Timeout", - &format!("Could not fetch content within {} seconds.", FETCH_TIMEOUT.as_secs()), - None, - self.embeddable_on.clone(), - ) - } - - fn method_not_allowed(&self) -> ContentHandler { - ContentHandler::error( - StatusCode::MethodNotAllowed, - "Method Not Allowed", - "Only GET requests are allowed.", - None, - self.embeddable_on.clone(), - ) - } -} - enum FetchState { Error(ContentHandler), InProgress(Box + Send>), @@ -237,7 +176,6 @@ impl fmt::Debug for FetchState { pub struct ContentFetcherHandler { fetch_control: FetchControl, status: FetchState, - errors: Errors, } impl ContentFetcherHandler { @@ -250,12 +188,10 @@ impl ContentFetcherHandler { url: &str, path: EndpointPath, installer: H, - embeddable_on: Embeddable, fetch: F, pool: CpuPool, ) -> Self { let fetch_control = FetchControl::default(); - let errors = Errors { embeddable_on }; // Validation of method let status = match *method { @@ -268,18 +204,16 @@ impl ContentFetcherHandler { url, fetch_control.abort.clone(), path, - errors.clone(), installer, )) }, // or return error - _ => FetchState::Error(errors.method_not_allowed()), + _ => FetchState::Error(errors::method_not_allowed()), }; ContentFetcherHandler { fetch_control, status, - errors, } } @@ -289,7 +223,6 @@ impl ContentFetcherHandler { url: &str, abort: Arc, path: EndpointPath, - errors: Errors, installer: H, ) -> Box + Send> { // Start fetching the content @@ -311,12 +244,12 @@ impl ContentFetcherHandler { }, Err(e) => { trace!(target: "dapps", "Error while validating content: {:?}", e); - FetchState::Error(errors.invalid_content(e)) + FetchState::Error(errors::invalid_content(e)) }, }, Err(e) => { warn!(target: "dapps", "Unable to fetch content: {:?}", e); - FetchState::Error(errors.download_error(e)) + FetchState::Error(errors::download_error(e)) }, }) }); @@ -347,7 +280,7 @@ impl Future for ContentFetcherHandler { // Request may time out FetchState::InProgress(_) if self.fetch_control.is_deadline_reached() => { trace!(target: "dapps", "Fetching dapp failed because of timeout."); - FetchState::Error(self.errors.timeout_error()) + FetchState::Error(errors::timeout_error()) }, FetchState::InProgress(ref mut receiver) => { // Check if there is a response diff --git a/dapps/src/handlers/mod.rs b/dapps/src/handlers/mod.rs index fad9c4041..cb0eba042 100644 --- a/dapps/src/handlers/mod.rs +++ b/dapps/src/handlers/mod.rs @@ -22,6 +22,7 @@ mod fetch; mod reader; mod redirect; mod streaming; +mod errors; pub use self::content::ContentHandler; pub use self::echo::EchoHandler; @@ -30,20 +31,16 @@ pub use self::reader::Reader; pub use self::redirect::Redirection; pub use self::streaming::StreamingHandler; -use std::iter; -use itertools::Itertools; use hyper::header; -use {apps, address, Embeddable}; +use std::time::Duration; + +const FETCH_TIMEOUT: Duration = Duration::from_secs(300); /// Adds security-related headers to the Response. -pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embeddable, allow_js_eval: bool) { +pub fn add_security_headers(headers: &mut header::Headers, allow_js_eval: bool) { headers.set_raw("X-XSS-Protection", "1; mode=block"); headers.set_raw("X-Content-Type-Options", "nosniff"); - - // Embedding header: - if let None = embeddable_on { - headers.set_raw("X-Frame-Options", "SAMEORIGIN"); - } + headers.set_raw("X-Frame-Options", "SAMEORIGIN"); // Content Security Policy headers headers.set_raw("Content-Security-Policy", String::new() @@ -70,11 +67,7 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd + "object-src 'none';" // Allow scripts + { - let script_src = embeddable_on.as_ref() - .map(|e| e.extra_script_src.iter() - .map(|&(ref host, port)| address(host, port)) - .join(" ") - ).unwrap_or_default(); + let script_src = ""; let eval = if allow_js_eval { " 'unsafe-eval'" } else { "" }; &format!( @@ -93,29 +86,6 @@ pub fn add_security_headers(headers: &mut header::Headers, embeddable_on: Embedd // Never allow mixed content + "block-all-mixed-content;" // Specify if the site can be embedded. - + &match embeddable_on { - Some(ref embed) => { - let std = address(&embed.host, embed.port); - let proxy = format!("{}.{}", apps::HOME_PAGE, embed.dapps_domain); - let domain = format!("*.{}:{}", embed.dapps_domain, embed.port); - - let mut ancestors = vec![std, domain, proxy] - .into_iter() - .chain(embed.extra_embed_on - .iter() - .map(|&(ref host, port)| address(host, port)) - ); - - let ancestors = if embed.host == "127.0.0.1" { - let localhost = address("localhost", embed.port); - ancestors.chain(iter::once(localhost)).join(" ") - } else { - ancestors.join(" ") - }; - - format!("frame-ancestors {};", ancestors) - }, - None => format!("frame-ancestors 'self';"), - } + + "frame-ancestors 'self';" ); } diff --git a/dapps/src/handlers/streaming.rs b/dapps/src/handlers/streaming.rs index 4dfd2c4af..b6feaa638 100644 --- a/dapps/src/handlers/streaming.rs +++ b/dapps/src/handlers/streaming.rs @@ -20,24 +20,21 @@ use std::io; use hyper::{self, header, mime, StatusCode}; use handlers::{add_security_headers, Reader}; -use Embeddable; pub struct StreamingHandler { initial: Vec, content: R, status: StatusCode, mimetype: mime::Mime, - safe_to_embed_on: Embeddable, } impl StreamingHandler { - pub fn new(content: R, status: StatusCode, mimetype: mime::Mime, safe_to_embed_on: Embeddable) -> Self { + pub fn new(content: R, status: StatusCode, mimetype: mime::Mime) -> Self { StreamingHandler { initial: Vec::new(), content, status, mimetype, - safe_to_embed_on, } } @@ -51,7 +48,7 @@ impl StreamingHandler { .with_status(self.status) .with_header(header::ContentType(self.mimetype)) .with_body(body); - add_security_headers(&mut res.headers_mut(), self.safe_to_embed_on, false); + add_security_headers(&mut res.headers_mut(), false); (reader, res) } diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index 255560e42..12a6a8050 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -38,8 +38,6 @@ extern crate fetch; extern crate node_health; extern crate parity_dapps_glue as parity_dapps; extern crate parity_hash_fetch as hash_fetch; -extern crate parity_ui; -extern crate parity_ui_deprecation; extern crate keccak_hash as hash; extern crate parity_version; extern crate registrar; @@ -84,6 +82,7 @@ use node_health::NodeHealth; pub use registrar::{RegistrarClient, Asynchronous}; pub use node_health::SyncStatus; +pub use page::builtin::Dapp; /// Validates Web Proxy tokens pub trait WebProxyTokens: Send + Sync { @@ -101,7 +100,6 @@ pub struct Endpoints { local_endpoints: Arc>>, endpoints: Arc>, dapps_path: PathBuf, - embeddable: Option, pool: Option, } @@ -119,7 +117,7 @@ impl Endpoints { None => return, Some(pool) => pool, }; - let new_local = apps::fs::local_endpoints(&self.dapps_path, self.embeddable.clone(), pool.clone()); + let new_local = apps::fs::local_endpoints(&self.dapps_path, pool.clone()); let old_local = mem::replace(&mut *self.local_endpoints.write(), new_local.keys().cloned().collect()); let (_, to_remove): (_, Vec<_>) = old_local .into_iter() @@ -151,69 +149,10 @@ impl Middleware { &self.endpoints } - /// Creates new middleware for UI server. - pub fn ui( - pool: CpuPool, - health: NodeHealth, - dapps_domain: &str, - registrar: Arc>, - sync_status: Arc, - fetch: F, - info_page_only: bool, - ) -> Self { - let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new( - hash_fetch::urlhint::URLHintContract::new(registrar), - sync_status.clone(), - fetch.clone(), - pool.clone(), - ).embeddable_on(None).allow_dapps(false)); - - if info_page_only { - let mut special = HashMap::default(); - special.insert(router::SpecialEndpoint::Home, Some(apps::ui_deprecation(pool.clone()))); - - return Middleware { - endpoints: Default::default(), - router: router::Router::new( - content_fetcher, - None, - special, - None, - dapps_domain.to_owned(), - ), - } - } - - let special = { - let mut special = special_endpoints( - pool.clone(), - health, - content_fetcher.clone(), - ); - special.insert(router::SpecialEndpoint::Home, Some(apps::ui(pool.clone()))); - special - }; - let router = router::Router::new( - content_fetcher, - None, - special, - None, - dapps_domain.to_owned(), - ); - - Middleware { - endpoints: Default::default(), - router: router, - } - } - /// Creates new Dapps server middleware. pub fn dapps( pool: CpuPool, health: NodeHealth, - ui_address: Option<(String, u16)>, - extra_embed_on: Vec<(String, u16)>, - extra_script_src: Vec<(String, u16)>, dapps_path: PathBuf, extra_dapps: Vec, dapps_domain: &str, @@ -222,18 +161,16 @@ impl Middleware { web_proxy_tokens: Arc, fetch: F, ) -> Self { - let embeddable = as_embeddable(ui_address, extra_embed_on, extra_script_src, dapps_domain); let content_fetcher = Arc::new(apps::fetcher::ContentFetcher::new( hash_fetch::urlhint::URLHintContract::new(registrar), sync_status.clone(), fetch.clone(), pool.clone(), - ).embeddable_on(embeddable.clone()).allow_dapps(true)); + ).allow_dapps(true)); let (local_endpoints, endpoints) = apps::all_endpoints( dapps_path.clone(), extra_dapps, dapps_domain, - embeddable.clone(), web_proxy_tokens, fetch.clone(), pool.clone(), @@ -242,28 +179,18 @@ impl Middleware { endpoints: Arc::new(RwLock::new(endpoints)), dapps_path, local_endpoints: Arc::new(RwLock::new(local_endpoints)), - embeddable: embeddable.clone(), pool: Some(pool.clone()), }; - let special = { - let mut special = special_endpoints( - pool.clone(), - health, - content_fetcher.clone(), - ); - special.insert( - router::SpecialEndpoint::Home, - Some(apps::ui_redirection(embeddable.clone())), - ); - special - }; + let special = special_endpoints( + health, + content_fetcher.clone(), + ); let router = router::Router::new( content_fetcher, Some(endpoints.clone()), special, - embeddable, dapps_domain.to_owned(), ); @@ -281,13 +208,11 @@ impl http::RequestMiddleware for Middleware { } fn special_endpoints( - pool: CpuPool, health: NodeHealth, content_fetcher: Arc, ) -> HashMap>> { let mut special = HashMap::new(); special.insert(router::SpecialEndpoint::Rpc, None); - special.insert(router::SpecialEndpoint::Utils, Some(apps::utils(pool))); special.insert(router::SpecialEndpoint::Api, Some(api::RestApi::new( content_fetcher, health, @@ -295,45 +220,9 @@ fn special_endpoints( special } -fn address(host: &str, port: u16) -> String { - format!("{}:{}", host, port) -} - -fn as_embeddable( - ui_address: Option<(String, u16)>, - extra_embed_on: Vec<(String, u16)>, - extra_script_src: Vec<(String, u16)>, - dapps_domain: &str, -) -> Option { - ui_address.map(|(host, port)| ParentFrameSettings { - host, - port, - extra_embed_on, - extra_script_src, - dapps_domain: dapps_domain.to_owned(), - }) -} - /// Random filename fn random_filename() -> String { use ::rand::Rng; let mut rng = ::rand::OsRng::new().unwrap(); rng.gen_ascii_chars().take(12).collect() } - -type Embeddable = Option; - -/// Parent frame host and port allowed to embed the content. -#[derive(Debug, Clone)] -pub struct ParentFrameSettings { - /// Hostname - pub host: String, - /// Port - pub port: u16, - /// Additional URLs the dapps can be embedded on. - pub extra_embed_on: Vec<(String, u16)>, - /// Additional URLs the dapp scripts can be loaded from. - pub extra_script_src: Vec<(String, u16)>, - /// Dapps Domain (web3.site) - pub dapps_domain: String, -} diff --git a/dapps/src/page/builtin.rs b/dapps/src/page/builtin.rs index b9f2fcdac..685b1401d 100644 --- a/dapps/src/page/builtin.rs +++ b/dapps/src/page/builtin.rs @@ -23,15 +23,13 @@ use parity_dapps::{WebApp, Info}; use endpoint::{Endpoint, EndpointInfo, EndpointPath, Request, Response}; use page::{handler, PageCache}; -use Embeddable; +/// Represents a builtin Dapp. pub struct Dapp { /// futures cpu pool pool: CpuPool, /// Content of the files app: T, - /// Safe to be loaded in frame by other origin. (use wisely!) - safe_to_embed_on: Embeddable, info: EndpointInfo, fallback_to_index_html: bool, } @@ -43,7 +41,6 @@ impl Dapp { Dapp { pool, app, - safe_to_embed_on: None, info: EndpointInfo::from(info), fallback_to_index_html: false, } @@ -56,26 +53,11 @@ impl Dapp { Dapp { pool, app, - safe_to_embed_on: None, info: EndpointInfo::from(info), fallback_to_index_html: true, } } - /// Creates new `Dapp` which can be safely used in iframe - /// even from different origin. It might be dangerous (clickjacking). - /// Use wisely! - pub fn new_safe_to_embed(pool: CpuPool, app: T, address: Embeddable) -> Self { - let info = app.info(); - Dapp { - pool, - app, - safe_to_embed_on: address, - info: EndpointInfo::from(info), - fallback_to_index_html: false, - } - } - /// Allow the dapp to use `unsafe-eval` to run JS. pub fn allow_js_eval(&mut self) { self.info.allow_js_eval = Some(true); @@ -121,7 +103,6 @@ impl Endpoint for Dapp { let (reader, response) = handler::PageHandler { file, cache: PageCache::Disabled, - safe_to_embed_on: self.safe_to_embed_on.clone(), allow_js_eval: self.info.allow_js_eval.clone().unwrap_or(false), }.into_response(); diff --git a/dapps/src/page/handler.rs b/dapps/src/page/handler.rs index 15e2b10c5..d7fcefa7f 100644 --- a/dapps/src/page/handler.rs +++ b/dapps/src/page/handler.rs @@ -20,7 +20,6 @@ use hyper::{self, header, StatusCode}; use hyper::mime::{Mime}; use handlers::{Reader, ContentHandler, add_security_headers}; -use {Embeddable}; /// Represents a file that can be sent to client. /// Implementation should keep track of bytes already sent internally. @@ -54,8 +53,6 @@ impl Default for PageCache { pub struct PageHandler { /// File currently being served pub file: Option, - /// Flag indicating if the file can be safely embeded (put in iframe). - pub safe_to_embed_on: Embeddable, /// Cache settings for this page. pub cache: PageCache, /// Allow JS unsafe-eval. @@ -70,7 +67,6 @@ impl PageHandler { "File not found", "Requested file has not been found.", None, - self.safe_to_embed_on, ).into()), Some(file) => file, }; @@ -94,7 +90,7 @@ impl PageHandler { headers.set(header::ContentType(file.content_type().to_owned())); - add_security_headers(&mut headers, self.safe_to_embed_on, self.allow_js_eval); + add_security_headers(&mut headers, self.allow_js_eval); } let (reader, body) = Reader::pair(file.into_reader(), Vec::new()); diff --git a/dapps/src/page/local.rs b/dapps/src/page/local.rs index f30af4523..a43735d76 100644 --- a/dapps/src/page/local.rs +++ b/dapps/src/page/local.rs @@ -22,7 +22,6 @@ use futures_cpupool::CpuPool; use page::handler::{self, PageCache}; use endpoint::{Endpoint, EndpointInfo, EndpointPath, Request, Response}; use hyper::mime::Mime; -use Embeddable; #[derive(Clone)] pub struct Dapp { @@ -31,7 +30,6 @@ pub struct Dapp { mime: Option, info: Option, cache: PageCache, - embeddable_on: Embeddable, } impl fmt::Debug for Dapp { @@ -41,20 +39,18 @@ impl fmt::Debug for Dapp { .field("mime", &self.mime) .field("info", &self.info) .field("cache", &self.cache) - .field("embeddable_on", &self.embeddable_on) .finish() } } impl Dapp { - pub fn new(pool: CpuPool, path: PathBuf, info: EndpointInfo, cache: PageCache, embeddable_on: Embeddable) -> Self { + pub fn new(pool: CpuPool, path: PathBuf, info: EndpointInfo, cache: PageCache) -> Self { Dapp { pool, path, mime: None, info: Some(info), cache, - embeddable_on, } } @@ -65,7 +61,6 @@ impl Dapp { mime: Some(mime), info: None, cache, - embeddable_on: None, } } @@ -96,7 +91,6 @@ impl Dapp { let (reader, response) = handler::PageHandler { file: self.get_file(path), cache: self.cache, - safe_to_embed_on: self.embeddable_on.clone(), allow_js_eval: self.info.as_ref().and_then(|x| x.allow_js_eval).unwrap_or(false), }.into_response(); diff --git a/dapps/src/proxypac.rs b/dapps/src/proxypac.rs index 4e11f3ea6..1acd7b1b9 100644 --- a/dapps/src/proxypac.rs +++ b/dapps/src/proxypac.rs @@ -21,25 +21,20 @@ use endpoint::{Endpoint, Request, Response, EndpointPath}; use futures::future; use handlers::ContentHandler; use hyper::mime; -use {address, Embeddable}; pub struct ProxyPac { - embeddable: Embeddable, dapps_domain: String, } impl ProxyPac { - pub fn boxed(embeddable: Embeddable, dapps_domain: String) -> Box { - Box::new(ProxyPac { embeddable, dapps_domain }) + pub fn boxed(dapps_domain: String) -> Box { + Box::new(ProxyPac { dapps_domain }) } } impl Endpoint for ProxyPac { fn respond(&self, path: EndpointPath, _req: Request) -> Response { - let ui = self.embeddable - .as_ref() - .map(|ref parent| address(&parent.host, parent.port)) - .unwrap_or_else(|| format!("{}:{}", path.host, path.port)); + let ui = format!("{}:{}", path.host, path.port); let content = format!( r#" diff --git a/dapps/src/router.rs b/dapps/src/router.rs index 565874f6a..28a3e24c3 100644 --- a/dapps/src/router.rs +++ b/dapps/src/router.rs @@ -29,14 +29,12 @@ use apps::fetcher::Fetcher; use endpoint::{self, Endpoint, EndpointPath}; use Endpoints; use handlers; -use Embeddable; /// Special endpoints are accessible on every domain (every dapp) #[derive(Debug, PartialEq, Hash, Eq)] pub enum SpecialEndpoint { Rpc, Api, - Utils, Home, None, } @@ -52,16 +50,14 @@ pub struct Router { endpoints: Option, fetch: Arc, special: HashMap>>, - embeddable_on: Embeddable, dapps_domain: String, } impl Router { - fn resolve_request(&self, req: hyper::Request, refresh_dapps: bool) -> (bool, Response) { + fn resolve_request(&self, req: hyper::Request, refresh_dapps: bool) -> Response { // Choose proper handler depending on path / domain let endpoint = extract_endpoint(req.uri(), req.headers().get(), &self.dapps_domain); let referer = extract_referer_endpoint(&req, &self.dapps_domain); - let is_utils = endpoint.1 == SpecialEndpoint::Utils; let is_get_request = *req.method() == hyper::Method::Get; let is_head_request = *req.method() == hyper::Method::Head; let has_dapp = |dapp: &str| self.endpoints @@ -71,7 +67,7 @@ impl Router { trace!(target: "dapps", "Routing request to {:?}. Details: {:?}", req.uri(), req); debug!(target: "dapps", "Handling endpoint request: {:?}, referer: {:?}", endpoint, referer); - (is_utils, match (endpoint.0, endpoint.1, referer) { + match (endpoint.0, endpoint.1, referer) { // Handle invalid web requests that we can recover from (ref path, SpecialEndpoint::None, Some(ref referer)) if referer.app_id == apps::WEB_PATH @@ -132,7 +128,6 @@ impl Router { "404 Not Found", "Requested content was not found.", None, - self.embeddable_on.clone(), ).into()))) } }, @@ -161,20 +156,19 @@ impl Router { "404 Not Found", "Requested content was not found.", None, - self.embeddable_on.clone(), ).into()))) }, - }) + } } } impl http::RequestMiddleware for Router { fn on_request(&self, req: hyper::Request) -> http::RequestMiddlewareAction { let is_origin_set = req.headers().get::().is_some(); - let (is_utils, response) = self.resolve_request(req, self.endpoints.is_some()); + let response = self.resolve_request(req, self.endpoints.is_some()); match response { Response::Some(response) => http::RequestMiddlewareAction::Respond { - should_validate_hosts: !is_utils, + should_validate_hosts: true, response, }, Response::None(request) => http::RequestMiddlewareAction::Proceed { @@ -190,14 +184,12 @@ impl Router { content_fetcher: Arc, endpoints: Option, special: HashMap>>, - embeddable_on: Embeddable, dapps_domain: String, ) -> Self { Router { endpoints: endpoints, fetch: content_fetcher, special: special, - embeddable_on: embeddable_on, dapps_domain: format!(".{}", dapps_domain), } } @@ -250,7 +242,6 @@ fn extract_endpoint(url: &Uri, extra_host: Option<&header::Host>, dapps_domain: match path[0].as_ref() { apps::RPC_PATH => SpecialEndpoint::Rpc, apps::API_PATH => SpecialEndpoint::Api, - apps::UTILS_PATH => SpecialEndpoint::Utils, apps::HOME_PAGE => SpecialEndpoint::Home, _ => SpecialEndpoint::None, } @@ -351,30 +342,6 @@ mod tests { }), SpecialEndpoint::Rpc) ); - assert_eq!( - extract_endpoint(&"http://my.status.web3.site/parity-utils/inject.js".parse().unwrap(), None, dapps_domain), - (Some(EndpointPath { - app_id: "status".to_owned(), - app_params: vec!["my".into(), "inject.js".into()], - query: None, - host: "my.status.web3.site".to_owned(), - port: 80, - using_dapps_domains: true, - }), SpecialEndpoint::Utils) - ); - - assert_eq!( - extract_endpoint(&"http://my.status.web3.site/inject.js".parse().unwrap(), None, dapps_domain), - (Some(EndpointPath { - app_id: "status".to_owned(), - app_params: vec!["my".into(), "inject.js".into()], - query: None, - host: "my.status.web3.site".to_owned(), - port: 80, - using_dapps_domains: true, - }), SpecialEndpoint::None) - ); - // By Subdomain assert_eq!( extract_endpoint(&"http://status.web3.site/test.html".parse().unwrap(), None, dapps_domain), diff --git a/dapps/src/tests/fetch.rs b/dapps/src/tests/fetch.rs index bbd766a55..444d5b656 100644 --- a/dapps/src/tests/fetch.rs +++ b/dapps/src/tests/fetch.rs @@ -19,7 +19,7 @@ use rustc_hex::FromHex; use tests::helpers::{ serve_with_registrar, serve_with_registrar_and_sync, serve_with_fetch, serve_with_registrar_and_fetch, - request, assert_security_headers_for_embed, + request, assert_security_headers }; #[test] @@ -40,7 +40,7 @@ fn should_resolve_dapp() { // then response.assert_status("HTTP/1.1 404 Not Found"); assert_eq!(registrar.calls.lock().len(), 4); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } #[test] @@ -61,7 +61,7 @@ fn should_return_503_when_syncing_but_should_make_the_calls() { // then response.assert_status("HTTP/1.1 503 Service Unavailable"); assert_eq!(registrar.calls.lock().len(), 2); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } const GAVCOIN_DAPP: &'static str = "00000000000000000000000000000000000000000000000000000000000000609faf32e1e3845e237cc6efd27187cee13b3b99db000000000000000000000000000000000000000000000000d8bd350823e28ff75e74a34215faefdc8a52fd8e00000000000000000000000000000000000000000000000000000000000000116761766f66796f726b2f676176636f696e000000000000000000000000000000"; @@ -95,7 +95,7 @@ fn should_return_502_on_hash_mismatch() { response.assert_status("HTTP/1.1 502 Bad Gateway"); assert!(response.body.contains("HashMismatch"), "Expected hash mismatch response, got: {:?}", response.body); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } #[test] @@ -126,7 +126,7 @@ fn should_return_error_for_invalid_dapp_zip() { response.assert_status("HTTP/1.1 502 Bad Gateway"); assert!(response.body.contains("InvalidArchive"), "Expected invalid zip response, got: {:?}", response.body); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); } #[test] @@ -165,7 +165,7 @@ fn should_return_fetched_dapp_content() { fetch.assert_no_more_requests(); response1.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response1.headers); + assert_security_headers(&response1.headers); assert!( response1.body.contains(r#"18

Hello Gavcoin!

@@ -178,7 +178,7 @@ fn should_return_fetched_dapp_content() { ); response2.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response2.headers); + assert_security_headers(&response2.headers); assert_eq!( response2.body, r#"EA @@ -331,7 +331,7 @@ fn should_stream_web_content() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://parity.io/"); fetch.assert_no_more_requests(); @@ -354,7 +354,7 @@ fn should_support_base32_encoded_web_urls() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://parity.io/styles.css?test=123"); fetch.assert_no_more_requests(); @@ -377,7 +377,7 @@ fn should_correctly_handle_long_label_when_splitted() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://contribution.melonport.com/styles.css?test=123"); fetch.assert_no_more_requests(); @@ -400,7 +400,7 @@ fn should_support_base32_encoded_web_urls_as_path() { // then response.assert_status("HTTP/1.1 200 OK"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_requested("https://parity.io/styles.css?test=123"); fetch.assert_no_more_requests(); @@ -423,7 +423,7 @@ fn should_return_error_on_non_whitelisted_domain() { // then response.assert_status("HTTP/1.1 400 Bad Request"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } @@ -445,7 +445,7 @@ fn should_return_error_on_invalid_token() { // then response.assert_status("HTTP/1.1 400 Bad Request"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } @@ -467,7 +467,7 @@ fn should_return_error_on_invalid_protocol() { // then response.assert_status("HTTP/1.1 400 Bad Request"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } @@ -492,7 +492,7 @@ fn should_disallow_non_get_requests() { // then response.assert_status("HTTP/1.1 405 Method Not Allowed"); - assert_security_headers_for_embed(&response.headers); + assert_security_headers(&response.headers); fetch.assert_no_more_requests(); } diff --git a/dapps/src/tests/helpers/mod.rs b/dapps/src/tests/helpers/mod.rs index aa7608979..58ec71d73 100644 --- a/dapps/src/tests/helpers/mod.rs +++ b/dapps/src/tests/helpers/mod.rs @@ -36,8 +36,6 @@ mod fetch; use self::registrar::FakeRegistrar; use self::fetch::FakeFetch; -const SIGNER_PORT: u16 = 18180; - #[derive(Debug)] struct FakeSync(bool); impl SyncStatus for FakeSync { @@ -63,8 +61,7 @@ pub fn init_server(process: F, io: IoHandler) -> (Server, Arc Server { init_server(|builder| builder, Default::default()).0 } -pub fn serve_ui() -> Server { - init_server(|mut builder| { - builder.serve_ui = true; - builder - }, Default::default()).0 -} - pub fn request(server: Server, request: &str) -> http_client::Response { http_client::request(server.addr(), request) } @@ -136,9 +126,6 @@ pub fn request(server: Server, request: &str) -> http_client::Response { pub fn assert_security_headers(headers: &[String]) { http_client::assert_security_headers_present(headers, None) } -pub fn assert_security_headers_for_embed(headers: &[String]) { - http_client::assert_security_headers_present(headers, Some(SIGNER_PORT)) -} /// Webapps HTTP+RPC server build. pub struct ServerBuilder { @@ -146,10 +133,8 @@ pub struct ServerBuilder { registrar: Arc>, sync_status: Arc, web_proxy_tokens: Arc, - signer_address: Option<(String, u16)>, allowed_hosts: DomainsValidation, fetch: T, - serve_ui: bool, } impl ServerBuilder { @@ -160,10 +145,8 @@ impl ServerBuilder { registrar: registrar, sync_status: Arc::new(FakeSync(false)), web_proxy_tokens: Arc::new(|_| None), - signer_address: None, allowed_hosts: DomainsValidation::Disabled, fetch: fetch, - serve_ui: false, } } } @@ -176,10 +159,8 @@ impl ServerBuilder { registrar: self.registrar, sync_status: self.sync_status, web_proxy_tokens: self.web_proxy_tokens, - signer_address: self.signer_address, allowed_hosts: self.allowed_hosts, fetch: fetch, - serve_ui: self.serve_ui, } } @@ -190,7 +171,6 @@ impl ServerBuilder { addr, io, self.allowed_hosts, - self.signer_address, self.dapps_path, vec![], self.registrar, @@ -198,7 +178,6 @@ impl ServerBuilder { self.web_proxy_tokens, Remote::new_sync(), self.fetch, - self.serve_ui, ) } } @@ -215,7 +194,6 @@ impl Server { addr: &SocketAddr, io: IoHandler, allowed_hosts: DomainsValidation, - signer_address: Option<(String, u16)>, dapps_path: PathBuf, extra_dapps: Vec, registrar: Arc>, @@ -223,7 +201,6 @@ impl Server { web_proxy_tokens: Arc, remote: Remote, fetch: F, - serve_ui: bool, ) -> io::Result { let health = NodeHealth::new( sync_status.clone(), @@ -231,23 +208,10 @@ impl Server { remote.clone(), ); let pool = ::futures_cpupool::CpuPool::new(1); - let middleware = if serve_ui { - Middleware::ui( - pool, - health, - DAPPS_DOMAIN.into(), - registrar, - sync_status, - fetch, - false, - ) - } else { + let middleware = Middleware::dapps( pool, health, - signer_address, - vec![], - vec![], dapps_path, extra_dapps, DAPPS_DOMAIN.into(), @@ -255,8 +219,7 @@ impl Server { sync_status, web_proxy_tokens, fetch, - ) - }; + ); let mut allowed_hosts: Option> = allowed_hosts.into(); allowed_hosts.as_mut().map(|hosts| { diff --git a/dapps/src/tests/home.rs b/dapps/src/tests/home.rs deleted file mode 100644 index 024261d5d..000000000 --- a/dapps/src/tests/home.rs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use tests::helpers::{serve_ui, request, assert_security_headers}; - -#[test] -fn should_serve_home_js() { - // given - let server = serve_ui(); - - // when - let response = request(server, - "\ - GET /inject.js HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "application/javascript"); - assert_eq!(response.body.contains("function(){"), true, "Expected function in: {}", response.body); - assert_security_headers(&response.headers); -} - -#[test] -fn should_serve_home() { - // given - let server = serve_ui(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "text/html"); - assert_security_headers(&response.headers); -} diff --git a/dapps/src/tests/mod.rs b/dapps/src/tests/mod.rs index 38a1d6f17..c4d88cf9f 100644 --- a/dapps/src/tests/mod.rs +++ b/dapps/src/tests/mod.rs @@ -20,7 +20,5 @@ mod helpers; mod api; mod fetch; -mod home; -mod redirection; mod rpc; mod validation; diff --git a/dapps/src/tests/redirection.rs b/dapps/src/tests/redirection.rs deleted file mode 100644 index 722ade25b..000000000 --- a/dapps/src/tests/redirection.rs +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -use tests::helpers::{serve, request, assert_security_headers, assert_security_headers_for_embed}; - -#[test] -fn should_redirect_to_home() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 302 Found"); - assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180"); -} - -#[test] -fn should_redirect_to_home_with_domain() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: home.web3.site\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 302 Found"); - assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180"); -} - -#[test] -fn should_redirect_to_home_when_trailing_slash_is_missing() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /app HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 302 Found"); - assert_eq!(response.headers.get(0).unwrap(), "Location: http://127.0.0.1:18180"); -} - -#[test] -fn should_display_404_on_invalid_dapp() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /invaliddapp/ HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 404 Not Found"); - assert_security_headers_for_embed(&response.headers); -} - -#[test] -fn should_display_404_on_invalid_dapp_with_domain() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET / HTTP/1.1\r\n\ - Host: invaliddapp.web3.site\r\n\ - Connection: close\r\n\ - \r\n\ - " - ); - - // then - response.assert_status("HTTP/1.1 404 Not Found"); - assert_security_headers_for_embed(&response.headers); -} - -#[test] -fn should_serve_rpc() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - POST / HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - Content-Type: application/json\r\n - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#)); -} - -#[test] -fn should_serve_rpc_at_slash_rpc() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - POST /rpc HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - Content-Type: application/json\r\n - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - assert_eq!(response.body, format!("4C\n{}\n\n0\n\n", r#"{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}"#)); -} - -#[test] -fn should_serve_proxy_pac() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /proxy/proxy.pac HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - assert_eq!(response.body, "DB\n\nfunction FindProxyForURL(url, host) {\n\tif (shExpMatch(host, \"home.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:18180\";\n\t}\n\n\tif (shExpMatch(host, \"*.web3.site\"))\n\t{\n\t\treturn \"PROXY 127.0.0.1:8080\";\n\t}\n\n\treturn \"DIRECT\";\n}\n\n0\n\n".to_owned()); - assert_security_headers(&response.headers); -} - -#[test] -fn should_serve_utils() { - // given - let server = serve(); - - // when - let response = request(server, - "\ - GET /parity-utils/inject.js HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); - response.assert_header("Content-Type", "application/javascript"); - assert_eq!(response.body.contains("function(){"), true, "Expected function in: {}", response.body); - assert_security_headers(&response.headers); -} diff --git a/dapps/src/tests/validation.rs b/dapps/src/tests/validation.rs index ed4a3dc2f..f9d22f802 100644 --- a/dapps/src/tests/validation.rs +++ b/dapps/src/tests/validation.rs @@ -37,26 +37,6 @@ fn should_reject_invalid_host() { assert!(response.body.contains("Provided Host header is not whitelisted."), response.body); } -#[test] -fn should_allow_valid_host() { - // given - let server = serve_hosts(Some(vec!["localhost:8080".into()])); - - // when - let response = request(server, - "\ - GET /ui/ HTTP/1.1\r\n\ - Host: localhost:8080\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); -} - #[test] fn should_serve_dapps_domains() { // given @@ -66,28 +46,7 @@ fn should_serve_dapps_domains() { let response = request(server, "\ GET / HTTP/1.1\r\n\ - Host: ui.web3.site\r\n\ - Connection: close\r\n\ - \r\n\ - {} - " - ); - - // then - response.assert_status("HTTP/1.1 200 OK"); -} - -#[test] -// NOTE [todr] This is required for error pages to be styled properly. -fn should_allow_parity_utils_even_on_invalid_domain() { - // given - let server = serve_hosts(Some(vec!["localhost:8080".into()])); - - // when - let response = request(server, - "\ - GET /parity-utils/styles.css HTTP/1.1\r\n\ - Host: 127.0.0.1:8080\r\n\ + Host: proxy.web3.site\r\n\ Connection: close\r\n\ \r\n\ {} diff --git a/dapps/src/web.rs b/dapps/src/web.rs index 14f215ca4..fac0dca1a 100644 --- a/dapps/src/web.rs +++ b/dapps/src/web.rs @@ -30,10 +30,9 @@ use handlers::{ ContentFetcherHandler, ContentHandler, ContentValidator, ValidatorResponse, StreamingHandler, }; -use {Embeddable, WebProxyTokens}; +use WebProxyTokens; pub struct Web { - embeddable_on: Embeddable, web_proxy_tokens: Arc, fetch: F, pool: CpuPool, @@ -41,13 +40,11 @@ pub struct Web { impl Web { pub fn boxed( - embeddable_on: Embeddable, web_proxy_tokens: Arc, fetch: F, pool: CpuPool, ) -> Box { Box::new(Web { - embeddable_on, web_proxy_tokens, fetch, pool, @@ -64,7 +61,6 @@ impl Web { "Invalid parameter", "Couldn't parse given parameter:", path.app_params.get(0).map(String::as_str), - self.embeddable_on.clone() ))?; let mut token_it = token_and_url.split('+'); @@ -76,7 +72,7 @@ impl Web { Some(domain) => domain, _ => { return Err(ContentHandler::error( - StatusCode::BadRequest, "Invalid Access Token", "Invalid or old web proxy access token supplied.", Some("Try refreshing the page."), self.embeddable_on.clone() + StatusCode::BadRequest, "Invalid Access Token", "Invalid or old web proxy access token supplied.", Some("Try refreshing the page."), )); } }; @@ -86,14 +82,14 @@ impl Web { Some(url) if url.starts_with("http://") || url.starts_with("https://") => url.to_owned(), _ => { return Err(ContentHandler::error( - StatusCode::BadRequest, "Invalid Protocol", "Invalid protocol used.", None, self.embeddable_on.clone() + StatusCode::BadRequest, "Invalid Protocol", "Invalid protocol used.", None, )); } }; if !target_url.starts_with(&*domain) { return Err(ContentHandler::error( - StatusCode::BadRequest, "Invalid Domain", "Dapp attempted to access invalid domain.", Some(&target_url), self.embeddable_on.clone(), + StatusCode::BadRequest, "Invalid Domain", "Dapp attempted to access invalid domain.", Some(&target_url), )); } @@ -128,10 +124,8 @@ impl Endpoint for Web { &target_url, path, WebInstaller { - embeddable_on: self.embeddable_on.clone(), token, }, - self.embeddable_on.clone(), self.fetch.clone(), self.pool.clone(), )) @@ -139,7 +133,6 @@ impl Endpoint for Web { } struct WebInstaller { - embeddable_on: Embeddable, token: String, } @@ -154,12 +147,10 @@ impl ContentValidator for WebInstaller { fetch::BodyReader::new(response), status, mime, - self.embeddable_on, ); if is_html { handler.set_initial_content(&format!( - r#""#, - apps::UTILS_PATH, + r#""#, apps::URL_REFERER, apps::WEB_PATH, &self.token, diff --git a/dapps/ui-deprecation/Cargo.toml b/dapps/ui-deprecation/Cargo.toml deleted file mode 100644 index f4479c236..000000000 --- a/dapps/ui-deprecation/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -description = "Parity UI deprecation notice." -name = "parity-ui-deprecation" -version = "1.10.0" -license = "GPL-3.0" -authors = ["Parity Technologies "] -build = "build.rs" - -[features] -default = ["with-syntex", "use-precompiled-js"] -use-precompiled-js = ["parity-dapps-glue/use-precompiled-js"] -with-syntex = ["parity-dapps-glue/with-syntex"] - -[build-dependencies] -parity-dapps-glue = "1.9" - -[dependencies] -parity-dapps-glue = "1.9" diff --git a/dapps/ui-deprecation/build.rs b/dapps/ui-deprecation/build.rs deleted file mode 100644 index c427f3d54..000000000 --- a/dapps/ui-deprecation/build.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate parity_dapps_glue; - -fn main() { - parity_dapps_glue::generate(); -} diff --git a/dapps/ui-deprecation/build/index.html b/dapps/ui-deprecation/build/index.html deleted file mode 100644 index 07059743c..000000000 --- a/dapps/ui-deprecation/build/index.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - Parity - - - -
-
-
-

The Parity UI has been split off into a standalone project.

-

Get the standalone Parity UI from here

-

- -

-
-
-
- - diff --git a/dapps/ui-deprecation/src/lib.rs b/dapps/ui-deprecation/src/lib.rs deleted file mode 100644 index 79a4a4249..000000000 --- a/dapps/ui-deprecation/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(feature = "with-syntex")] -include!(concat!(env!("OUT_DIR"), "/lib.rs")); - -#[cfg(not(feature = "with-syntex"))] -include!("lib.rs.in"); diff --git a/dapps/ui-deprecation/src/lib.rs.in b/dapps/ui-deprecation/src/lib.rs.in deleted file mode 100644 index 892ebbded..000000000 --- a/dapps/ui-deprecation/src/lib.rs.in +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -extern crate parity_dapps_glue; - -use std::collections::HashMap; -use parity_dapps_glue::{WebApp, File, Info}; - -#[derive(WebAppFiles)] -#[webapp(path = "../build")] -pub struct App { - pub files: HashMap<&'static str, File>, -} - -impl Default for App { - fn default() -> App { - App { - files: Self::files(), - } - } -} - -impl WebApp for App { - fn file(&self, path: &str) -> Option<&File> { - self.files.get(path) - } - - fn info(&self) -> Info { - Info { - name: "Parity Wallet info page", - version: env!("CARGO_PKG_VERSION"), - author: "Parity ", - description: "Deprecation notice for Parity Wallet", - icon_url: "icon.png", - } - } -} - -#[test] -fn test_js() { - parity_dapps_glue::js::build(env!("CARGO_MANIFEST_DIR"), "build"); -} diff --git a/dapps/ui/Cargo.toml b/dapps/ui/Cargo.toml deleted file mode 100644 index acb7a9173..000000000 --- a/dapps/ui/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -description = "Ethcore Parity UI" -homepage = "http://parity.io" -license = "GPL-3.0" -name = "parity-ui" -version = "1.12.0" -authors = ["Parity Technologies "] - -[build-dependencies] -rustc_version = "0.2" - -[dependencies] -parity-ui-dev = { git = "https://github.com/parity-js/shell.git", rev = "eecaadcb9e421bce31e91680d14a20bbd38f92a2", optional = true } -parity-ui-old-dev = { git = "https://github.com/parity-js/dapp-wallet.git", rev = "65deb02e7c007a0fd8aab0c089c93e3fd1de6f87", optional = true } -parity-ui-precompiled = { git = "https://github.com/js-dist-paritytech/parity-master-1-10-shell.git", rev="bd25b41cd642c6b822d820dded3aa601a29aa079", optional = true } -parity-ui-old-precompiled = { git = "https://github.com/js-dist-paritytech/parity-master-1-10-wallet.git", rev="4b6f112412716cd05123d32eeb7fda448288a6c6", optional = true } - -[features] -no-precompiled-js = ["parity-ui-dev", "parity-ui-old-dev"] -use-precompiled-js = ["parity-ui-precompiled", "parity-ui-old-precompiled"] diff --git a/dapps/ui/src/lib.rs b/dapps/ui/src/lib.rs deleted file mode 100644 index f04f755a9..000000000 --- a/dapps/ui/src/lib.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -#[cfg(feature = "parity-ui-dev")] -mod inner { - extern crate parity_ui_dev; - - pub use self::parity_ui_dev::*; -} - -#[cfg(feature = "parity-ui-precompiled")] -mod inner { - extern crate parity_ui_precompiled; - - pub use self::parity_ui_precompiled::*; -} - -#[cfg(feature = "parity-ui-old-dev")] -pub mod old { - extern crate parity_ui_old_dev; - - pub use self::parity_ui_old_dev::*; -} - -#[cfg(feature = "parity-ui-old-precompiled")] -pub mod old { - extern crate parity_ui_old_precompiled; - - pub use self::parity_ui_old_precompiled::*; -} - -pub use self::inner::*; diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index facd01dbf..a3f3d4887 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -26,10 +26,6 @@ usage! { // Arguments must start with arg_ // Flags must start with flag_ - CMD cmd_ui { - "Manage ui", - } - CMD cmd_dapp { "Manage dapps", @@ -376,35 +372,10 @@ usage! { "Provide a file containing passwords for unlocking accounts (signer, private account, validators).", ["UI options"] - FLAG flag_force_ui: (bool) = false, or |c: &Config| c.ui.as_ref()?.force.clone(), - "--force-ui", - "Enable Trusted UI WebSocket endpoint, even when --unlock is in use.", - - FLAG flag_no_ui: (bool) = false, or |c: &Config| c.ui.as_ref()?.disable.clone(), - "--no-ui", - "Disable Trusted UI WebSocket endpoint.", - - // NOTE [todr] For security reasons don't put this to config files - FLAG flag_ui_no_validation: (bool) = false, or |_| None, - "--ui-no-validation", - "Disable Origin and Host headers validation for Trusted UI. WARNING: INSECURE. Used only for development.", - - ARG arg_ui_interface: (String) = "local", or |c: &Config| c.ui.as_ref()?.interface.clone(), - "--ui-interface=[IP]", - "Specify the hostname portion of the Trusted UI server, IP should be an interface's IP address, or local.", - - ARG arg_ui_hosts: (String) = "none", or |c: &Config| c.ui.as_ref()?.hosts.as_ref().map(|vec| vec.join(",")), - "--ui-hosts=[HOSTS]", - "List of allowed Host header values. This option will validate the Host header sent by the browser, it is additional security against some attack vectors. Special options: \"all\", \"none\",.", - ARG arg_ui_path: (String) = "$BASE/signer", or |c: &Config| c.ui.as_ref()?.path.clone(), "--ui-path=[PATH]", "Specify directory where Trusted UIs tokens should be stored.", - ARG arg_ui_port: (u16) = 8180u16, or |c: &Config| c.ui.as_ref()?.port.clone(), - "--ui-port=[PORT]", - "Specify the port of Trusted UI server.", - ["Networking options"] FLAG flag_no_warp: (bool) = false, or |c: &Config| c.network.as_ref()?.warp.clone().map(|w| !w), "--no-warp", @@ -948,6 +919,30 @@ usage! { "--public-node", "Does nothing; Public node is removed from Parity.", + FLAG flag_force_ui: (bool) = false, or |_| None, + "--force-ui", + "Does nothing; UI is now a separate project.", + + FLAG flag_no_ui: (bool) = false, or |_| None, + "--no-ui", + "Does nothing; UI is now a separate project.", + + FLAG flag_ui_no_validation: (bool) = false, or |_| None, + "--ui-no-validation", + "Does nothing; UI is now a separate project.", + + ARG arg_ui_interface: (String) = "local", or |_| None, + "--ui-interface=[IP]", + "Does nothing; UI is now a separate project.", + + ARG arg_ui_hosts: (String) = "none", or |_| None, + "--ui-hosts=[HOSTS]", + "Does nothing; UI is now a separate project.", + + ARG arg_ui_port: (u16) = 8180u16, or |_| None, + "--ui-port=[PORT]", + "Does nothing; UI is now a separate project.", + ARG arg_dapps_port: (Option) = None, or |c: &Config| c.dapps.as_ref()?.port.clone(), "--dapps-port=[PORT]", "Dapps server is merged with RPC server. Use --jsonrpc-port.", @@ -1111,12 +1106,18 @@ struct PrivateTransactions { #[derive(Default, Debug, PartialEq, Deserialize)] #[serde(deny_unknown_fields)] struct Ui { - force: Option, - disable: Option, - port: Option, - interface: Option, - hosts: Option>, path: Option, + + #[serde(rename="force")] + _legacy_force: Option, + #[serde(rename="disable")] + _legacy_disable: Option, + #[serde(rename="port")] + _legacy_port: Option, + #[serde(rename="interface")] + _legacy_interface: Option, + #[serde(rename="hosts")] + _legacy_hosts: Option>, } #[derive(Default, Debug, PartialEq, Deserialize)] @@ -1404,15 +1405,13 @@ mod tests { let args = Args::parse(&["parity", "--secretstore-nodes", "abc@127.0.0.1:3333,cde@10.10.10.10:4444"]).unwrap(); assert_eq!(args.arg_secretstore_nodes, "abc@127.0.0.1:3333,cde@10.10.10.10:4444"); - let args = Args::parse(&["parity", "--password", "~/.safe/1", "--password", "~/.safe/2", "--ui-port", "8123", "ui"]).unwrap(); + let args = Args::parse(&["parity", "--password", "~/.safe/1", "--password", "~/.safe/2", "--ui-port", "8123"]).unwrap(); assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]); assert_eq!(args.arg_ui_port, 8123); - assert_eq!(args.cmd_ui, true); - let args = Args::parse(&["parity", "--password", "~/.safe/1,~/.safe/2", "--ui-port", "8123", "ui"]).unwrap(); + let args = Args::parse(&["parity", "--password", "~/.safe/1,~/.safe/2", "--ui-port", "8123"]).unwrap(); assert_eq!(args.arg_password, vec!["~/.safe/1".to_owned(), "~/.safe/2".to_owned()]); assert_eq!(args.arg_ui_port, 8123); - assert_eq!(args.cmd_ui, true); } #[test] @@ -1476,7 +1475,6 @@ mod tests { // then assert_eq!(args, Args { // Commands - cmd_ui: false, cmd_dapp: false, cmd_daemon: false, cmd_account: false, @@ -1566,7 +1564,7 @@ mod tests { flag_force_ui: false, flag_no_ui: false, arg_ui_port: 8180u16, - arg_ui_interface: "127.0.0.1".into(), + arg_ui_interface: "local".into(), arg_ui_hosts: "none".into(), arg_ui_path: "$HOME/.parity/signer".into(), flag_ui_no_validation: false, @@ -1820,12 +1818,12 @@ mod tests { fast_unlock: None, }), ui: Some(Ui { - force: None, - disable: Some(true), - port: None, - interface: None, - hosts: None, path: None, + _legacy_force: None, + _legacy_disable: Some(true), + _legacy_port: None, + _legacy_interface: None, + _legacy_hosts: None, }), network: Some(Network { warp: Some(false), diff --git a/parity/configuration.rs b/parity/configuration.rs index 6f475aa83..ec73046a4 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -20,7 +20,6 @@ use std::net::SocketAddr; use std::path::{Path, PathBuf}; use std::collections::BTreeMap; use std::cmp; -use std::str::FromStr; use cli::{Args, ArgsError}; use hash::keccak; use ethereum_types::{U256, H256, Address}; @@ -34,7 +33,7 @@ use ethcore::miner::{stratum, MinerOptions}; use ethcore::verification::queue::VerifierSettings; use miner::pool; -use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration, UiConfiguration}; +use rpc::{IpcConfiguration, HttpConfiguration, WsConfiguration}; use parity_rpc::NetworkSettings; use cache::CacheConfig; use helpers::{to_duration, to_mode, to_block_id, to_u256, to_pending_set, to_price, geth_ipc_path, parity_ipc_path, to_bootnodes, to_addresses, to_address, to_queue_strategy, to_queue_penalization, passwords_from_files}; @@ -65,7 +64,7 @@ pub enum Cmd { Account(AccountCmd), ImportPresaleWallet(ImportWallet), Blockchain(BlockchainCmd), - SignerToken(WsConfiguration, UiConfiguration, LogConfig), + SignerToken(WsConfiguration, LogConfig), SignerSign { id: Option, pwfile: Option, @@ -130,7 +129,6 @@ impl Configuration { let http_conf = self.http_config()?; let ipc_conf = self.ipc_config()?; let net_conf = self.net_config()?; - let ui_conf = self.ui_config(); let network_id = self.network_id(); let cache_config = self.cache_config(); let tracing = self.args.arg_tracing.parse()?; @@ -150,7 +148,7 @@ impl Configuration { let authfile = ::signer::codes_path(&ws_conf.signer_path); if self.args.cmd_signer_new_token { - Cmd::SignerToken(ws_conf, ui_conf, logger_config.clone()) + Cmd::SignerToken(ws_conf, logger_config.clone()) } else if self.args.cmd_signer_sign { let pwfile = self.accounts_config()?.password_files.first().map(|pwfile| { PathBuf::from(pwfile) @@ -381,13 +379,11 @@ impl Configuration { net_settings: self.network_settings()?, dapps_conf: dapps_conf, ipfs_conf: ipfs_conf, - ui_conf: ui_conf, secretstore_conf: secretstore_conf, private_provider_conf: private_provider_conf, private_encryptor_conf: private_enc_conf, private_tx_enabled, dapp: self.dapp_to_open()?, - ui: self.args.cmd_ui, name: self.args.arg_identity, custom_bootnodes: self.args.arg_bootnodes.is_some(), no_periodic_snapshot: self.args.flag_no_periodic_snapshot, @@ -588,29 +584,11 @@ impl Configuration { }) } - fn ui_port(&self) -> u16 { - self.args.arg_ports_shift + self.args.arg_ui_port - } - fn ntp_servers(&self) -> Vec { self.args.arg_ntp_servers.split(",").map(str::to_owned).collect() } - fn ui_config(&self) -> UiConfiguration { - let ui = self.ui_enabled(); - UiConfiguration { - enabled: ui.enabled, - interface: self.ui_interface(), - port: self.ui_port(), - hosts: self.ui_hosts(), - info_page_only: ui.info_page_only, - } - } - fn dapps_config(&self) -> DappsConfiguration { - let dev_ui = if self.args.flag_ui_no_validation { vec![("127.0.0.1".to_owned(), 3000)] } else { vec![] }; - let ui_port = self.ui_port(); - DappsConfiguration { enabled: self.dapps_enabled(), dapps_path: PathBuf::from(self.directories().dapps), @@ -619,31 +597,6 @@ impl Configuration { } else { vec![] }, - extra_embed_on: { - let mut extra_embed = dev_ui.clone(); - match self.ui_hosts() { - // In case host validation is disabled allow all frame ancestors - None => { - // NOTE Chrome does not seem to support "*:" - // we use `http(s)://*:` instead. - extra_embed.push(("http://*".to_owned(), ui_port)); - extra_embed.push(("https://*".to_owned(), ui_port)); - }, - Some(hosts) => extra_embed.extend(hosts.into_iter().filter_map(|host| { - let mut it = host.split(":"); - let host = it.next(); - let port = it.next().and_then(|v| u16::from_str(v).ok()); - - match (host, port) { - (Some(host), Some(port)) => Some((host.into(), port)), - (Some(host), None) => Some((host.into(), ui_port)), - _ => None, - } - })), - } - extra_embed - }, - extra_script_src: dev_ui, } } @@ -863,10 +816,6 @@ impl Configuration { Some(hosts) } - fn ui_hosts(&self) -> Option> { - self.hosts(&self.args.arg_ui_hosts, &self.ui_interface()) - } - fn rpc_hosts(&self) -> Option> { self.hosts(&self.args.arg_jsonrpc_hosts, &self.rpc_interface()) } @@ -876,7 +825,7 @@ impl Configuration { } fn ws_origins(&self) -> Option> { - if self.args.flag_unsafe_expose || self.args.flag_ui_no_validation { + if self.args.flag_unsafe_expose { return None; } @@ -925,7 +874,6 @@ impl Configuration { } fn ws_config(&self) -> Result { - let ui = self.ui_config(); let http = self.http_config()?; let support_token_api = @@ -941,7 +889,6 @@ impl Configuration { origins: self.ws_origins(), signer_path: self.directories().signer.into(), support_token_api, - ui_address: ui.address(), dapps_address: http.address(), max_connections: self.args.arg_ws_max_connections, }; @@ -1065,10 +1012,6 @@ impl Configuration { }.into() } - fn ui_interface(&self) -> String { - self.interface(&self.args.arg_ui_interface) - } - fn rpc_interface(&self) -> String { let rpc_interface = self.args.arg_rpcaddr.clone().unwrap_or(self.args.arg_jsonrpc_interface.clone()); self.interface(&rpc_interface) @@ -1184,24 +1127,6 @@ impl Configuration { into_secretstore_service_contract_address(self.args.arg_secretstore_doc_sretr_contract.as_ref()) } - fn ui_enabled(&self) -> UiEnabled { - if self.args.flag_force_ui { - return UiEnabled { - enabled: true, - info_page_only: false, - }; - } - - let ui_disabled = self.args.arg_unlock.is_some() || - self.args.flag_geth || - self.args.flag_no_ui; - - return UiEnabled { - enabled: (self.args.cmd_ui || !ui_disabled) && cfg!(feature = "ui-enabled"), - info_page_only: !self.args.cmd_ui, - } - } - fn verifier_settings(&self) -> VerifierSettings { let mut settings = VerifierSettings::default(); settings.scale_verifiers = self.args.flag_scale_verifiers; @@ -1220,12 +1145,6 @@ impl Configuration { } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -struct UiEnabled { - pub enabled: bool, - pub info_page_only: bool, -} - fn into_secretstore_service_contract_address(s: &str) -> Result, String> { match s { "none" => Ok(None), @@ -1254,7 +1173,7 @@ mod tests { use helpers::{default_network_config}; use params::SpecType; use presale::ImportWallet; - use rpc::{WsConfiguration, UiConfiguration}; + use rpc::WsConfiguration; use rpc_apis::ApiSet; use run::RunCmd; @@ -1438,16 +1357,9 @@ mod tests { origins: Some(vec!["parity://*".into(),"chrome-extension://*".into(), "moz-extension://*".into()]), hosts: Some(vec![]), signer_path: expected.into(), - ui_address: Some("127.0.0.1:8180".into()), dapps_address: Some("127.0.0.1:8545".into()), support_token_api: true, max_connections: 100, - }, UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, }, LogConfig { color: true, mode: None, @@ -1516,12 +1428,10 @@ mod tests { net_settings: Default::default(), dapps_conf: Default::default(), ipfs_conf: Default::default(), - ui_conf: Default::default(), secretstore_conf: Default::default(), private_provider_conf: Default::default(), private_encryptor_conf: Default::default(), private_tx_enabled: false, - ui: false, dapp: None, name: "".into(), custom_bootnodes: false, @@ -1704,49 +1614,6 @@ mod tests { assert_eq!(conf2.ipfs_cors(), Some(vec!["http://parity.io".into(),"http://something.io".into()])); } - #[test] - fn should_disable_signer_in_geth_compat() { - // given - - // when - let conf0 = parse(&["parity", "--geth"]); - let conf1 = parse(&["parity", "--geth", "--force-ui"]); - let conf2 = parse(&["parity", "--geth", "ui"]); - let conf3 = parse(&["parity"]); - - // then - assert_eq!(conf0.ui_enabled(), UiEnabled { - enabled: false, - info_page_only: true, - }); - assert_eq!(conf1.ui_enabled(), UiEnabled { - enabled: true, - info_page_only: false, - }); - assert_eq!(conf2.ui_enabled(), UiEnabled { - enabled: true, - info_page_only: false, - }); - assert_eq!(conf3.ui_enabled(), UiEnabled { - enabled: true, - info_page_only: true, - }); - } - - #[test] - fn should_disable_signer_when_account_is_unlocked() { - // given - - // when - let conf0 = parse(&["parity", "--unlock", "0x0"]); - - // then - assert_eq!(conf0.ui_enabled(), UiEnabled { - enabled: false, - info_page_only: true, - }); - } - #[test] fn should_parse_ui_configuration() { // given @@ -1757,69 +1624,22 @@ mod tests { let conf2 = parse(&["parity", "--ui-path=signer", "--ui-port", "3123"]); let conf3 = parse(&["parity", "--ui-path=signer", "--ui-interface", "test"]); let conf4 = parse(&["parity", "--ui-path=signer", "--force-ui"]); - let conf5 = parse(&["parity", "--ui-path=signer", "ui"]); // then assert_eq!(conf0.directories().signer, "signer".to_owned()); - assert_eq!(conf0.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, - }); assert!(conf1.ws_config().unwrap().hosts.is_some()); - assert_eq!(conf1.ws_config().unwrap().origins, None); + assert_eq!(conf1.ws_config().unwrap().origins, Some(vec!["parity://*".into(), "chrome-extension://*".into(), "moz-extension://*".into()])); assert_eq!(conf1.directories().signer, "signer".to_owned()); - assert_eq!(conf1.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, - }); - assert_eq!(conf1.dapps_config().extra_embed_on, vec![("127.0.0.1".to_owned(), 3000)]); assert!(conf2.ws_config().unwrap().hosts.is_some()); assert_eq!(conf2.directories().signer, "signer".to_owned()); - assert_eq!(conf2.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 3123, - hosts: Some(vec![]), - info_page_only: true, - }); assert!(conf3.ws_config().unwrap().hosts.is_some()); assert_eq!(conf3.directories().signer, "signer".to_owned()); - assert_eq!(conf3.ui_config(), UiConfiguration { - enabled: true, - interface: "test".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: true, - }); assert!(conf4.ws_config().unwrap().hosts.is_some()); assert_eq!(conf4.directories().signer, "signer".to_owned()); - assert_eq!(conf4.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: false, - }); - - assert!(conf5.ws_config().unwrap().hosts.is_some()); - assert_eq!(conf5.directories().signer, "signer".to_owned()); - assert_eq!(conf5.ui_config(), UiConfiguration { - enabled: true, - interface: "127.0.0.1".into(), - port: 8180, - hosts: Some(vec![]), - info_page_only: false, - }); } #[test] @@ -1976,7 +1796,6 @@ mod tests { assert_eq!(conf0.network_settings().unwrap().rpc_port, 8546); assert_eq!(conf0.http_config().unwrap().port, 8546); assert_eq!(conf0.ws_config().unwrap().port, 8547); - assert_eq!(conf0.ui_config().port, 8181); assert_eq!(conf0.secretstore_config().unwrap().port, 8084); assert_eq!(conf0.secretstore_config().unwrap().http_port, 8083); assert_eq!(conf0.ipfs_config().port, 5002); @@ -1987,7 +1806,6 @@ mod tests { assert_eq!(conf1.network_settings().unwrap().rpc_port, 8545); assert_eq!(conf1.http_config().unwrap().port, 8545); assert_eq!(conf1.ws_config().unwrap().port, 8547); - assert_eq!(conf1.ui_config().port, 8181); assert_eq!(conf1.secretstore_config().unwrap().port, 8084); assert_eq!(conf1.secretstore_config().unwrap().http_port, 8083); assert_eq!(conf1.ipfs_config().port, 5002); @@ -2007,8 +1825,6 @@ mod tests { assert_eq!(&conf0.ws_config().unwrap().interface, "0.0.0.0"); assert_eq!(conf0.ws_config().unwrap().hosts, None); assert_eq!(conf0.ws_config().unwrap().origins, None); - assert_eq!(&conf0.ui_config().interface, "0.0.0.0"); - assert_eq!(conf0.ui_config().hosts, None); assert_eq!(&conf0.secretstore_config().unwrap().interface, "0.0.0.0"); assert_eq!(&conf0.secretstore_config().unwrap().http_interface, "0.0.0.0"); assert_eq!(&conf0.ipfs_config().interface, "0.0.0.0"); diff --git a/parity/dapps.rs b/parity/dapps.rs index 427bfa53b..ce5b3a8da 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -39,8 +39,6 @@ pub struct Configuration { pub enabled: bool, pub dapps_path: PathBuf, pub extra_dapps: Vec, - pub extra_embed_on: Vec<(String, u16)>, - pub extra_script_src: Vec<(String, u16)>, } impl Default for Configuration { @@ -50,8 +48,6 @@ impl Default for Configuration { enabled: true, dapps_path: replace_home(&data_dir, "$BASE/dapps").into(), extra_dapps: vec![], - extra_embed_on: vec![], - extra_script_src: vec![], } } } @@ -163,8 +159,6 @@ pub struct Dependencies { pub fetch: FetchClient, pub pool: CpuPool, pub signer: Arc, - pub ui_address: Option<(String, u16)>, - pub info_page_only: bool, } pub fn new(configuration: Configuration, deps: Dependencies) -> Result, String> { @@ -177,19 +171,6 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Result Result, String> { - if !enabled { - return Ok(None); - } - - server::ui_middleware( - deps, - rpc::DAPPS_DOMAIN, ).map(Some) } @@ -215,19 +196,10 @@ mod server { _dapps_path: PathBuf, _extra_dapps: Vec, _dapps_domain: &str, - _extra_embed_on: Vec<(String, u16)>, - _extra_script_src: Vec<(String, u16)>, ) -> Result { Err("Your Parity version has been compiled without WebApps support.".into()) } - pub fn ui_middleware( - _deps: Dependencies, - _dapps_domain: &str, - ) -> Result { - Err("Your Parity version has been compiled without UI support.".into()) - } - pub fn service(_: &Option) -> Option> { None } @@ -249,8 +221,6 @@ mod server { dapps_path: PathBuf, extra_dapps: Vec, dapps_domain: &str, - extra_embed_on: Vec<(String, u16)>, - extra_script_src: Vec<(String, u16)>, ) -> Result { let signer = deps.signer; let web_proxy_tokens = Arc::new(move |token| signer.web_proxy_access_token_domain(&token)); @@ -258,9 +228,6 @@ mod server { Ok(parity_dapps::Middleware::dapps( deps.pool, deps.node_health, - deps.ui_address, - extra_embed_on, - extra_script_src, dapps_path, extra_dapps, dapps_domain, @@ -271,21 +238,6 @@ mod server { )) } - pub fn ui_middleware( - deps: Dependencies, - dapps_domain: &str, - ) -> Result { - Ok(parity_dapps::Middleware::ui( - deps.pool, - deps.node_health, - dapps_domain, - deps.contract_client, - deps.sync_status, - deps.fetch, - deps.info_page_only, - )) - } - pub fn service(middleware: &Option) -> Option> { middleware.as_ref().map(|m| Arc::new(DappsServiceWrapper { endpoints: m.endpoints().clone(), diff --git a/parity/lib.rs b/parity/lib.rs index c76872255..8c3242afb 100644 --- a/parity/lib.rs +++ b/parity/lib.rs @@ -118,15 +118,13 @@ mod user_defaults; mod whisper; mod db; -use std::net::{TcpListener}; use std::io::BufReader; use std::fs::File; -use ansi_term::Style; use hash::keccak_buffer; use cli::Args; use configuration::{Cmd, Execute}; use deprecated::find_deprecated; -use ethcore_logger::{Config as LogConfig, setup_log}; +use ethcore_logger::setup_log; pub use self::configuration::Configuration; pub use self::run::RunningClient; @@ -195,24 +193,6 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res match command.cmd { Cmd::Run(run_cmd) => { - if run_cmd.ui_conf.enabled && !run_cmd.ui_conf.info_page_only { - warn!("{}", Style::new().bold().paint("Parity browser interface is deprecated. It's going to be removed in the next version, use standalone Parity UI instead.")); - warn!("{}", Style::new().bold().paint("Standalone Parity UI: https://github.com/Parity-JS/shell/releases")); - } - - if run_cmd.ui && run_cmd.dapps_conf.enabled { - // Check if Parity is already running - let addr = format!("{}:{}", run_cmd.ui_conf.interface, run_cmd.ui_conf.port); - if !TcpListener::bind(&addr as &str).is_ok() { - return open_ui(&run_cmd.ws_conf, &run_cmd.ui_conf, &run_cmd.logger_config).map(|_| ExecutionAction::Instant(None)); - } - } - - // start ui - if run_cmd.ui { - open_ui(&run_cmd.ws_conf, &run_cmd.ui_conf, &run_cmd.logger_config)?; - } - if let Some(ref dapp) = run_cmd.dapp { open_dapp(&run_cmd.dapps_conf, &run_cmd.http_conf, dapp)?; } @@ -225,7 +205,7 @@ fn execute(command: Execute, on_client_rq: Cr, on_updater_rq: Rr) -> Res Cmd::Account(account_cmd) => account::execute(account_cmd).map(|s| ExecutionAction::Instant(Some(s))), Cmd::ImportPresaleWallet(presale_cmd) => presale::execute(presale_cmd).map(|s| ExecutionAction::Instant(Some(s))), Cmd::Blockchain(blockchain_cmd) => blockchain::execute(blockchain_cmd).map(|_| ExecutionAction::Instant(None)), - Cmd::SignerToken(ws_conf, ui_conf, logger_config) => signer::execute(ws_conf, ui_conf, logger_config).map(|s| ExecutionAction::Instant(Some(s))), + Cmd::SignerToken(ws_conf, logger_config) => signer::execute(ws_conf, logger_config).map(|s| ExecutionAction::Instant(Some(s))), Cmd::SignerSign { id, pwfile, port, authfile } => rpc_cli::signer_sign(id, pwfile, port, authfile).map(|s| ExecutionAction::Instant(Some(s))), Cmd::SignerList { port, authfile } => rpc_cli::signer_list(port, authfile).map(|s| ExecutionAction::Instant(Some(s))), Cmd::SignerReject { id, port, authfile } => rpc_cli::signer_reject(id, port, authfile).map(|s| ExecutionAction::Instant(Some(s))), @@ -257,19 +237,6 @@ pub fn start(conf: Configuration, on_client_rq: Cr, on_updater_rq: Rr) - execute(conf.into_command()?, on_client_rq, on_updater_rq) } -fn open_ui(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result<(), String> { - if !ui_conf.enabled { - return Err("Cannot use UI command with UI turned off.".into()) - } - - let token = signer::generate_token_and_url(ws_conf, ui_conf, logger_config)?; - // Open a browser - url::open(&token.url).map_err(|e| format!("{}", e))?; - // Print a message - println!("{}", token.message); - Ok(()) -} - fn open_dapp(dapps_conf: &dapps::Configuration, rpc_conf: &rpc::HttpConfiguration, dapp: &str) -> Result<(), String> { if !dapps_conf.enabled { return Err("Cannot use DAPP command with Dapps turned off.".into()) diff --git a/parity/rpc.rs b/parity/rpc.rs index cdc8e7ca5..3e71cc629 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -68,58 +68,6 @@ impl Default for HttpConfiguration { } } -#[derive(Debug, PartialEq, Clone)] -pub struct UiConfiguration { - pub enabled: bool, - pub interface: String, - pub port: u16, - pub hosts: Option>, - pub info_page_only: bool, -} - -impl UiConfiguration { - pub fn address(&self) -> Option { - address(self.enabled, &self.interface, self.port, &self.hosts) - } - - pub fn redirection_address(&self) -> Option<(String, u16)> { - self.address().map(|host| { - let mut it = host.split(':'); - let hostname: Option = it.next().map(|s| s.to_owned()); - let port: Option = it.next().and_then(|s| s.parse().ok()); - - (hostname.unwrap_or_else(|| "localhost".into()), port.unwrap_or(8180)) - }) - } -} - -impl From for HttpConfiguration { - fn from(conf: UiConfiguration) -> Self { - HttpConfiguration { - enabled: conf.enabled, - interface: conf.interface, - port: conf.port, - apis: rpc_apis::ApiSet::UnsafeContext, - cors: Some(vec![]), - hosts: conf.hosts, - server_threads: 1, - processing_threads: 0, - } - } -} - -impl Default for UiConfiguration { - fn default() -> Self { - UiConfiguration { - enabled: cfg!(feature = "ui-enabled"), - port: 8180, - interface: "127.0.0.1".into(), - hosts: Some(vec![]), - info_page_only: true, - } - } -} - #[derive(Debug, PartialEq)] pub struct IpcConfiguration { pub enabled: bool, @@ -153,7 +101,6 @@ pub struct WsConfiguration { pub hosts: Option>, pub signer_path: PathBuf, pub support_token_api: bool, - pub ui_address: Option, pub dapps_address: Option, } @@ -170,7 +117,6 @@ impl Default for WsConfiguration { hosts: Some(Vec::new()), signer_path: replace_home(&data_dir, "$BASE/signer").into(), support_token_api: true, - ui_address: Some("127.0.0.1:8180".into()), dapps_address: Some("127.0.0.1:8545".into()), } } @@ -225,9 +171,8 @@ pub fn new_ws( }; let remote = deps.remote.clone(); - let ui_address = conf.ui_address.clone(); - let allowed_origins = into_domains(with_domain(conf.origins, domain, &ui_address, &conf.dapps_address)); - let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()), &None)); + let allowed_origins = into_domains(with_domain(conf.origins, domain, &conf.dapps_address)); + let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()))); let signer_path; let path = match conf.support_token_api { @@ -276,7 +221,7 @@ pub fn new_http( let remote = deps.remote.clone(); let cors_domains = into_domains(conf.cors); - let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()), &None)); + let allowed_hosts = into_domains(with_domain(conf.hosts, domain, &Some(url.clone().into()))); let start_result = rpc::start_http( &addr, @@ -328,7 +273,7 @@ fn into_domains>(items: Option>) -> DomainsValidatio items.map(|vals| vals.into_iter().map(T::from).collect()).into() } -fn with_domain(items: Option>, domain: &str, ui_address: &Option, dapps_address: &Option) -> Option> { +fn with_domain(items: Option>, domain: &str, dapps_address: &Option) -> Option> { fn extract_port(s: &str) -> Option { s.split(':').nth(1).and_then(|s| s.parse().ok()) } @@ -347,7 +292,6 @@ fn with_domain(items: Option>, domain: &str, ui_address: &Option, - pub ui: bool, pub name: String, pub custom_bootnodes: bool, pub stratum: Option, @@ -185,7 +183,7 @@ fn execute_light_impl(cmd: RunCmd, logger: Arc) -> Result) -> Result) -> Result) -> Result(cmd: RunCmd, logger: Arc, on_client_rq: execute_upgrades(&cmd.dirs.base, &db_dirs, algorithm, &cmd.compaction)?; // create dirs used by parity - cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.ui_conf.enabled, cmd.secretstore_conf.enabled)?; + cmd.dirs.create_dirs(cmd.dapps_conf.enabled, cmd.acc_conf.unlocked_accounts.len() == 0, cmd.secretstore_conf.enabled)?; // run in daemon mode if let Some(pid_file) = cmd.daemon { @@ -756,12 +750,9 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: fetch: fetch.clone(), pool: cpu_pool.clone(), signer: signer_service.clone(), - ui_address: cmd.ui_conf.redirection_address(), - info_page_only: cmd.ui_conf.info_page_only, }) }; let dapps_middleware = dapps::new(cmd.dapps_conf.clone(), dapps_deps.clone())?; - let ui_middleware = dapps::new_ui(cmd.ui_conf.enabled, dapps_deps)?; let dapps_service = dapps::service(&dapps_middleware); let deps_for_rpc_apis = Arc::new(rpc_apis::FullDependencies { @@ -807,8 +798,6 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: let ws_server = rpc::new_ws(cmd.ws_conf.clone(), &dependencies)?; let ipc_server = rpc::new_ipc(cmd.ipc_conf, &dependencies)?; let http_server = rpc::new_http("HTTP JSON-RPC", "jsonrpc", cmd.http_conf.clone(), &dependencies, dapps_middleware)?; - // the ui server - let ui_server = rpc::new_http("UI WALLET", "ui", cmd.ui_conf.clone().into(), &dependencies, ui_middleware)?; // secret store key server let secretstore_deps = secretstore::Dependencies { @@ -881,7 +870,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: informant, client, client_service: Arc::new(service), - keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, ui_server, secretstore_key_server, ipfs_server, event_loop)), + keep_alive: Box::new((watcher, updater, ws_server, http_server, ipc_server, secretstore_key_server, ipfs_server, event_loop)), } }) } diff --git a/parity/signer.rs b/parity/signer.rs index 4388e11aa..e9a636bf8 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -28,7 +28,6 @@ pub const CODES_FILENAME: &'static str = "authcodes"; pub struct NewToken { pub token: String, - pub url: String, pub message: String, } @@ -49,45 +48,26 @@ pub fn codes_path(path: &Path) -> PathBuf { p } -pub fn execute(ws_conf: rpc::WsConfiguration, ui_conf: rpc::UiConfiguration, logger_config: LogConfig) -> Result { - Ok(generate_token_and_url(&ws_conf, &ui_conf, &logger_config)?.message) +pub fn execute(ws_conf: rpc::WsConfiguration, logger_config: LogConfig) -> Result { + Ok(generate_token_and_url(&ws_conf, &logger_config)?.message) } -pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, ui_conf: &rpc::UiConfiguration, logger_config: &LogConfig) -> Result { +pub fn generate_token_and_url(ws_conf: &rpc::WsConfiguration, logger_config: &LogConfig) -> Result { let code = generate_new_token(&ws_conf.signer_path, logger_config.color).map_err(|err| format!("Error generating token: {:?}", err))?; - let auth_url = format!("http://{}:{}/#/auth?token={}", ui_conf.interface, ui_conf.port, code); let colored = |s: String| match logger_config.color { true => format!("{}", White.bold().paint(s)), false => s, }; - if !ui_conf.enabled { - return Ok(NewToken { - token: code.clone(), - url: auth_url.clone(), - message: format!( - r#" + Ok(NewToken { + token: code.clone(), + message: format!( + r#" Generated token: {} "#, - colored(code) - ), - }) - } - - // And print in to the console - Ok(NewToken { - token: code.clone(), - url: auth_url.clone(), - message: format!( - r#" -Open: {} -to authorize your browser. -Or use the generated token: -{}"#, - colored(auth_url), - code - ) + colored(code) + ), }) }