Skip to content

Commit 89b1367

Browse files
authored
Merge pull request #7721 from BohuTANG/dev-privilege-7697
chore(query): Move privilege check to access check
2 parents e0ae369 + 9426872 commit 89b1367

16 files changed

+227
-137
lines changed

src/query/service/src/interpreters/access/accessor.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use std::sync::Arc;
1818
use common_exception::Result;
1919
use common_legacy_planners::PlanNode;
2020

21+
use crate::interpreters::access::PrivilegeAccess;
2122
use crate::interpreters::ManagementModeAccess;
2223
use crate::sessions::QueryContext;
2324
use crate::sql::plans::Plan;
@@ -39,7 +40,11 @@ pub struct Accessor {
3940
impl Accessor {
4041
pub fn create(ctx: Arc<QueryContext>) -> Self {
4142
let mut accessors: HashMap<String, Box<dyn AccessChecker>> = Default::default();
42-
accessors.insert("management".to_string(), ManagementModeAccess::create(ctx));
43+
accessors.insert(
44+
"management".to_string(),
45+
ManagementModeAccess::create(ctx.clone()),
46+
);
47+
accessors.insert("privilege".to_string(), PrivilegeAccess::create(ctx));
4348
Accessor { accessors }
4449
}
4550

src/query/service/src/interpreters/access/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
mod accessor;
1616
mod management_mode_access;
17+
mod privilege_access;
1718

1819
pub use accessor::AccessChecker;
1920
pub use accessor::Accessor;
2021
pub use management_mode_access::ManagementModeAccess;
22+
pub use privilege_access::PrivilegeAccess;
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
// Copyright 2022 Datafuse Labs.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use std::sync::Arc;
16+
17+
use common_exception::Result;
18+
use common_legacy_planners::PlanNode;
19+
use common_meta_types::GrantObject;
20+
use common_meta_types::UserPrivilegeType;
21+
22+
use crate::interpreters::access::AccessChecker;
23+
use crate::sessions::QueryContext;
24+
use crate::sql::plans::Plan;
25+
26+
pub struct PrivilegeAccess {
27+
ctx: Arc<QueryContext>,
28+
}
29+
30+
impl PrivilegeAccess {
31+
pub fn create(ctx: Arc<QueryContext>) -> Box<dyn AccessChecker> {
32+
Box::new(PrivilegeAccess { ctx })
33+
}
34+
}
35+
36+
#[async_trait::async_trait]
37+
impl AccessChecker for PrivilegeAccess {
38+
async fn check(&self, _plan: &PlanNode) -> Result<()> {
39+
// The old planner *NO* need to check anymore.
40+
Ok(())
41+
}
42+
43+
async fn check_new(&self, plan: &Plan) -> Result<()> {
44+
let session = self.ctx.get_current_session();
45+
46+
match plan {
47+
Plan::Query { .. } => {}
48+
Plan::Explain { .. } => {}
49+
Plan::Copy(_) => {}
50+
Plan::Call(_) => {}
51+
52+
// Database.
53+
Plan::ShowCreateDatabase(_) => {}
54+
Plan::CreateDatabase(_) => {
55+
session
56+
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Create)
57+
.await?;
58+
}
59+
Plan::DropDatabase(_) => {
60+
session
61+
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Drop)
62+
.await?;
63+
}
64+
Plan::UndropDatabase(_) => {
65+
session
66+
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Drop)
67+
.await?;
68+
}
69+
Plan::RenameDatabase(_) => {
70+
session
71+
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Alter)
72+
.await?;
73+
}
74+
Plan::UseDatabase(_) => {}
75+
76+
// Table.
77+
Plan::ShowCreateTable(_) => {}
78+
Plan::DescribeTable(_) => {}
79+
Plan::CreateTable(plan) => {
80+
session
81+
.validate_privilege(
82+
&GrantObject::Database(plan.catalog.clone(), plan.database.clone()),
83+
UserPrivilegeType::Create,
84+
)
85+
.await?;
86+
}
87+
Plan::DropTable(plan) => {
88+
session
89+
.validate_privilege(
90+
&GrantObject::Database(plan.catalog.clone(), plan.database.clone()),
91+
UserPrivilegeType::Drop,
92+
)
93+
.await?;
94+
}
95+
Plan::UndropTable(plan) => {
96+
session
97+
.validate_privilege(
98+
&GrantObject::Database(plan.catalog.clone(), plan.database.clone()),
99+
UserPrivilegeType::Drop,
100+
)
101+
.await?;
102+
}
103+
Plan::RenameTable(_) => {}
104+
Plan::AlterTableClusterKey(plan) => {
105+
session
106+
.validate_privilege(
107+
&GrantObject::Table(
108+
plan.catalog.clone(),
109+
plan.database.clone(),
110+
plan.table.clone(),
111+
),
112+
UserPrivilegeType::Alter,
113+
)
114+
.await?;
115+
}
116+
Plan::DropTableClusterKey(plan) => {
117+
session
118+
.validate_privilege(
119+
&GrantObject::Table(
120+
plan.catalog.clone(),
121+
plan.database.clone(),
122+
plan.table.clone(),
123+
),
124+
UserPrivilegeType::Drop,
125+
)
126+
.await?;
127+
}
128+
Plan::ReclusterTable(plan) => {
129+
session
130+
.validate_privilege(
131+
&GrantObject::Table(
132+
plan.catalog.clone(),
133+
plan.database.clone(),
134+
plan.table.clone(),
135+
),
136+
UserPrivilegeType::Alter,
137+
)
138+
.await?;
139+
}
140+
Plan::TruncateTable(plan) => {
141+
session
142+
.validate_privilege(
143+
&GrantObject::Table(
144+
plan.catalog.clone(),
145+
plan.database.clone(),
146+
plan.table.clone(),
147+
),
148+
UserPrivilegeType::Delete,
149+
)
150+
.await?;
151+
}
152+
Plan::OptimizeTable(_) => {}
153+
Plan::ExistsTable(_) => {}
154+
155+
// Others.
156+
Plan::Insert(_) => {}
157+
Plan::Delete(_) => {}
158+
Plan::CreateView(plan) => {
159+
session
160+
.validate_privilege(
161+
&GrantObject::Database(plan.catalog.clone(), plan.database.clone()),
162+
UserPrivilegeType::Alter,
163+
)
164+
.await?;
165+
}
166+
Plan::AlterView(plan) => {
167+
session
168+
.validate_privilege(
169+
&GrantObject::Database(plan.catalog.clone(), plan.database.clone()),
170+
UserPrivilegeType::Alter,
171+
)
172+
.await?;
173+
}
174+
Plan::DropView(plan) => {
175+
session
176+
.validate_privilege(
177+
&GrantObject::Database(plan.catalog.clone(), plan.database.clone()),
178+
UserPrivilegeType::Drop,
179+
)
180+
.await?;
181+
}
182+
Plan::AlterUser(_) => {}
183+
Plan::CreateUser(_) => {}
184+
Plan::DropUser(_) => {}
185+
Plan::CreateUDF(_) => {}
186+
Plan::AlterUDF(_) => {}
187+
Plan::DropUDF(_) => {}
188+
Plan::CreateRole(_) => {}
189+
Plan::DropRole(_) => {}
190+
Plan::GrantRole(_) => {}
191+
Plan::GrantPriv(_) => {}
192+
Plan::ShowGrants(_) => {}
193+
Plan::RevokePriv(_) => {}
194+
Plan::RevokeRole(_) => {}
195+
Plan::ListStage(_) => {}
196+
Plan::CreateStage(_) => {}
197+
Plan::DropStage(_) => {}
198+
Plan::RemoveStage(_) => {}
199+
Plan::Presign(_) => {}
200+
Plan::SetVariable(_) => {}
201+
Plan::Kill(_) => {
202+
session
203+
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Super)
204+
.await?;
205+
}
206+
Plan::CreateShare(_) => {}
207+
Plan::DropShare(_) => {}
208+
Plan::GrantShareObject(_) => {}
209+
Plan::RevokeShareObject(_) => {}
210+
Plan::AlterShareTenants(_) => {}
211+
Plan::DescShare(_) => {}
212+
Plan::ShowShares(_) => {}
213+
Plan::ShowObjectGrantPrivileges(_) => {}
214+
Plan::ShowGrantTenantsOfShare(_) => {}
215+
}
216+
217+
Ok(())
218+
}
219+
}

