Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable use of separate connection for running queries and powering sql-explorer #675

Closed
WillNilges opened this issue Sep 18, 2024 · 6 comments

Comments

@WillNilges
Copy link

This might be a bit of an XY problem. I am trying to enable normal users to make read-only (SELECT) queries against only the models of my Django database. To accomplish this, I have created a migration to create a read-only ROLE in my Postgres DB that only has SELECT privileges on those tables. However, this prevents the explorer from working. The schema preview, autocomplete, and actually running queries results in an error: permission denied for table authtoken_token.

If I allow SELECT on the following tables, it works:

public.authtoken_token;

public.django_admin_log;

public.django_content_type;

public.django_migrations;

public.explorer_databaseconnection;

public.explorer_val;

public.explorer_val;

public.explorer_;

public.explorer_v;

public.explorer_explorervalue;

public.explorer_promptlog;

public.explorer_query;

public.explorer_queryfavorite;

public.explorer_querylog;

public.flags_flagstate;

It's clear that this project is doing stuff on its own with this role. I would like to give it its own role, and then use a separate role for queries, ideally on a per-user basis.

TL;DR: Is there any way to only allow people to run queries on certain tables, without being able to see sensitive tables like authtoken_token?

@WillNilges
Copy link
Author

WillNilges commented Sep 18, 2024

I am aware of the blacklist functionality, but I would like to implement this protection at the database level if possible. Also, adding auth to SQL_BLACKLIST did not work 😔

@chrisclark
Copy link
Collaborator

@WillNilges can you please share the stacktrace? I'd like to see which line in shema.py is throwing the error. Basically, i need to know whether it is connection.introspection.table_names or connection.introspection.get_table_description.

If it's the second, I think it's quite fixable and would be happy to make this work. Otherwise...I'd have to think about how to approach it. Solvable I'm sure, but not totally obvious how to do it.

Good find.

@WillNilges
Copy link
Author

Sure thing!

Here's what the role has access to:

meshdb=# select
 *
from information_schema.role_table_grants
where grantee='meshdb_ro'
;
 grantor |  grantee  | table_catalog | table_schema |             table_name             | privilege_type | is_grantable | with_hierarchy
---------+-----------+---------------+--------------+------------------------------------+----------------+--------------+----------------
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_los                        | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_hooks_celeryserializerhook | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | django_session                     | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_link                       | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_accesspoint                | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_sector                     | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_device                     | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_building_nodes             | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_node                       | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_install                    | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_building                   | SELECT         | NO           | YES
 meshdb  | meshdb_ro | meshdb        | public       | meshapi_member                     | SELECT         | NO           | YES

This, out of the following

meshdb=# select
 *
from information_schema.role_table_grants
where privilege_type = 'SELECT'
and table_schema = 'public'
meshdb-# and grantee = 'meshdb';
 grantor | grantee | table_catalog | table_schema |             table_name             | privilege_type | is_grantable | with_hierarchy
---------+---------+---------------+--------------+------------------------------------+----------------+--------------+----------------
 meshdb  | meshdb  | meshdb        | public       | django_migrations                  | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | django_content_type                | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | auth_permission                    | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | auth_group                         | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | auth_group_permissions             | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | auth_user                          | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | auth_user_groups                   | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | auth_user_user_permissions         | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | django_admin_log                   | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | authtoken_token                    | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | explorer_promptlog                 | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | explorer_query                     | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | explorer_queryfavorite             | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | explorer_querylog                  | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | explorer_explorervalue             | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | explorer_databaseconnection        | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | flags_flagstate                    | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_los                        | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_hooks_celeryserializerhook | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | django_session                     | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_link                       | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_accesspoint                | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_sector                     | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_device                     | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_building_nodes             | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_node                       | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_install                    | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_building                   | SELECT         | YES          | YES
 meshdb  | meshdb  | meshdb        | public       | meshapi_member                     | SELECT         | YES          | YES
(29 rows)

Here's what happens when I load up the playground with that role:

image


[18/Sep/2024 19:58:37] "GET /explorer/play/ HTTP/1.1" 200 5858
Internal Server Error: /explorer/schema/readonly
Traceback (most recent call last):
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.InsufficientPrivilege: permission denied for table authtoken_token


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/decorators/clickjacking.py", line 38, in wrapper_view
    resp = view_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/schema.py", line 18, in dispatch
    return super().dispatch(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/auth.py", line 36, in dispatch
    return super().dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/schema.py", line 24, in get
    schema = schema_info(connection)
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 73, in schema_info
    return build_schema_cache_async(connection_alias)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/tasks.py", line 107, in build_schema_cache_async
    ret = build_schema_info(connection_alias)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 112, in build_schema_info
    table_description = connection.introspection.get_table_description(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/postgresql/introspection.py", line 112, in get_table_description
    cursor.execute(
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 102, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.ProgrammingError: permission denied for table authtoken_token

Internal Server Error: /explorer/schema.json/readonly
Traceback (most recent call last):
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.InsufficientPrivilege: permission denied for table authtoken_token


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/auth.py", line 36, in dispatch
    return super().dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/schema.py", line 43, in get
    return JsonResponse(schema_json_info(connection))
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 57, in schema_json_info
    si = schema_info(connection_alias) or []
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 73, in schema_info
    return build_schema_cache_async(connection_alias)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/tasks.py", line 107, in build_schema_cache_async
    ret = build_schema_info(connection_alias)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 112, in build_schema_info
    table_description = connection.introspection.get_table_description(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/postgresql/introspection.py", line 112, in get_table_description
    cursor.execute(
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 102, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.ProgrammingError: permission denied for table authtoken_token

[18/Sep/2024 19:58:37] "GET /explorer/schema/readonly HTTP/1.1" 500 174891
[18/Sep/2024 19:58:37] "GET /explorer/schema.json/readonly HTTP/1.1" 500 163784

Here's the trace when I try to submit a query anyway.

Internal Server Error: /explorer/play/
Traceback (most recent call last):
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.InsufficientPrivilege: permission denied for table authtoken_token


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/auth.py", line 36, in dispatch
    return super().dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/query.py", line 51, in post
    return self.render_with_sql(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/query.py", line 77, in render_with_sql
    query_viewmodel(
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/views/utils.py", line 87, in query_viewmodel
    "schema_json": schema_json_info(query.connection if query else None),
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 57, in schema_json_info
    si = schema_info(connection_alias) or []
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 73, in schema_info
    return build_schema_cache_async(connection_alias)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/tasks.py", line 107, in build_schema_cache_async
    ret = build_schema_info(connection_alias)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/explorer/schema.py", line 112, in build_schema_info
    table_description = connection.introspection.get_table_description(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/postgresql/introspection.py", line 112, in get_table_description
    cursor.execute(
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 102, in execute
    return super().execute(sql, params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/wilnil/Code/nycmeshnet/meshdb/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.ProgrammingError: permission denied for table authtoken_token

[18/Sep/2024 20:00:42] "POST /explorer/play/ HTTP/1.1" 500 177721

It looks like it's an issue with get_table_description.

    table_description = connection.introspection.get_table_description(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^```
                        
Good news, right? 😄 

@chrisclark
Copy link
Collaborator

Ah! Yeah great. Super easy to fix. I’ll see if I can address it tomorrow. I’ll probably forward-fix it in 5.3 and do a final release of that. Lots of good things in that version.

Thanks much!

@chrisclark
Copy link
Collaborator

I'm fixing this now -- but in the meantime you could set EXPLORER_SCHEMA_EXCLUDE_TABLE_PREFIXES to be a list of the tables the connection does not have permission for, and that should also fix it. Eg. in settings.py

EXPLORER_SCHEMA_EXCLUDE_TABLE_PREFIXES = [
    "authtoken_",
    "django_",
    "auth_",
    "contenttypes_",
    "sessions_",
    "admin_"
]

That should do the trick, with no changes to the app itself.

@chrisclark chrisclark mentioned this issue Sep 23, 2024
@chrisclark
Copy link
Collaborator

Fix has been merged into the 5.3 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants