Skip to content
This repository has been archived by the owner on Feb 22, 2024. It is now read-only.

Unique Oauth connections for users #44

Closed
jquacinella opened this issue Apr 6, 2014 · 7 comments
Closed

Unique Oauth connections for users #44

jquacinella opened this issue Apr 6, 2014 · 7 comments

Comments

@jquacinella
Copy link

Is there a way to ensure that users who register or connect with an Oauth account are not using this Oauth'ed account more than once across the system? In other words, can we prevent users from connecting or using their Twitter account on multiple accounts on our site? I tried googling and searching the docs, to no avail. I assume this would be a good feature for most sites.

@eriktaubeneck
Copy link
Collaborator

If you are using a SQL datastore, you can set a unique constraint on provider_id and provider_user_id. These types of constraints are typically part of the datastore, not part of the application.

@mattupstate
Copy link
Collaborator

@jquacinella
Copy link
Author

@mattupstate I am not sure if the code you linked to is related to what I was talking about, as that code seems to handle connections. Not registrations, which is what I was trying to prevent. Then again, I don't know the innards of the code so maybe I am wrong.

I think what @eriktaubeneck said was what I was thinking. I added:

__table_args__ = (db.UniqueConstraint('provider_id', 'provider_user_id', name='_providerid_userid_uc'), {})

but it didn't seem to do much. However, I was using sqlite and not MySQL (which I am now). I'll check this out again and see if it works. If so, I'll submit a PR for a documentation update.

@jquacinella
Copy link
Author

Adding a unique constraint on those columns helps, as instead of letting the same OAuth account be connected to two different accound, I now get an error from Flask when doing so (with somenumbers replacing my ID):

IntegrityError: (IntegrityError) (1062, "Duplicate entry 'twitter-somenumbers' for key '_providerid_userid_uc'") 'INSERT INTO connections (user_id, provider_id, provider_user_id, access_token, secret, full_name, display_name, profile_url, image_url, rank) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' (u'4', 'twitter', 'somenumbers', 'somenumbers-randomstring', 'another-random-string', 'twitter-handle', '@'twitter-handle', 'http://twitter.com/'twitter-handle', 'https://pbs.twimg.com/profile_images/etc/etc.jpeg', None)

The lines from the trace back that seem most useful are:

File "/home/james/Development/Credacious.com/credacious-flask/flask-env/lib/python2.7/site-packages/flask_social/views.py", line 38, in _commit

_datastore.commit()

File "/home/james/Development/Credacious.com/credacious-flask/flask-env/lib/python2.7/site-packages/flask_security/datastore.py", line 31, in commit

self.db.session.commit()

I am a bit of a newbie at Flask. Is there a way to catch this Exception at the app level, or would we need to add error handling in Flask-Security?

@eriktaubeneck
Copy link
Collaborator

Not all users will want this to be unique (and the error will depend on which sort of Connection you are using) so it should be handled in your app. Just put the operation that raises the error in a try/except block, and then surface some sort of error message to the user that it's already connected to an account.

@jquacinella
Copy link
Author

Sorry for not getting back to this. I understand what you are saying, but when you say "Just put the operation that raises the error in a try/except block," ... the code that does this is in Flask-Social itself. So I do not think we want to change the modue based on what you said. So my question is, can this be caught at the app level and if so, how?

@eriktaubeneck
Copy link
Collaborator

If you application is set up similar to the Flask-Social-Example, then when in the view where the user is created, the commit will be the top of the stack trace that causes the error to occur. (In Flask-Social-Example, that happens here.) If you change that to something like:

try:
    ds.commit()
except IntegrityError:
    #flash a warning or something

that should take care of the issue.

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

No branches or pull requests

3 participants