Repository: edgedb/edgedb

Issue:
ISE: `unimplemented auth method: NoneType` when inserting new user on clean instance
<!-- Please search existing issues to avoid creating duplicates. -->
- EdgeDB Version: 1-beta3-451baf4
- OS Version: ubuntu 18.04

Steps to Reproduce:

1. initialize new project with new `EdgeDB` instance in docker with `edgedb project init`
2. login into EdgeDB shell using `edgedb` command and create new user with password:
```
CREATE SUPERUSER ROLE edgedb_scram {
    SET password := 'edgedb_scram_password'
};

CONFIGURE INSTANCE INSERT Auth {
    user := 'edgedb_scram',
    method := (INSERT SCRAM),
    priority := 2
};
```
3. exit current shell session and try running `edgedb` command again to login into shell
```
$ edgedb
edgedb error: Error authenticating: ERROR: InternalServerError: unimplemented auth method: NoneType
  Hint: This is most likely a bug in EdgeDB. Please consider opening an issue ticket at https://github.com/edgedb/edgedb/issues/new?template=bug_report.md
  Server traceback:
      Traceback (most recent call last):
        File "edb/server/protocol/binary.pyx", line 1689, in edb.server.protocol.binary.EdgeConnection.main
        File "edb/server/protocol/binary.pyx", line 445, in auth
      edb.errors.InternalServerError: unimplemented auth method: NoneType
```

As I understand it, this is because the default user (`edgedb`) created by the EdgeDB bootstrap process is not being added to `cfg::Auth`. This can be verified by selecting the existing `cfg::Auth` objects before inserting a new one:
```
SELECT cfg::Auth {
    user,
    method,
    priority
};
```
The output will be an empty set (`{}`).

But in any case, user should not receive such error from the EdgeDB server in case of authentication failure. I would rather expect something like `AuthenticationError: no authentication method configured for the "edgedb" role` or something similar.

It's possible I missed something about roles configuration, but that part of EdgeDB is poorly documented right now, IMO.


Discussion:
Yeah, this is a bug, huge thanks for reporting it

Resolving patch:
diff --git a/edb/server/server.py b/edb/server/server.py
--- a/edb/server/server.py
+++ b/edb/server/server.py
@@ -1191,6 +1191,10 @@ async def get_auth_method(self, user):
                 if match:
                     return auth.method
 
+        raise errors.AuthenticationError(
+            f"no authentication method configured for {user!r} role"
+        )
+
     def get_sys_query(self, key):
         return self._sys_queries[key]
 


Test patch:
diff --git a/tests/test_server_auth.py b/tests/test_server_auth.py
--- a/tests/test_server_auth.py
+++ b/tests/test_server_auth.py
@@ -158,6 +158,57 @@ async def test_server_auth_01(self):
         finally:
             await self.con.query("DROP ROLE bar")
 
+    async def test_server_auth_02(self):
+        try:
+            await self.con.query('''
+                CREATE SUPERUSER ROLE foo {
+                    SET password := 'foo-pass';
+                }
+            ''')
+
+            await self.con.query('''
+                CREATE SUPERUSER ROLE bar {
+                    SET password := 'bar-pass';
+                }
+            ''')
+
+            await self.con.query('''
+                CONFIGURE INSTANCE INSERT Auth {
+                    comment := 'test-02',
+                    priority := 0,
+                    method := (INSERT SCRAM),
+                    user := 'foo',
+                }
+            ''')
+
+            # good password with configured Auth
+            conn = await self.connect(
+                user='foo',
+                password='foo-pass',
+            )
+            await conn.aclose()
+
+            # good password but Auth is not configured
+            with self.assertRaisesRegex(
+                    edgedb.AuthenticationError,
+                    "no authentication method configured for 'bar' role"):
+                await self.connect(
+                    user='bar',
+                    password='bar-pass'
+                )
+        finally:
+            await self.con.query('''
+                CONFIGURE INSTANCE RESET Auth FILTER .comment = 'test-02'
+            ''')
+
+            await self.con.query('''
+                DROP ROLE foo;
+            ''')
+
+            await self.con.query('''
+                DROP ROLE bar;
+            ''')
+
     async def test_long_role_name(self):
         with self.assertRaisesRegex(
                 edgedb.SchemaDefinitionError,