summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/ops/websocket.rs33
-rw-r--r--cli/rt/27_websocket.js4
-rw-r--r--cli/tests/unit/unit_tests.ts1
-rw-r--r--cli/tests/unit/websocket_test.ts9
4 files changed, 45 insertions, 2 deletions
diff --git a/cli/ops/websocket.rs b/cli/ops/websocket.rs
index 23dee5f85..77b2b5f11 100644
--- a/cli/ops/websocket.rs
+++ b/cli/ops/websocket.rs
@@ -8,12 +8,12 @@ use deno_core::error::AnyError;
use deno_core::futures::future::poll_fn;
use deno_core::futures::StreamExt;
use deno_core::futures::{ready, SinkExt};
-use deno_core::serde_json;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::url;
use deno_core::BufVec;
use deno_core::OpState;
+use deno_core::{serde_json, ZeroCopyBuf};
use http::{Method, Request, Uri};
use serde::Deserialize;
use std::borrow::Cow;
@@ -34,6 +34,7 @@ use tokio_tungstenite::{client_async, WebSocketStream};
use webpki::DNSNameRef;
pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_ws_check_permission", op_ws_check_permission);
super::reg_json_async(rt, "op_ws_create", op_ws_create);
super::reg_json_async(rt, "op_ws_send", op_ws_send);
super::reg_json_async(rt, "op_ws_close", op_ws_close);
@@ -47,6 +48,29 @@ type WsStream = WebSocketStream<MaybeTlsStream>;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
+struct CheckPermissionArgs {
+ url: String,
+}
+
+// This op is needed because creating a WS instance in JavaScript is a sync
+// operation and should throw error when permissions are not fullfiled,
+// but actual op that connects WS is async.
+pub fn op_ws_check_permission(
+ state: &mut OpState,
+ args: Value,
+ _zero_copy: &mut [ZeroCopyBuf],
+) -> Result<Value, AnyError> {
+ let args: CheckPermissionArgs = serde_json::from_value(args)?;
+
+ state
+ .borrow::<Permissions>()
+ .check_net_url(&url::Url::parse(&args.url)?)?;
+
+ Ok(json!({}))
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
struct CreateArgs {
url: String,
protocols: String,
@@ -58,11 +82,16 @@ pub async fn op_ws_create(
_bufs: BufVec,
) -> Result<Value, AnyError> {
let args: CreateArgs = serde_json::from_value(args)?;
+
{
let s = state.borrow();
s.borrow::<Permissions>()
- .check_net_url(&url::Url::parse(&args.url)?)?;
+ .check_net_url(&url::Url::parse(&args.url)?)
+ .expect(
+ "Permission check should have been done in op_ws_check_permission",
+ );
}
+
let ca_file = {
let cli_state = super::global_state2(&state);
cli_state.flags.ca_file.clone()
diff --git a/cli/rt/27_websocket.js b/cli/rt/27_websocket.js
index 675c1e836..60428c24d 100644
--- a/cli/rt/27_websocket.js
+++ b/cli/rt/27_websocket.js
@@ -33,6 +33,10 @@
this.#url = wsURL.href;
+ core.jsonOpSync("op_ws_check_permission", {
+ url: this.#url,
+ });
+
if (protocols && typeof protocols === "string") {
protocols = [protocols];
}
diff --git a/cli/tests/unit/unit_tests.ts b/cli/tests/unit/unit_tests.ts
index f545e55fa..6885204a3 100644
--- a/cli/tests/unit/unit_tests.ts
+++ b/cli/tests/unit/unit_tests.ts
@@ -79,3 +79,4 @@ import "./write_file_test.ts";
import "./write_text_file_test.ts";
import "./performance_test.ts";
import "./version_test.ts";
+import "./websocket_test.ts";
diff --git a/cli/tests/unit/websocket_test.ts b/cli/tests/unit/websocket_test.ts
new file mode 100644
index 000000000..8e5726d44
--- /dev/null
+++ b/cli/tests/unit/websocket_test.ts
@@ -0,0 +1,9 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+import { assertThrows, unitTest } from "./test_util.ts";
+
+unitTest(function websocketPermissionless() {
+ assertThrows(
+ () => new WebSocket("ws://localhost"),
+ Deno.errors.PermissionDenied,
+ );
+});