Skip to content

Commit

Permalink
Merge pull request #4700 from Junnplus/show-grants-role
Browse files Browse the repository at this point in the history
Support show grants for role
  • Loading branch information
BohuTANG authored Apr 6, 2022
2 parents 21e1d25 + 5f89641 commit 8fabe4b
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 30 deletions.
8 changes: 8 additions & 0 deletions common/meta/types/src/role_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ impl RoleInfo {
pub fn identity(&self) -> String {
self.name.clone()
}

pub fn format_grants(&self) -> Vec<Vec<u8>> {
self.grants
.entries()
.iter()
.map(|e| format!("{} TO '{}'", e, self.name).into_bytes())
.collect::<Vec<_>>()
}
}

impl TryFrom<Vec<u8>> for RoleInfo {
Expand Down
8 changes: 8 additions & 0 deletions common/meta/types/src/user_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ impl UserInfo {
pub fn has_option_flag(&self, flag: UserOptionFlag) -> bool {
self.option.has_option_flag(flag)
}

pub fn format_grants(&self) -> Vec<Vec<u8>> {
self.grants
.entries()
.iter()
.map(|e| format!("{} TO {}", e, self.identity()).into_bytes())
.collect::<Vec<_>>()
}
}

impl TryFrom<Vec<u8>> for UserInfo {
Expand Down
4 changes: 2 additions & 2 deletions common/planners/src/plan_show_grants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use common_meta_types::UserIdentity;
use common_meta_types::PrincipalIdentity;

#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq)]
pub struct ShowGrantsPlan {
pub user_identity: Option<UserIdentity>,
pub principal: Option<PrincipalIdentity>,
}
29 changes: 15 additions & 14 deletions query/src/interpreters/interpreter_show_grants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use std::sync::Arc;
use common_datablocks::DataBlock;
use common_datavalues::prelude::*;
use common_exception::Result;
use common_meta_types::PrincipalIdentity;
use common_planners::ShowGrantsPlan;
use common_streams::DataBlockStream;
use common_streams::SendableDataBlockStream;
Expand Down Expand Up @@ -47,24 +48,24 @@ impl Interpreter for ShowGrantsInterpreter {
_input_stream: Option<SendableDataBlockStream>,
) -> Result<SendableDataBlockStream> {
let schema = DataSchemaRefExt::create(vec![DataField::new("Grants", Vu8::to_data_type())]);
let tenant = self.ctx.get_tenant();
let user_mgr = self.ctx.get_user_manager();

// TODO: add permission check on reading user grants
let user_info = match self.plan.user_identity {
None => self.ctx.get_current_user()?,
Some(ref user_identity) => {
let tenant = self.ctx.get_tenant();
let user_mgr = self.ctx.get_user_manager();
user_mgr.get_user(&tenant, user_identity.clone()).await?
}
let grant_list = match self.plan.principal {
None => self.ctx.get_current_user()?.format_grants(),
Some(ref principal) => match principal {
PrincipalIdentity::User(user) => user_mgr
.get_user(&tenant, user.clone())
.await?
.format_grants(),
PrincipalIdentity::Role(role) => user_mgr
.get_role(&tenant, role.clone())
.await?
.format_grants(),
},
};

let grant_list = user_info
.grants
.entries()
.iter()
.map(|e| format!("{} TO {}", e, user_info.identity()).into_bytes())
.collect::<Vec<_>>();

let block = DataBlock::create(schema.clone(), vec![Series::from_data(grant_list)]);
Ok(Box::pin(DataBlockStream::create(schema, None, vec![block])))
}
Expand Down
10 changes: 4 additions & 6 deletions query/src/sql/parsers/parser_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,13 @@ impl<'a> DfParser<'a> {
pub(crate) fn parse_show_grants(&mut self) -> Result<DfStatement, ParserError> {
// SHOW GRANTS
if !self.consume_token("FOR") {
return Ok(DfStatement::ShowGrants(DfShowGrants {
user_identity: None,
}));
return Ok(DfStatement::ShowGrants(DfShowGrants { principal: None }));
}

// SHOW GRANTS FOR 'u1'@'%'
let (username, hostname) = self.parse_principal_name_and_host()?;
// SHOW GRANTS FOR { ROLE 'name' | [USER] 'u1'@'%' }
let prinicpal = self.parse_principal_identity()?;
Ok(DfStatement::ShowGrants(DfShowGrants {
user_identity: Some(UserIdentity { username, hostname }),
principal: Some(prinicpal),
}))
}

Expand Down
6 changes: 3 additions & 3 deletions query/src/sql/statements/statement_show_grants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use std::sync::Arc;

use common_exception::Result;
use common_meta_types::UserIdentity;
use common_meta_types::PrincipalIdentity;
use common_planners::PlanNode;
use common_planners::ShowGrantsPlan;
use common_planners::ShowPlan;
Expand All @@ -27,7 +27,7 @@ use crate::sql::statements::AnalyzedResult;

#[derive(Debug, Clone, PartialEq)]
pub struct DfShowGrants {
pub user_identity: Option<UserIdentity>,
pub principal: Option<PrincipalIdentity>,
}

#[async_trait::async_trait]
Expand All @@ -36,7 +36,7 @@ impl AnalyzableStatement for DfShowGrants {
async fn analyze(&self, _ctx: Arc<QueryContext>) -> Result<AnalyzedResult> {
Ok(AnalyzedResult::SimpleQuery(Box::new(PlanNode::Show(
ShowPlan::ShowGrants(ShowGrantsPlan {
user_identity: self.user_identity.clone(),
principal: self.principal.clone(),
}),
))))
}
Expand Down
15 changes: 10 additions & 5 deletions query/tests/it/sql/parsers/parser_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,18 +330,23 @@ fn drop_user_test() -> Result<()> {
fn show_grants_test() -> Result<()> {
expect_parse_ok(
"SHOW GRANTS",
DfStatement::ShowGrants(DfShowGrants {
user_identity: None,
}),
DfStatement::ShowGrants(DfShowGrants { principal: None }),
)?;

expect_parse_ok(
"SHOW GRANTS FOR 'u1'@'%'",
DfStatement::ShowGrants(DfShowGrants {
user_identity: Some(UserIdentity {
principal: Some(PrincipalIdentity::User(UserIdentity {
username: "u1".into(),
hostname: "%".into(),
}),
})),
}),
)?;

expect_parse_ok(
"SHOW GRANTS FOR ROLE 'test_role'",
DfStatement::ShowGrants(DfShowGrants {
principal: Some(PrincipalIdentity::Role("test_role".into())),
}),
)?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ GRANT SELECT ON 'db01'.'tb1' TO 'test-grant'@'localhost'
GRANT ALL ON 'default'.* TO 'test-grant'@'localhost'
GRANT SELECT ON 'db01'.'tb1' TO 'test-grant'@'localhost'
GRANT SELECT ON 'db01'.'tb1' TO 'test-grant'@'localhost'
GRANT SELECT ON 'default'.* TO 'test-grant-role'
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ SHOW GRANTS FOR 'test-grant'@'localhost';
REVOKE ALL PRIVILEGES ON * FROM 'test-grant'@'localhost';
SHOW GRANTS FOR 'test-grant'@'localhost';

CREATE ROLE 'test-grant-role';
GRANT SELECT ON * TO ROLE 'test-grant-role';
GRANT SELECT ON * TO ROLE 'test-grant-role1'; -- {ErrorCode 2204}
SHOW GRANTS FOR ROLE 'test-grant-role';
DROP ROLE 'test-grant-role';

DROP DATABASE `db01`;

0 comments on commit 8fabe4b

Please sign in to comment.