sc_rpc_api/policy.rs
1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Policy-related types.
20//!
21//! Contains a `DenyUnsafe` type that can be used to deny potentially unsafe
22//! RPC when accessed externally.
23
24use jsonrpsee::types::{error::ErrorCode, ErrorObject, ErrorObjectOwned};
25
26/// Checks if the RPC call is safe to be called externally.
27pub fn check_if_safe(ext: &jsonrpsee::Extensions) -> Result<(), UnsafeRpcError> {
28 match ext.get::<DenyUnsafe>().map(|deny_unsafe| deny_unsafe.check_if_safe()) {
29 Some(Ok(())) => Ok(()),
30 Some(Err(e)) => Err(e),
31 None => unreachable!("DenyUnsafe extension is always set by the substrate rpc server; qed"),
32 }
33}
34
35/// Signifies whether a potentially unsafe RPC should be denied.
36#[derive(Clone, Copy, Debug)]
37pub enum DenyUnsafe {
38 /// Denies only potentially unsafe RPCs.
39 Yes,
40 /// Allows calling every RPCs.
41 No,
42}
43
44impl DenyUnsafe {
45 /// Returns `Ok(())` if the RPCs considered unsafe are safe to call,
46 /// otherwise returns `Err(UnsafeRpcError)`.
47 pub fn check_if_safe(self) -> Result<(), UnsafeRpcError> {
48 match self {
49 DenyUnsafe::Yes => Err(UnsafeRpcError),
50 DenyUnsafe::No => Ok(()),
51 }
52 }
53}
54
55/// Signifies whether an RPC considered unsafe is denied to be called externally.
56#[derive(Debug)]
57pub struct UnsafeRpcError;
58
59impl std::fmt::Display for UnsafeRpcError {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 write!(f, "RPC call is unsafe to be called externally")
62 }
63}
64
65impl std::error::Error for UnsafeRpcError {}
66
67impl From<UnsafeRpcError> for ErrorObjectOwned {
68 fn from(e: UnsafeRpcError) -> ErrorObjectOwned {
69 ErrorObject::owned(ErrorCode::MethodNotFound.code(), e.to_string(), None::<()>)
70 }
71}