Skip to content
This repository has been archived by the owner on Sep 24, 2023. It is now read-only.

Fix IntegrityError when user has multiple email addresses #29

Merged
merged 1 commit into from
Apr 20, 2018

Conversation

ralphje
Copy link
Contributor

@ralphje ralphje commented Jan 14, 2018

Since you can set up multiple email addresses for users, it is possible that sentry_ldap_auth updates the wrong email address when changing the UserEmail field.

Say, you have two UserEmail objects for an user, 'personal' and 'system-wide'. When 'personal' gets updated to "system-wide", this generates an IntegrityError because (user, email) is unique in the database, preventing logon.

Instead of changing the attribute, I add it to the list of the user's email addresses. There's no reliable way to remove an old email address. I also do not add any empty email addresses.

I doubt this entire structure is even necessary because when the 'email' attribute is set correctly on AUTH_LDAP_USER_ATTR_MAP this should all happen automatically, since Sentry has added a signal on User creation to automatically create the UserEmail object.

I do delete any lingering UserEmails that are empty (this is the case if the map is not set up correctly, since django-auth-ldap will then create a User object without an email address).

Since you can set up multiple email addresses for users, it is possible that sentry_ldap_auth updates the wrong email address when changing the UserEmail field. 

Say, you have two UserEmail objects for an user, 'personal' and 'system-wide'. When 'personal' gets updated to "system-wide", this generates an IntegrityError because (user, email) is unique in the database, preventing logon.

I doubt this entire structure is even necessary because when the 'email' attribute is set correctly on ``AUTH_LDAP_USER_ATTR_MAP`` this should all happen automatically.
Copy link

@aleksihakli aleksihakli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a small fix should be made to improve backwards compatibility. The django.db.models.Q object should be available in Django 1.6+, meaning the Sentry Django installation should have it.

userEmail.email = ldap_user.attrs.get('mail')[0]
email = ldap_user.attrs.get('mail')[0]
elif not hasattr(settings, 'AUTH_LDAP_DEFAULT_EMAIL_DOMAIN'):
email = ''

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the currently "empty" getsentry-ldap-auth email from ' ' to '', possibly leaving dangling database rows with email=' '.

email = username + '@' + settings.AUTH_LDAP_DEFAULT_EMAIL_DOMAIN

# django-auth-ldap may have accidentally created an empty email address
UserEmail.objects.filter(user=user, email='').delete()
Copy link

@aleksihakli aleksihakli Apr 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be something like

from django.db.models import Q

# ...

UserEmail.objects.filter(user=user, Q(email='') | Q(email=' ')).delete()

@aleksihakli
Copy link

@barronhagerman is it possible to get this baked into a new release, e.g. 2.6? We have ongoing issues with users inputting custom emails and failing authentication over LDAP afterwards.

Copy link
Contributor

@barronhagerman barronhagerman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I'm just getting around to this. I don't have the problem you've described, and I don't have a good environment to test it. However, I do think this should fix it without breaking something else. I'll try to get a release cut next week with this and the updates @aleksihakli brought up.

@barronhagerman barronhagerman merged commit 857394a into Banno:master Apr 20, 2018
barronhagerman pushed a commit that referenced this pull request Apr 20, 2018
Since you can set up multiple email addresses for users, it is possible that sentry_ldap_auth updates the wrong email address when changing the UserEmail field. 

Say, you have two UserEmail objects for an user, 'personal' and 'system-wide'. When 'personal' gets updated to "system-wide", this generates an IntegrityError because (user, email) is unique in the database, preventing logon.

I doubt this entire structure is even necessary because when the 'email' attribute is set correctly on ``AUTH_LDAP_USER_ATTR_MAP`` this should all happen automatically.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants