转授权
This commit is contained in:
1 parent
39480e2f2e
commit
a8e85b7ac0
18 files changed
+284
-57
No files matched your search
@@ -415,7 +415,7 @@ checkResolvedWith db outer q = case q of
|
||||
DropUser name -> checkUserName name
|
||||
CreateRole name -> checkRoleName name
|
||||
DropRole name -> checkRoleName name
|
||||
GrantPrivileges privs obj role -> do
|
||||
GrantPrivileges privs obj role _ -> do
|
||||
mapM_ checkPrivilege privs
|
||||
checkGrantObject obj
|
||||
checkRoleName role
|
||||
|
||||
@@ -41,8 +41,8 @@ data Statement
|
||||
| CreateRole String
|
||||
-- | 删角色:连同它的授权与成员一起删
|
||||
| DropRole String
|
||||
-- | GRANT 权限 ON 表 TO 角色
|
||||
| GrantPrivileges [String] String String
|
||||
-- | GRANT 权限 ON 表 TO 角色,末位表示带 WITH GRANT OPTION
|
||||
| GrantPrivileges [String] String String Bool
|
||||
-- | REVOKE 权限 ON 表 FROM 角色
|
||||
| RevokePrivileges [String] String String
|
||||
-- | GRANT 角色 TO 用户:给用户加角色
|
||||
|
||||
@@ -464,6 +464,10 @@ privilegeName =
|
||||
grantObject :: Parser String
|
||||
grantObject = ("*" <$ symbol "*") <|> tableName
|
||||
|
||||
-- | 可选的 WITH GRANT OPTION
|
||||
grantOption :: Parser Bool
|
||||
grantOption = (True <$ try (keyword "with" *> keyword "grant" *> keyword "option")) <|> pure False
|
||||
|
||||
-- | 读 GRANT:带 ON 的授权限,不带的加角色
|
||||
grantStatement :: Parser Statement
|
||||
grantStatement = do
|
||||
@@ -474,7 +478,7 @@ grantStatement = do
|
||||
keyword "on"
|
||||
obj <- grantObject
|
||||
keyword "to"
|
||||
GrantPrivileges privs obj <$> userName
|
||||
GrantPrivileges privs obj <$> userName <*> grantOption
|
||||
, GrantRole <$> userName <*> (keyword "to" *> sepBy1 userName (symbol ","))
|
||||
]
|
||||
|
||||
|
||||
@@ -683,13 +683,21 @@ main = hspec $ do
|
||||
|
||||
it "parses privilege grants on one table, on another database's table or on everything" $ do
|
||||
parseStatement "GRANT SELECT ON users TO analyst"
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT"] "users" "analyst")
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT"] "users" "analyst" False)
|
||||
parseStatement "grant select, insert on users to analyst"
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT", "INSERT"] "users" "analyst")
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT", "INSERT"] "users" "analyst" False)
|
||||
parseStatement "GRANT ALL ON sales.orders TO analyst"
|
||||
`shouldBe` Right (GrantPrivileges ["ALL"] "sales.orders" "analyst")
|
||||
`shouldBe` Right (GrantPrivileges ["ALL"] "sales.orders" "analyst" False)
|
||||
parseStatement "GRANT DELETE ON * TO analyst"
|
||||
`shouldBe` Right (GrantPrivileges ["DELETE"] "*" "analyst")
|
||||
`shouldBe` Right (GrantPrivileges ["DELETE"] "*" "analyst" False)
|
||||
|
||||
it "parses WITH GRANT OPTION on a privilege grant" $ do
|
||||
parseStatement "GRANT SELECT ON users TO analyst WITH GRANT OPTION"
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT"] "users" "analyst" True)
|
||||
parseStatement "grant select, insert on * to analyst with grant option"
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT", "INSERT"] "*" "analyst" True)
|
||||
parseStatement "GRANT SELECT ON users TO analyst WITH"
|
||||
`shouldSatisfy` isLeft
|
||||
|
||||
it "parses REVOKE symmetrically" $ do
|
||||
parseStatement "REVOKE SELECT ON users FROM analyst"
|
||||
@@ -717,7 +725,9 @@ main = hspec $ do
|
||||
(parseStatement "CREATE ROLE select" >>= prepare testDB) `shouldSatisfy` isLeft
|
||||
(parseStatement "DROP ROLE insert" >>= prepare testDB) `shouldSatisfy` isLeft
|
||||
(parseStatement "GRANT SELECT ON users TO analyst" >>= prepare testDB)
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT"] "users" "analyst")
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT"] "users" "analyst" False)
|
||||
(parseStatement "GRANT SELECT ON users TO analyst WITH GRANT OPTION" >>= prepare testDB)
|
||||
`shouldBe` Right (GrantPrivileges ["SELECT"] "users" "analyst" True)
|
||||
(parseStatement "GRANT SELECT ON users TO select" >>= prepare testDB) `shouldSatisfy` isLeft
|
||||
(parseStatement "REVOKE SELECT ON users FROM analyst" >>= prepare testDB)
|
||||
`shouldBe` Right (RevokePrivileges ["SELECT"] "users" "analyst")
|
||||
|
||||
@@ -230,7 +230,12 @@ pub fn reserved_table(table: &str) -> bool {
|
||||
}
|
||||
|
||||
/// 服务自己的角色与授权表名
|
||||
pub const PRIVILEGE_TABLES: [&str; 3] = ["__system_roles", "__system_grants", "__system_members"];
|
||||
pub const PRIVILEGE_TABLES: [&str; 4] = [
|
||||
"__system_roles",
|
||||
"__system_grants",
|
||||
"__system_grant_options",
|
||||
"__system_members",
|
||||
];
|
||||
|
||||
/// 是不是服务自己经请求通道读写的系统表
|
||||
pub fn internal_table(table: &str) -> bool {
|
||||
|
||||
@@ -1756,8 +1756,11 @@ fn privilege_tables_are_reachable_but_account_table_is_not() -> Result<(), Box<d
|
||||
let (_server, _data) = start_server();
|
||||
let mut c = connect()?;
|
||||
request_ok(&mut c, serde_json::json!({"method":"create_table","database":"system","table":"__system_roles","columns":[{"name":"id","ty":"int"},{"name":"name","ty":"str"}]}))?;
|
||||
request_ok(&mut c, serde_json::json!({"method":"create_table","database":"system","table":"__system_grant_options","columns":[{"name":"id","ty":"int"},{"name":"role","ty":"str"}]}))?;
|
||||
let scanned: serde_json::Value = serde_json::from_str(&send(&mut c, r#"{"method":"scan","database":"system","table":"__system_roles"}"#))?;
|
||||
assert_eq!(scanned["status"], "rows", "{scanned}");
|
||||
let options: serde_json::Value = serde_json::from_str(&send(&mut c, r#"{"method":"scan","database":"system","table":"__system_grant_options"}"#))?;
|
||||
assert_eq!(options["status"], "rows", "{options}");
|
||||
let denied: serde_json::Value = serde_json::from_str(&send(&mut c, r#"{"method":"scan","database":"system","table":"__system_users"}"#))?;
|
||||
assert_eq!(denied["status"], "error", "{denied}");
|
||||
assert!(
|
||||
@@ -1772,6 +1775,7 @@ fn privilege_tables_are_reachable_but_account_table_is_not() -> Result<(), Box<d
|
||||
.map(|one| one.as_str().unwrap_or(""))
|
||||
.collect();
|
||||
assert!(tables.contains(&"__system_roles"), "授权表要在字典里: {listed}");
|
||||
assert!(tables.contains(&"__system_grant_options"), "转授权表要在字典里: {listed}");
|
||||
assert!(!tables.contains(&"__system_users"), "账号表不能露面: {listed}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user