-
-
Notifications
You must be signed in to change notification settings - Fork 101
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
Integrity error (#93) #95
Conversation
Ah, I forgot to do a |
Codecov Report
@@ Coverage Diff @@
## master #95 +/- ##
=========================================
Coverage ? 82.35%
=========================================
Files ? 7
Lines ? 408
Branches ? 0
=========================================
Hits ? 336
Misses ? 72
Partials ? 0
Continue to review full report at Codecov.
|
I have figured that the real reason this would happen so often to us is because of a group name in AD being changed from groups_to_remove = set(django_groups) - set(claim_groups)
groups_to_add = set(claim_groups) - set(django_groups) it would result in the following: DEBUG 2020-01-21 11:04:26,562 django_auth_adfs User removed from group 'myGroup'
DEBUG 2020-01-21 11:04:26,564 django_auth_adfs Created group 'MyGroup'
DEBUG 2020-01-21 11:04:26,575 django_auth_adfs User added to group 'MyGroup' In other words, on every request to the site, it would do a full clean, making it get an I you'd like, I could rather raise a different PR that simply does this. This won't solve the issue for integrity errors when a user has a different group set, though. How ever, I have made the checks case insensitive when looking for groups in this PR. |
It depends whether Django's group names are case sensitive or not. And whether there are situation where it could be case sensitive (e.g. when someone extends django's authentication). |
Looking at the logs you posted, it does look like Django's groups are case insensitive themselves: The code determines the group needs to be deleted, but when "creating" the group, it actually retrieves the one with the lower case Strange... That's quite an unexpected quirk from Django. |
You are correct. If I do >>> Group.objects.get(name='mygroup')
<Group: MyGroup> EDIT: Same with >>> group, created = Group.objects.get_or_create(name='mygroup')
>>> created
False
>>> group
<Group: MyGroup> |
Let me see where this case insensitivity comes from. I always though you need to do it explicitly with |
When I test, getting groups by name is case sensitive (or at least on the latest 2.2.x version). So it looks like something modified the behavior of you Django setup >>> Group.objects.get_or_create(name="MyTestGroup")
(<Group: MyTestGroup>, True)
>>> Group.objects.get(name="MyTestGroup")
<Group: MyTestGroup>
>>> Group.objects.get(name="MyTestGROUP")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/vagrant/.venv/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/vagrant/.venv/lib/python3.7/site-packages/django/db/models/query.py", line 408, in get
self.model._meta.object_name
django.contrib.auth.models.Group.DoesNotExist: Group matching query does not exist.
>>> Group.objects.get_or_create(name="MyTestGROUP")
(<Group: MyTestGROUP>, True)
>>> Group.objects.get(name="MyTestGROUP")
<Group: MyTestGROUP> What is your Django version? What other packages did you install? What other apps are activated in Django? |
Wait, that's really interesting. I tested on my DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'PASSWORD': '',
'NAME': 'django-adfs-test',
'USER': 'test',
},
} Driver used here is from django.contrib.auth.models import Group
Group.objects.get_or_create(name="MyTestGroup")
(<Group: MyTestGroup>, True)
Group.objects.get(name="MyTestGroup")
<Group: MyTestGroup>
Group.objects.get(name="MyTestGROUP")
<Group: MyTestGroup> How ever, with a DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
} from django.contrib.auth.models import Group
Group.objects.get_or_create(name="MyTestGroup")
(<Group: MyTestGroup>, True)
Group.objects.get(name="MyTestGroup")
<Group: MyTestGroup>
Group.objects.get(name="MyTestGROUP")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/aa545@i04.local/Documents/projects/personal/django-guid/venv/lib/python3.8/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/aa545@i04.local/Documents/projects/personal/django-guid/venv/lib/python3.8/site-packages/django/db/models/query.py", line 415, in get
raise self.model.DoesNotExist(
django.contrib.auth.models.Group.DoesNotExist: Group matching query does not exist. EDIT: Seems like I need to fix my databases. Link EDIT2: Confirmed that all my databases uses collation |
Looks like it's a "feature" of MySQL: https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html |
Yeah, in Django I can do this (when I run my tests): DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'PASSWORD': '',
'USER': 'test',
'TEST': {
'NAME': 'django-adfs-test',
'CHARSET': 'utf8mb4',
'COLLATION': 'utf8mb4_0900_as_cs',
},
},
} Now, the question still stand though. Since multiple groups with different case sensitivity is not possible in AD( |
To recap:
The missing link here, is "why" ADFS changes the group name. Are you sure the field ADFS uses as the group's name is the same as what you used to create the groups initially? Ideally, the groups you create in Django would match with what ADFS sends back. |
Recap:
I have no strong feelings about a solution here, I can fix the tables on my end and add a little note in your documentation about this for MySQL users. |
My preference goes to an entry in the FAQ to be honest. (If you get this error, then...) Implementing case insensitivity is going to trigger other issues I'm afraid. |
Perfect. I'll document it in the FAQ after work or tomorrow if you don't mind. The rest of the code, any comments on that? |
Remove the lower case changes and I'll have another look. |
Done. I'll write a little note about it in the docs tonight. I'm just happy that I finally figured out why the API were slow for a selected few people. |
Codecov Report
@@ Coverage Diff @@
## master #95 +/- ##
==========================================
- Coverage 82.77% 82.69% -0.09%
==========================================
Files 7 7
Lines 418 416 -2
==========================================
- Hits 346 344 -2
Misses 72 72
Continue to review full report at Codecov.
|
Any thoughts or comments? |
…dn't touch ¯\_(ツ)_/¯
This is still causing issues for us. Did you end up checking out the solution? :) |
We're experiencing a lot of these errors (same company but different projects). Would really appreciate if this could be looked at soon, as we're currently forced to switch to Jonas' fork, just based on the number of errors we're seeing from this in production. |
Integrity error (snok#93)
Attempt to fix #93. All tests pass and I've confirmed that it works locally.
Please let me know if you have any concerns or comments.