diff --git a/edb/schema/roles.py b/edb/schema/roles.py index 23c191973af..d560ad28803 100644 --- a/edb/schema/roles.py +++ b/edb/schema/roles.py @@ -18,7 +18,7 @@ from __future__ import annotations -from typing import Optional, Type, List, TYPE_CHECKING +from typing import Optional, Type, List, Union, overload, TYPE_CHECKING from edgedb import scram @@ -30,6 +30,7 @@ from . import annos as s_anno from . import delta as sd from . import inheriting +from . import name as sn from . import objects as so from . import utils @@ -195,6 +196,60 @@ class RenameRole(RoleCommand, sd.RenameObject[Role]): class AlterRole(RoleCommand, inheriting.AlterInheritingObject[Role]): astnode = qlast.AlterRole + @overload + def get_object( + self, + schema: s_schema.Schema, + context: sd.CommandContext, + *, + name: Optional[sn.Name] = None, + default: Union[Role, so.NoDefaultT] = so.NoDefault, + sourcectx: Optional[qlast.Span] = None, + ) -> Role: + ... + + @overload + def get_object( + self, + schema: s_schema.Schema, + context: sd.CommandContext, + *, + name: Optional[sn.Name] = None, + default: None = None, + sourcectx: Optional[qlast.Span] = None, + ) -> Optional[Role]: + ... + + def get_object( + self, + schema: s_schema.Schema, + context: sd.CommandContext, + *, + name: Optional[sn.Name] = None, + default: Union[Role, so.NoDefaultT, None] = so.NoDefault, + sourcectx: Optional[qlast.Span] = None, + ) -> Optional[Role]: + # On an ALTER ROLE edgedb, if 'edgedb' doesn't exist, fall + # back to 'admin'. This mirrors what we do for login and + # avoids breaking setup scripts. + if name is None and str(self.classname) == 'edgedb': + try: + return super().get_object( + schema, + context, + sourcectx=sourcectx, + ) + except errors.InvalidReferenceError: + name = sn.UnqualName('admin') + + return super().get_object( + schema, + context, + name=name, + default=default, + sourcectx=sourcectx, + ) + @classmethod def _cmd_tree_from_ast( cls, diff --git a/tests/test_server_ops.py b/tests/test_server_ops.py index 8b41df81c41..cf07b8247c8 100644 --- a/tests/test_server_ops.py +++ b/tests/test_server_ops.py @@ -419,6 +419,19 @@ async def test_server_only_bootstraps_once(self): finally: await con.aclose() + async def test_server_alter_role_fallback(self): + with tempfile.TemporaryDirectory() as temp_dir: + async with tb.start_edgedb_server( + data_dir=temp_dir, + default_auth_method=args.ServerAuthMethod.Scram, + bootstrap_command='ALTER ROLE edgedb SET password := "first";' + ) as sd: + con = await sd.connect(password='first') + try: + await con.query_single('SELECT 1') + finally: + await con.aclose() + async def test_server_ops_bogus_bind_addr_in_mix(self): async with tb.start_edgedb_server( bind_addrs=('host.invalid', '127.0.0.1',),