src/query/service/src/interpreters/interpreter_cluster_key_alter.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ use std::sync::Arc;
1616

1717
use common_exception::Result;
1818
use common_legacy_planners::AlterTableClusterKeyPlan;
19-
use common_meta_types::GrantObject;
20-
use common_meta_types::UserPrivilegeType;
2119

2220
use super::Interpreter;
2321
use crate::pipelines::PipelineBuildResult;
@@ -43,18 +41,6 @@ impl Interpreter for AlterTableClusterKeyInterpreter {
4341

4442
async fn execute2(&self) -> Result<PipelineBuildResult> {
4543
let plan = &self.plan;
46-
self.ctx
47-
.get_current_session()
48-
.validate_privilege(
49-
&GrantObject::Table(
50-
plan.catalog.clone(),
51-
plan.database.clone(),
52-
plan.table.clone(),
53-
),
54-
UserPrivilegeType::Alter,
55-
)
56-
.await?;
57-
5844
let tenant = self.ctx.get_tenant();
5945
let catalog = self.ctx.get_catalog(&plan.catalog)?;
6046

src/query/service/src/interpreters/interpreter_cluster_key_drop.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ use std::sync::Arc;
1616

1717
use common_exception::Result;
1818
use common_legacy_planners::DropTableClusterKeyPlan;
19-
use common_meta_types::GrantObject;
20-
use common_meta_types::UserPrivilegeType;
2119

2220
use super::Interpreter;
2321
use crate::pipelines::PipelineBuildResult;
@@ -43,18 +41,6 @@ impl Interpreter for DropTableClusterKeyInterpreter {
4341

4442
async fn execute2(&self) -> Result<PipelineBuildResult> {
4543
let plan = &self.plan;
46-
self.ctx
47-
.get_current_session()
48-
.validate_privilege(
49-
&GrantObject::Table(
50-
plan.catalog.clone(),
51-
plan.database.clone(),
52-
plan.table.clone(),
53-
),
54-
UserPrivilegeType::Alter,
55-
)
56-
.await?;
57-
5844
let tenant = self.ctx.get_tenant();
5945
let catalog = self.ctx.get_catalog(&plan.catalog)?;
6046

src/query/service/src/interpreters/interpreter_database_create.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ use std::sync::Arc;
1717
use common_exception::ErrorCode;
1818
use common_exception::Result;
1919
use common_legacy_planners::CreateDatabasePlan;
20-
use common_meta_types::GrantObject;
21-
use common_meta_types::UserPrivilegeType;
2220
use common_users::UserApiProvider;
2321

2422
use crate::interpreters::Interpreter;
@@ -46,11 +44,6 @@ impl Interpreter for CreateDatabaseInterpreter {
4644

4745
#[tracing::instrument(level = "debug", skip(self), fields(ctx.id = self.ctx.get_id().as_str()))]
4846
async fn execute2(&self) -> Result<PipelineBuildResult> {
49-
self.ctx
50-
.get_current_session()
51-
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Create)
52-
.await?;
53-
5447
let tenant = self.plan.tenant.clone();
5548
let quota_api = UserApiProvider::instance().get_tenant_quota_api_client(&tenant)?;
5649
let quota = quota_api.get_quota(None).await?.data;

src/query/service/src/interpreters/interpreter_database_drop.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ use std::sync::Arc;
1616

1717
use common_exception::Result;
1818
use common_legacy_planners::DropDatabasePlan;
19-
use common_meta_types::GrantObject;
20-
use common_meta_types::UserPrivilegeType;
2119

2220
use crate::interpreters::Interpreter;
2321
use crate::pipelines::PipelineBuildResult;
@@ -42,11 +40,6 @@ impl Interpreter for DropDatabaseInterpreter {
4240
}
4341

4442
async fn execute2(&self) -> Result<PipelineBuildResult> {
45-
self.ctx
46-
.get_current_session()
47-
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Drop)
48-
.await?;
49-
5043
let catalog = self.ctx.get_catalog(&self.plan.catalog)?;
5144
catalog.drop_database(self.plan.clone().into()).await?;
5245

src/query/service/src/interpreters/interpreter_database_undrop.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ use std::sync::Arc;
1616

1717
use common_exception::Result;
1818
use common_legacy_planners::UndropDatabasePlan;
19-
use common_meta_types::GrantObject;
20-
use common_meta_types::UserPrivilegeType;
2119

2220
use crate::interpreters::Interpreter;
2321
use crate::pipelines::PipelineBuildResult;
@@ -43,16 +41,6 @@ impl Interpreter for UndropDatabaseInterpreter {
4341

4442
async fn execute2(&self) -> Result<PipelineBuildResult> {
4543
let catalog_name = self.plan.catalog.as_str();
46-
let db_name = self.plan.database.as_str();
47-
48-
self.ctx
49-
.get_current_session()
50-
.validate_privilege(
51-
&GrantObject::Database(catalog_name.into(), db_name.into()),
52-
UserPrivilegeType::Drop,
53-
)
54-
.await?;
55-
5644
let catalog = self.ctx.get_catalog(catalog_name)?;
5745
catalog.undrop_database(self.plan.clone().into()).await?;
5846
Ok(PipelineBuildResult::create())

src/query/service/src/interpreters/interpreter_kill.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ use std::sync::Arc;
1717
use common_exception::ErrorCode;
1818
use common_exception::Result;
1919
use common_legacy_planners::KillPlan;
20-
use common_meta_types::GrantObject;
21-
use common_meta_types::UserPrivilegeType;
2220

2321
use crate::interpreters::Interpreter;
2422
use crate::pipelines::PipelineBuildResult;
@@ -61,11 +59,6 @@ impl Interpreter for KillInterpreter {
6159
}
6260

6361
async fn execute2(&self) -> Result<PipelineBuildResult> {
64-
self.ctx
65-
.get_current_session()
66-
.validate_privilege(&GrantObject::Global, UserPrivilegeType::Super)
67-
.await?;
68-
6962
let id = &self.plan.id;
7063
// If press Ctrl + C, MySQL Client will create a new session and send query
7164
// `kill query mysql_connection_id` to server.

0 commit comments

Comments
 (0)