@@ -503,6 +503,154 @@ impl PrivilegeAccess {
503503 Ok ( ( ) )
504504 }
505505
506+ async fn validate_table_index_access (
507+ & self ,
508+ catalog_name : & str ,
509+ db_name : & str ,
510+ table_name : & str ,
511+ ) -> Result < ( ) > {
512+ self . access_system_history (
513+ Some ( catalog_name) ,
514+ Some ( db_name) ,
515+ None ,
516+ UserPrivilegeType :: Alter ,
517+ ) ?;
518+
519+ self . validate_table_index_alter_or_super_access ( catalog_name, db_name, table_name)
520+ . await
521+ }
522+
523+ async fn validate_drop_table_index_access (
524+ & self ,
525+ catalog_name : & str ,
526+ db_name : & str ,
527+ table_name : & str ,
528+ ) -> Result < ( ) > {
529+ self . access_system_history (
530+ Some ( catalog_name) ,
531+ Some ( db_name) ,
532+ None ,
533+ UserPrivilegeType :: Drop ,
534+ ) ?;
535+
536+ match self
537+ . validate_table_index_alter_or_super_access ( catalog_name, db_name, table_name)
538+ . await
539+ {
540+ Ok ( ( ) ) => Ok ( ( ) ) ,
541+ Err ( err) if err. code ( ) == ErrorCode :: PERMISSION_DENIED => {
542+ match self
543+ . validate_access ( & GrantObject :: Global , UserPrivilegeType :: Drop , false , false )
544+ . await
545+ {
546+ Ok ( ( ) ) => Ok ( ( ) ) ,
547+ Err ( drop_err) if drop_err. code ( ) == ErrorCode :: PERMISSION_DENIED => Err ( err) ,
548+ Err ( drop_err) => Err ( drop_err) ,
549+ }
550+ }
551+ Err ( err) => Err ( err) ,
552+ }
553+ }
554+
555+ async fn validate_table_index_alter_or_super_access (
556+ & self ,
557+ catalog_name : & str ,
558+ db_name : & str ,
559+ table_name : & str ,
560+ ) -> Result < ( ) > {
561+ match self
562+ . validate_real_table_alter_access ( catalog_name, db_name, table_name)
563+ . await
564+ {
565+ Ok ( ( ) ) => Ok ( ( ) ) ,
566+ Err ( err) if err. code ( ) == ErrorCode :: PERMISSION_DENIED => {
567+ match self
568+ . validate_access ( & GrantObject :: Global , UserPrivilegeType :: Super , false , false )
569+ . await
570+ {
571+ Ok ( ( ) ) => Ok ( ( ) ) ,
572+ Err ( super_err) if super_err. code ( ) == ErrorCode :: PERMISSION_DENIED => Err ( err) ,
573+ Err ( super_err) => Err ( super_err) ,
574+ }
575+ }
576+ Err ( err) => Err ( err) ,
577+ }
578+ }
579+
580+ async fn validate_real_table_alter_access (
581+ & self ,
582+ catalog_name : & str ,
583+ db_name : & str ,
584+ table_name : & str ,
585+ ) -> Result < ( ) > {
586+ if self . ctx . is_temp_table ( catalog_name, db_name, table_name) {
587+ return Ok ( ( ) ) ;
588+ }
589+
590+ let tenant = self . ctx . get_tenant ( ) ;
591+ let catalog = self . ctx . get_catalog ( catalog_name) . await ?;
592+
593+ match self
594+ . validate_access (
595+ & GrantObject :: Table (
596+ catalog_name. to_string ( ) ,
597+ db_name. to_string ( ) ,
598+ table_name. to_string ( ) ,
599+ ) ,
600+ UserPrivilegeType :: Alter ,
601+ false ,
602+ false ,
603+ )
604+ . await
605+ {
606+ Ok ( ( ) ) => Ok ( ( ) ) ,
607+ Err ( err) if err. code ( ) == ErrorCode :: PERMISSION_DENIED => {
608+ match self
609+ . convert_to_id ( & tenant, & catalog, db_name, Some ( table_name) , false )
610+ . await
611+ {
612+ Ok ( ObjectId :: Table ( db_id, table_id) ) => {
613+ match self
614+ . validate_access (
615+ & GrantObject :: TableById ( catalog_name. to_string ( ) , db_id, table_id) ,
616+ UserPrivilegeType :: Alter ,
617+ false ,
618+ false ,
619+ )
620+ . await
621+ {
622+ Ok ( ( ) ) => Ok ( ( ) ) ,
623+ Err ( err) if err. code ( ) == ErrorCode :: PERMISSION_DENIED => {
624+ let current_user = self . ctx . get_current_user ( ) ?;
625+ let session = self . ctx . get_current_session ( ) ;
626+ let roles_name = session
627+ . get_all_effective_roles ( )
628+ . await ?
629+ . iter ( )
630+ . map ( |r| r. name . clone ( ) )
631+ . collect :: < Vec < _ > > ( )
632+ . join ( "," ) ;
633+ Err ( ErrorCode :: PermissionDenied ( format ! (
634+ "Permission denied: privilege [{:?}] is required on '{}'.'{}'.'{}' for user {} with roles [{}]" ,
635+ UserPrivilegeType :: Alter ,
636+ catalog_name,
637+ db_name,
638+ table_name,
639+ & current_user. identity( ) . display( ) ,
640+ roles_name,
641+ ) ) )
642+ }
643+ Err ( err) => Err ( err) ,
644+ }
645+ }
646+ Ok ( ObjectId :: Database ( _) ) => unreachable ! ( "table name is provided" ) ,
647+ Err ( err) => Err ( err. add_message ( "error on validating table index access" ) ) ,
648+ }
649+ }
650+ Err ( err) => Err ( err) ,
651+ }
652+ }
653+
506654 async fn validate_warehouse_ownership (
507655 & self ,
508656 warehouse : String ,
@@ -1403,13 +1551,15 @@ impl AccessChecker for PrivilegeAccess {
14031551 Plan :: DropDatabase ( plan) => {
14041552 self . validate_db_access ( & plan. catalog , & plan. database , UserPrivilegeType :: Drop , plan. if_exists ) . await ?;
14051553 }
1406- Plan :: UndropDatabase ( _)
1407- | Plan :: DropIndex ( _)
1408- | Plan :: DropTableIndex ( _) => {
1554+ Plan :: UndropDatabase ( _) | Plan :: DropIndex ( _) => {
14091555 // undroptable/db need convert name to id. But because of drop, can not find the id. Upgrade Object to Database.
14101556 self . validate_access ( & GrantObject :: Global , UserPrivilegeType :: Drop , false , false )
14111557 . await ?;
14121558 }
1559+ Plan :: DropTableIndex ( plan) => {
1560+ self . validate_drop_table_index_access ( & plan. catalog , & plan. database , & plan. table )
1561+ . await ?;
1562+ }
14131563 Plan :: CreateStage ( _) => {
14141564 self . validate_access ( & GrantObject :: Global , UserPrivilegeType :: Super , true , false )
14151565 . await ?;
@@ -1893,12 +2043,15 @@ impl AccessChecker for PrivilegeAccess {
18932043 | Plan :: RevertTable ( _)
18942044 | Plan :: AlterUDF ( _)
18952045 | Plan :: RefreshIndex ( _)
1896- | Plan :: RefreshTableIndex ( _)
18972046 | Plan :: AlterRole ( _)
18982047 | Plan :: AlterUser ( _) => {
18992048 self . validate_access ( & GrantObject :: Global , UserPrivilegeType :: Alter , false , false )
19002049 . await ?;
19012050 }
2051+ Plan :: RefreshTableIndex ( plan) => {
2052+ self . validate_table_index_access ( & plan. catalog , & plan. database , & plan. table )
2053+ . await ?;
2054+ }
19022055 Plan :: CopyIntoTable ( plan) => {
19032056 self . validate_stage_access ( & plan. stage_table_info . stage_info , UserPrivilegeType :: Read ) . await ?;
19042057 self . validate_table_access ( plan. catalog_info . catalog_name ( ) , & plan. database_name , & plan. table_name , UserPrivilegeType :: Insert , false , false ) . await ?;
@@ -1998,7 +2151,6 @@ impl AccessChecker for PrivilegeAccess {
19982151 | Plan :: DropPasswordPolicy ( _)
19992152 | Plan :: DescPasswordPolicy ( _)
20002153 | Plan :: CreateIndex ( _)
2001- | Plan :: CreateTableIndex ( _)
20022154 | Plan :: CreateNotification ( _)
20032155 | Plan :: DropNotification ( _)
20042156 | Plan :: DescNotification ( _)
@@ -2018,6 +2170,10 @@ impl AccessChecker for PrivilegeAccess {
20182170 self . validate_access ( & GrantObject :: Global , UserPrivilegeType :: Super , false , false )
20192171 . await ?;
20202172 }
2173+ Plan :: CreateTableIndex ( plan) => {
2174+ self . validate_table_index_access ( & plan. catalog , & plan. database , & plan. table )
2175+ . await ?;
2176+ }
20212177 Plan :: CreateDatamaskPolicy ( _) => {
20222178 self
20232179 . validate_access (
0 commit comments