risingwave_frontend/user/
user_privilege.rs1use itertools::Itertools;
16use risingwave_common::acl;
17use risingwave_common::acl::{AclMode, AclModeSet};
18use risingwave_common::catalog::DEFAULT_SUPER_USER_ID;
19use risingwave_pb::user::PbGrantPrivilege;
20use risingwave_pb::user::grant_privilege::{ActionWithGrantOption, PbAction, PbObject};
21use risingwave_sqlparser::ast::{Action, GrantObjects, Privileges};
22
23use crate::error::{ErrorCode, Result};
24
25pub fn check_privilege_type(privilege: &Privileges, objects: &GrantObjects) -> Result<()> {
26 match privilege {
27 Privileges::All { .. } => Ok(()),
28 Privileges::Actions(actions) => {
29 let acl_sets = get_all_available_modes(objects)?;
30 let valid = actions
31 .iter()
32 .map(get_prost_action)
33 .all(|action| acl_sets.has_mode(action.into()));
34 if !valid {
35 return Err(ErrorCode::BindError(
36 "Invalid privilege type for the given object.".to_owned(),
37 )
38 .into());
39 }
40
41 Ok(())
42 }
43 }
44}
45
46fn get_all_available_modes(object: &GrantObjects) -> Result<&AclModeSet> {
47 match object {
48 GrantObjects::Databases(_) => Ok(&acl::ALL_AVAILABLE_DATABASE_MODES),
49 GrantObjects::Schemas(_) => Ok(&acl::ALL_AVAILABLE_SCHEMA_MODES),
50 GrantObjects::Sources(_) | GrantObjects::AllSourcesInSchema { .. } => {
51 Ok(&acl::ALL_AVAILABLE_SOURCE_MODES)
52 }
53 GrantObjects::Mviews(_) | GrantObjects::AllMviewsInSchema { .. } => {
54 Ok(&acl::ALL_AVAILABLE_MVIEW_MODES)
55 }
56 GrantObjects::Tables(_) | GrantObjects::AllTablesInSchema { .. } => {
57 Ok(&acl::ALL_AVAILABLE_TABLE_MODES)
58 }
59 GrantObjects::Sinks(_) | GrantObjects::AllSinksInSchema { .. } => {
60 Ok(&acl::ALL_AVAILABLE_SINK_MODES)
61 }
62 GrantObjects::Views(_) | GrantObjects::AllViewsInSchema { .. } => {
63 Ok(&acl::ALL_AVAILABLE_VIEW_MODES)
64 }
65 GrantObjects::Functions(_) | GrantObjects::AllFunctionsInSchema { .. } => {
66 Ok(&acl::ALL_AVAILABLE_FUNCTION_MODES)
67 }
68 GrantObjects::Secrets(_) | GrantObjects::AllSecretsInSchema { .. } => {
69 Ok(&acl::ALL_AVAILABLE_SECRET_MODES)
70 }
71 GrantObjects::Subscriptions(_) | GrantObjects::AllSubscriptionsInSchema { .. } => {
72 Ok(&acl::ALL_AVAILABLE_SUBSCRIPTION_MODES)
73 }
74 GrantObjects::Connections(_) | GrantObjects::AllConnectionsInSchema { .. } => {
75 Ok(&acl::ALL_AVAILABLE_CONNECTION_MODES)
76 }
77 _ => Err(
78 ErrorCode::BindError("Invalid privilege type for the given object.".to_owned()).into(),
79 ),
80 }
81}
82
83pub fn available_privilege_actions(objects: &GrantObjects) -> Result<Vec<PbAction>> {
84 let acl_sets = get_all_available_modes(objects)?;
85 Ok(acl_sets.iter().map(Into::into).collect_vec())
86}
87
88#[inline(always)]
89pub fn get_prost_action(action: &Action) -> PbAction {
90 match action {
91 Action::Select { .. } => PbAction::Select,
92 Action::Insert { .. } => PbAction::Insert,
93 Action::Update { .. } => PbAction::Update,
94 Action::Delete => PbAction::Delete,
95 Action::Connect => PbAction::Connect,
96 Action::Create => PbAction::Create,
97 Action::Usage => PbAction::Usage,
98 Action::Execute => PbAction::Execute,
99 _ => unreachable!(),
100 }
101}
102
103pub fn available_prost_privilege(object: PbObject, for_dml_table: bool) -> PbGrantPrivilege {
104 let acl_set = match object {
105 PbObject::DatabaseId(_) => &acl::ALL_AVAILABLE_DATABASE_MODES,
106 PbObject::SchemaId(_) => &acl::ALL_AVAILABLE_SCHEMA_MODES,
107 PbObject::SourceId(_) => &acl::ALL_AVAILABLE_SOURCE_MODES,
108 PbObject::TableId(_) => {
109 if for_dml_table {
110 &acl::ALL_AVAILABLE_TABLE_MODES
111 } else {
112 &acl::ALL_AVAILABLE_MVIEW_MODES
113 }
114 }
115 PbObject::ViewId(_) => &acl::ALL_AVAILABLE_VIEW_MODES,
116 PbObject::SinkId(_) => &acl::ALL_AVAILABLE_SINK_MODES,
117 PbObject::SubscriptionId(_) => &acl::ALL_AVAILABLE_SUBSCRIPTION_MODES,
118 PbObject::FunctionId(_) => &acl::ALL_AVAILABLE_FUNCTION_MODES,
119 PbObject::ConnectionId(_) => &acl::ALL_AVAILABLE_CONNECTION_MODES,
120 PbObject::SecretId(_) => &acl::ALL_AVAILABLE_SECRET_MODES,
121 };
122 let actions = acl_set
123 .iter()
124 .map(|mode| ActionWithGrantOption {
125 action: <AclMode as Into<PbAction>>::into(mode) as i32,
126 with_grant_option: false,
127 granted_by: DEFAULT_SUPER_USER_ID,
128 })
129 .collect_vec();
130 PbGrantPrivilege {
131 action_with_opts: actions,
132 object: Some(object),
133 }
134}