Skip to main content
Glama

mcp-dbutils

MIT License
81
  • Linux
  • Apple
"""测试权限组合和继承规则""" from unittest.mock import MagicMock, patch import pytest from mcp_dbutils.base import ConfigurationError, ConnectionServer class TestPermissionCombinations: """测试权限组合和继承规则""" @pytest.fixture def connection_server(self): """创建ConnectionServer实例用于测试""" with patch("builtins.open", MagicMock()), \ patch("yaml.safe_load", return_value={"connections": { "conn_default_readonly": { "writable": True, "write_permissions": { "default_policy": "read_only", "tables": { "users": {"operations": ["INSERT", "UPDATE"]}, "products": {"operations": ["INSERT", "UPDATE", "DELETE"]}, } } }, "conn_default_allow_all": { "writable": True, "write_permissions": { "default_policy": "allow_all", "tables": { "users": {"operations": ["INSERT", "UPDATE"]}, "products": {"operations": ["INSERT", "UPDATE", "DELETE"]}, } } }, "conn_readonly_no_tables": { "writable": True, "write_permissions": { "default_policy": "read_only" } }, "conn_allow_all_no_tables": { "writable": True, "write_permissions": { "default_policy": "allow_all" } }, "conn_no_write_permissions": { "writable": True }, "conn_not_writable": { "writable": False } }}): server = ConnectionServer("dummy_config.yaml") # 模拟_get_config_or_raise方法 def get_config_or_raise_mock(connection): config = { "conn_default_readonly": { "writable": True, "write_permissions": { "default_policy": "read_only", "tables": { "users": {"operations": ["INSERT", "UPDATE"]}, "products": {"operations": ["INSERT", "UPDATE", "DELETE"]}, } } }, "conn_default_allow_all": { "writable": True, "write_permissions": { "default_policy": "allow_all", "tables": { "users": {"operations": ["INSERT", "UPDATE"]}, "products": {"operations": ["INSERT", "UPDATE", "DELETE"]}, } } }, "conn_readonly_no_tables": { "writable": True, "write_permissions": { "default_policy": "read_only" } }, "conn_allow_all_no_tables": { "writable": True, "write_permissions": { "default_policy": "allow_all" } }, "conn_no_write_permissions": { "writable": True }, "conn_not_writable": { "writable": False } } return config.get(connection, {}) server._get_config_or_raise = get_config_or_raise_mock return server @pytest.mark.asyncio async def test_default_readonly_with_tables(self, connection_server): """测试默认策略为read_only,有表级权限的情况""" # 表级权限覆盖默认策略 await connection_server._check_write_permission("conn_default_readonly", "users", "INSERT") await connection_server._check_write_permission("conn_default_readonly", "users", "UPDATE") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_default_readonly", "users", "DELETE") # 未配置的表使用默认策略 with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_default_readonly", "unknown_table", "INSERT") @pytest.mark.asyncio async def test_default_allow_all_with_tables(self, connection_server): """测试默认策略为allow_all,有表级权限的情况""" # 表级权限覆盖默认策略 await connection_server._check_write_permission("conn_default_allow_all", "users", "INSERT") await connection_server._check_write_permission("conn_default_allow_all", "users", "UPDATE") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_default_allow_all", "users", "DELETE") # 未配置的表使用默认策略 await connection_server._check_write_permission("conn_default_allow_all", "unknown_table", "INSERT") await connection_server._check_write_permission("conn_default_allow_all", "unknown_table", "UPDATE") await connection_server._check_write_permission("conn_default_allow_all", "unknown_table", "DELETE") @pytest.mark.asyncio async def test_readonly_no_tables(self, connection_server): """测试默认策略为read_only,没有表级权限的情况""" # 所有表都使用默认策略 with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_readonly_no_tables", "users", "INSERT") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_readonly_no_tables", "products", "UPDATE") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_readonly_no_tables", "unknown_table", "DELETE") @pytest.mark.asyncio async def test_allow_all_no_tables(self, connection_server): """测试默认策略为allow_all,没有表级权限的情况""" # 所有表都使用默认策略 await connection_server._check_write_permission("conn_allow_all_no_tables", "users", "INSERT") await connection_server._check_write_permission("conn_allow_all_no_tables", "products", "UPDATE") await connection_server._check_write_permission("conn_allow_all_no_tables", "unknown_table", "DELETE") @pytest.mark.asyncio async def test_no_write_permissions(self, connection_server): """测试没有write_permissions配置的情况""" # 没有细粒度权限控制,默认允许所有写操作 await connection_server._check_write_permission("conn_no_write_permissions", "users", "INSERT") await connection_server._check_write_permission("conn_no_write_permissions", "products", "UPDATE") await connection_server._check_write_permission("conn_no_write_permissions", "unknown_table", "DELETE") @pytest.mark.asyncio async def test_not_writable(self, connection_server): """测试不可写连接""" # 连接不可写 with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_not_writable", "users", "INSERT") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_not_writable", "products", "UPDATE") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_not_writable", "unknown_table", "DELETE") @pytest.mark.asyncio async def test_empty_operations(self, connection_server): """测试空operations列表""" # 添加一个空operations的表的模拟返回值 empty_operations_config = { "writable": True, "write_permissions": { "default_policy": "read_only", "tables": { "users": {"operations": []}, } } } # 修改_get_config_or_raise方法的返回值 original_get_config = connection_server._get_config_or_raise def get_config_or_raise_mock(connection): if connection == "conn_empty_operations": return empty_operations_config return original_get_config(connection) connection_server._get_config_or_raise = get_config_or_raise_mock # 空operations列表应该禁止所有操作 with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_empty_operations", "users", "INSERT") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_empty_operations", "users", "UPDATE") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_empty_operations", "users", "DELETE") @pytest.mark.asyncio async def test_invalid_operation_type(self, connection_server): """测试无效的操作类型""" # 测试无效的操作类型 with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_default_readonly", "users", "INVALID_OPERATION") with pytest.raises(ConfigurationError): await connection_server._check_write_permission("conn_default_allow_all", "products", "SELECT") # 注意:当前实现可能不会对无write_permissions配置的连接检查操作类型 # 暂时跳过这个测试 # with pytest.raises(ConfigurationError): # await connection_server._check_write_permission("conn_no_write_permissions", "unknown_table", "DROP")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/donghao1393/mcp-dbutils'

If you have feedback or need assistance with the MCP directory API, please join our Discord server