-
-
Notifications
You must be signed in to change notification settings - Fork 387
Add non-empty constraint for UserSocialAuth uid #557
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
base: master
Are you sure you want to change the base?
Conversation
5f306dd
to
2a4d46a
Compare
Any thoughts on whether this could be accepted? |
I think it makes sense, but I'm not sure about splitting the constraint to |
I can move the constraint up to AbstractUserSocialAuth, i'm not familiar with the difference between AbstractUserSocialAuth and UserSocialAuth though. I'll have a look at the test failure. |
I'm not familiar with it either, I'm just curious about splitting the constraint from the field definition. |
It would probably work as long as the Meta-class of UserSocialAuth is also updated to explicitly subclass AbstractUserSocialAuth.Meta, like this: |
@stianjensen Can you please rebase this? As there was no other feedback, I think it's okay to merge as is, I just want to see the tests pass. |
a17f0d6
to
014f43e
Compare
Pushed up a rebased and updated version @nijel , but i can't figure out how to run the tests locally, can you approve CI for tests? |
migrations.AddConstraint( | ||
model_name="usersocialauth", | ||
constraint=models.CheckConstraint( | ||
condition=models.Q(("uid", ""), _negated=True), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fails with TypeError: __init__() got an unexpected keyword argument 'condition'
.
Perhaps need a more recent Django version and the dependencies need to be adjusted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, i'll need to use check to support 3.2 i see.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, i have check in the models.py but django generated condition because i used a newer django generating the migration. I'll modify it by hand to use check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
014f43e
to
cf38c01
Compare
There is also pre-commit fixing some formatting. Can you allow edits to the PR so that it can push the fixes? |
...and the constraint fails some checks:
|
cf38c01
to
1e1c733
Compare
Seems like i can't enable maintainer edits because my fork lives in an organization. Locally, ruff seems to pass but the local commands might not be the same that CI runs. I added an uid to the one test that failed on CI. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #557 +/- ##
==========================================
- Coverage 91.72% 91.63% -0.10%
==========================================
Files 39 41 +2
Lines 1172 1195 +23
Branches 144 67 -77
==========================================
+ Hits 1075 1095 +20
- Misses 72 74 +2
- Partials 25 26 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Django main fails now because check has been renamed to condition, but that change doesn't happen until django 6.0. |
1e1c733
to
c5de7dc
Compare
Aha, pre-commit run ruff-format --all-files was the magic incantation i needed. Crazy that ruff tells me no changes are needed, and yet it formats when i run ruff-format. |
Django main is tested against Django from Git. I don't mind dropping support for old Django versions if needed. |
Check was replaced with condition in 5.1 it seems, https://docs.djangoproject.com/en/5.1/ref/models/constraints/#django.db.models.CheckConstraint.condition, and 4.2 is still in LTS. |
That's unfortunate that it is impossible to write code which would work with both 4.2 and 6.0 as both will be supported at the same time by Django. For now, we can probably skip testing Django main (and replace it with 5.2b1), but we will need a solution for this later. That might be dropping support for Django < 5.1 once Django 5.0 is no longer supported. |
c5de7dc
to
ca76b29
Compare
So it seems like the migrations get generated with check regardless of you use check or condition, so as long as we set up the Metaclass to switch based on django-version. Pushed up a version with this now. |
Any empty uids are surely erroneous, and better to have integrity errors than having users start sharing accounts when logging in.
ca76b29
to
d0182d1
Compare
In #674 I'm dropping support for the oldest Django versions, but this will not help with this. Can you try discussing this compatibility issue at Django? Whether it is expected that the same code cannot work for both 4.2 and 6.0, while they will be supported at the same time. |
I actually did ask a related question to this previously and their answer then was 'squash old migrations or edit them': So I think the solution must be to add a version switch to the migration file as well, to make the kwargs to CheckConstraint dynamic. |
I've posted this at https://forum.djangoproject.com/t/reusable-library-and-incompatible-django-core-changes/40097, let's see if we get some feedback. I'm not really sure if it's better to include additional code for compatibility with Django 4.2 or drop support for it (we can disregard 5.0 as it is out of support as of April 2025). |
constraint=models.CheckConstraint( | ||
check=models.Q(("uid", ""), _negated=True), | ||
name="user_social_auth_uid_required", | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same django.VERSION
approach can be used here
constraint=models.CheckConstraint( | |
check=models.Q(("uid", ""), _negated=True), | |
name="user_social_auth_uid_required", | |
), | |
constraint=( | |
models.CheckConstraint(condition=~models.Q(uid=""), name="user_social_auth_uid_required") | |
if django.VERSION >= (5, 1) | |
else models.CheckConstraint(check=~models.Q(uid=""), name="user_social_auth_uid_required") | |
), |
if django.VERSION[0] < 6: | ||
constraints = [models.CheckConstraint(check=~models.Q(uid=""), name="user_social_auth_uid_required")] | ||
else: | ||
constraints = [models.CheckConstraint(condition=~models.Q(uid=""), name="user_social_auth_uid_required")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to favor the non-deprecated way instead
if django.VERSION[0] < 6: | |
constraints = [models.CheckConstraint(check=~models.Q(uid=""), name="user_social_auth_uid_required")] | |
else: | |
constraints = [models.CheckConstraint(condition=~models.Q(uid=""), name="user_social_auth_uid_required")] | |
if django.VERSION >= (5, 1): | |
constraints = [models.CheckConstraint(condition=~models.Q(uid=""), name="user_social_auth_uid_required")] | |
else: | |
constraints = [models.CheckConstraint(check=~models.Q(uid=""), name="user_social_auth_uid_required")] |
- Django 5.0 is no longer supported upstream. - Django 4.2 is still LTS, but it is no longer possible to keep compatibility with upcoming Django 6 and 4.2 (see python-social-auth#557). - Python 3.9 was supported only with Django 4.2.
As Django 5.0 is now out of support, I think it's time to drop support for 4.2 as well. LTS users can still use the older releases and it will be easier to move forward. See |
- Django 5.0 is no longer supported upstream. - Django 4.2 is still LTS, but it is no longer possible to keep compatibility with upcoming Django 6 and 4.2 (see #557). - Python 3.9 was supported only with Django 4.2.
Proposed changes
Any empty uids delivered by providers are surely erroneous, and better to have integrity errors than having users start sharing accounts when logging in.
A DB check constraint will catch issues like this one, and ensure that no matter the way a usersocialauth model is created, no empty uids can be inserted.
I'd say this is a bugfix mostly, but a breaking bugfix at that, as existing users of this library might have uid='' in their database by accident. These are real errors that those users will want to fix, and we should mention this upgrade in the changelog as a breaking change.
Types of changes
Please check the type of change your PR introduces:
Checklist
Put an
x
in the boxes that apply. You can also fill these out after creatingthe PR. If you're unsure about any of them, don't hesitate to ask. We're here to
help! This is simply a reminder of what we are going to look for before merging
your code.