deno_runtime/ops/
permissions.rs

1// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2
3use ::deno_permissions::PermissionState;
4use ::deno_permissions::PermissionsContainer;
5use deno_core::op2;
6use deno_core::OpState;
7use serde::Deserialize;
8use serde::Serialize;
9
10deno_core::extension!(
11  deno_permissions,
12  ops = [
13    op_query_permission,
14    op_revoke_permission,
15    op_request_permission,
16  ],
17);
18
19#[derive(Deserialize)]
20pub struct PermissionArgs {
21  name: String,
22  path: Option<String>,
23  host: Option<String>,
24  variable: Option<String>,
25  kind: Option<String>,
26  command: Option<String>,
27}
28
29#[derive(Serialize)]
30pub struct PermissionStatus {
31  state: String,
32  partial: bool,
33}
34
35impl From<PermissionState> for PermissionStatus {
36  fn from(state: PermissionState) -> Self {
37    PermissionStatus {
38      state: if state == PermissionState::GrantedPartial {
39        PermissionState::Granted.to_string()
40      } else {
41        state.to_string()
42      },
43      partial: state == PermissionState::GrantedPartial,
44    }
45  }
46}
47
48#[derive(Debug, thiserror::Error)]
49pub enum PermissionError {
50  #[error("No such permission name: {0}")]
51  InvalidPermissionName(String),
52  #[error("{0}")]
53  PathResolve(#[from] ::deno_permissions::PathResolveError),
54  #[error("{0}")]
55  NetDescriptorParse(#[from] ::deno_permissions::NetDescriptorParseError),
56  #[error("{0}")]
57  SysDescriptorParse(#[from] ::deno_permissions::SysDescriptorParseError),
58  #[error("{0}")]
59  RunDescriptorParse(#[from] ::deno_permissions::RunDescriptorParseError),
60}
61
62#[op2]
63#[serde]
64pub fn op_query_permission(
65  state: &mut OpState,
66  #[serde] args: PermissionArgs,
67) -> Result<PermissionStatus, PermissionError> {
68  let permissions = state.borrow::<PermissionsContainer>();
69  let perm = match args.name.as_ref() {
70    "read" => permissions.query_read(args.path.as_deref())?,
71    "write" => permissions.query_write(args.path.as_deref())?,
72    "net" => permissions.query_net(args.host.as_deref())?,
73    "env" => permissions.query_env(args.variable.as_deref()),
74    "sys" => permissions.query_sys(args.kind.as_deref())?,
75    "run" => permissions.query_run(args.command.as_deref())?,
76    "ffi" => permissions.query_ffi(args.path.as_deref())?,
77    _ => return Err(PermissionError::InvalidPermissionName(args.name)),
78  };
79  Ok(PermissionStatus::from(perm))
80}
81
82#[op2]
83#[serde]
84pub fn op_revoke_permission(
85  state: &mut OpState,
86  #[serde] args: PermissionArgs,
87) -> Result<PermissionStatus, PermissionError> {
88  let permissions = state.borrow::<PermissionsContainer>();
89  let perm = match args.name.as_ref() {
90    "read" => permissions.revoke_read(args.path.as_deref())?,
91    "write" => permissions.revoke_write(args.path.as_deref())?,
92    "net" => permissions.revoke_net(args.host.as_deref())?,
93    "env" => permissions.revoke_env(args.variable.as_deref()),
94    "sys" => permissions.revoke_sys(args.kind.as_deref())?,
95    "run" => permissions.revoke_run(args.command.as_deref())?,
96    "ffi" => permissions.revoke_ffi(args.path.as_deref())?,
97    _ => return Err(PermissionError::InvalidPermissionName(args.name)),
98  };
99  Ok(PermissionStatus::from(perm))
100}
101
102#[op2(stack_trace)]
103#[serde]
104pub fn op_request_permission(
105  state: &mut OpState,
106  #[serde] args: PermissionArgs,
107) -> Result<PermissionStatus, PermissionError> {
108  let permissions = state.borrow::<PermissionsContainer>();
109  let perm = match args.name.as_ref() {
110    "read" => permissions.request_read(args.path.as_deref())?,
111    "write" => permissions.request_write(args.path.as_deref())?,
112    "net" => permissions.request_net(args.host.as_deref())?,
113    "env" => permissions.request_env(args.variable.as_deref()),
114    "sys" => permissions.request_sys(args.kind.as_deref())?,
115    "run" => permissions.request_run(args.command.as_deref())?,
116    "ffi" => permissions.request_ffi(args.path.as_deref())?,
117    _ => return Err(PermissionError::InvalidPermissionName(args.name)),
118  };
119  Ok(PermissionStatus::from(perm))
120}