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

Upgrading to 5.3 breaks down completely #693

Open
ionelmc opened this issue Dec 19, 2024 · 1 comment
Open

Upgrading to 5.3 breaks down completely #693

ionelmc opened this issue Dec 19, 2024 · 1 comment

Comments

@ionelmc
Copy link

ionelmc commented Dec 19, 2024

Seems the new user-configurable connections have broken migrations - even trying to list the connections will fail with something like:

[2024-12-19 15:02:09.399] django.request (ERROR) Internal Server Error: /manage/explorer/databaseconnection/
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/dist-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/contrib/admin/options.py", line 688, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/utils/decorators.py", line 134, in _wrapper_view
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/views/decorators/cache.py", line 62, in _wrapper_view_func
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/contrib/admin/sites.py", line 242, in inner
    return view(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/utils/decorators.py", line 134, in _wrapper_view
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/contrib/admin/options.py", line 2065, in changelist_view
    "selection_note": _("0 of %(cnt)s selected") % {"cnt": len(cl.result_list)},
                                                           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 380, in __len__
    self._fetch_all()
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 1881, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 121, in __iter__
    for row in compiler.results_iter(results):
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/sql/compiler.py", line 1500, in apply_converters
    value = converter(value, expression, connection)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/fields.py", line 182, in from_db_value
    return self._load(force_bytes(value))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/fields.py", line 120, in _load
    return pickle.loads(self._fernet.decrypt(value, self.ttl))
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/utils/crypto.py", line 160, in decrypt
    data = self.signer.unsign(data, ttl)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/core/signing.py", line 324, in unsign
    raise BadSignature('Signature "%r" does not match' % binascii.b2a_base64(sig))
django.core.signing.BadSignature: Signature "b'......\n'" does not match

I have these versions:

django==4.2.17 
django-cryptography-django5==2.2 
django-sql-explorer==5.3 

Sadly enough this is hard to clean up manually as even DatabaseConnection.objects.all().delete() fails with:

>>> DatabaseConnection.objects.all().delete()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 1147, in delete
    collector.collect(del_query)
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/deletion.py", line 284, in collect
    new_objs = self.add(
               ^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/deletion.py", line 126, in add
    if not objs:
           ^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 412, in __bool__
    self._fetch_all()
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 1881, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/query.py", line 121, in __iter__
    for row in compiler.results_iter(results):
  File "/usr/local/lib/python3.12/dist-packages/django/db/models/sql/compiler.py", line 1500, in apply_converters
    value = converter(value, expression, connection)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/fields.py", line 182, in from_db_value
    return self._load(force_bytes(value))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/fields.py", line 120, in _load
    return pickle.loads(self._fernet.decrypt(value, self.ttl))
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/utils/crypto.py", line 160, in decrypt
    data = self.signer.unsign(data, ttl)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/dist-packages/django_cryptography/core/signing.py", line 324, in unsign
    raise BadSignature('Signature "%r" does not match' % binascii.b2a_base64(sig))
django.core.signing.BadSignature: Signature "b'......\n'" does not match

(i have removed the signature value from the tracebacks, it was a base64 encoded value if it matters)

So going forward I have truncated the explorer_querylog and explorer_databaseconnection tables using dbshell and I am trying to see what is allowed in /manage/explorer/databaseconnection/add/ and to my dismay I see that everything is allowed, and the extra field doesn't even have a help_text to indicate what sort of value should be there. First off, I think that while this might be useful for some projects, it's a terrible idea to allow users to connect to anything, with any connection option they like in general. I would like to have a restricted mode that worked exactly like in 5.2.0, something that completely restricts users and available connections only come from settings. Yes, superuser in django admin == user. It's still an user, sorry. I don't want superusers do bad stuff :-)

@chrisclark
Copy link
Collaborator

hi there - sorry for the trouble! I'm not totally sure what the problem is re: the error trace. I will think about it...

As for connection management, that is a configurable permission. See this bit of code:
https://github.com/explorerhq/sql-explorer/blob/master/explorer/app_settings.py#L74

You can simply set:
EXPLORER_PERMISSION_CONNECTIONS = lamba u: false
in your settings file to restrict users from connection management.

I agree the 'extras' thing is a bit nasty. I'll think about how to improve. The idea behind it is to support a variety of 'long tail' DB drivers for django (see: MS SQL Server) that might have weird additional connection parameters. But yeah, I don't love it either.

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