pallets-eco / flask-social

OAuth Provider Integration for Flask-Security
MIT License
245 stars 103 forks source link

AttributeError: 'Connection' object has no attribute 'user' #47

Closed tedmiston closed 10 years ago

tedmiston commented 10 years ago

I'm attempting a standard implementation per the current tutorial of flask-social 1.6.2 with Flask 0.10.1 with SQLAlchemyDatastore running on localhost. After a user has authorized the app on Facebook and attempts to log in, this error occurs.

The only spot I've diverged from the quickstart is adding full_name to the Connection class because it was getting returned by the Facebook provider and throwing an error not being in the model.

class Connection(db.Model):
    ...
    full_name = db.Column(db.String(255))

I thought perhaps it was actually looking for user id, but digging a little deeper to login_user(...) in flask_login.py states Logs a user in. You should pass the actual user object to this.

I'm not sure if I'm doing something wrong in my implementation, or if this is actually a bug.

Full traceback after clicking the Login with Facebook button:

Traceback (most recent call last):
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask_social/views.py", line 215, in login_callback
    return login_handler(response, provider, query)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask_security/decorators.py", line 205, in wrapper
    return f(*args, **kwargs)
  File "/Users/taylor/Documents/ce2/venv/lib/python2.7/site-packages/flask_social/views.py", line 171, in login_handler
    user = connection.user
AttributeError: 'Connection' object has no attribute 'user'
mattupstate commented 10 years ago

@tedmiston Have you checked your database to see if the proper fields were set? You may also want to set nullable=False on the user_id field of the Connection class and see if any issues arise when a user authorizes a connection with Facebook.

tedmiston commented 10 years ago

@mattupstate In the connection table,

In the user table:

The initial authorization appears to be happening properly to make this database row and on Facebook to give the permissions, but the error occurs when I click the Login with Facebook button while not logged for a Facebook account that's already authorized.

(I've also tried clearing the app permissions on Facebook and following the same steps to ensure I can reproduce it.)

Edit: Also, I don't think it should matter, but I'm currently using SQLite behind SQLAlchemy.

eriktaubeneck commented 10 years ago

You'll want to create a SQLAlchemy Relationship to connect the Connection and the User. This will produce a Connection.user_id and automagically created a Connection.user reference that looks up the user from the user_id.

mattupstate commented 10 years ago

Oh right, do you have user = db.relationship('User') on the Connection class? Is that missing from the docs?

eriktaubeneck commented 10 years ago

Just looked. It has user_id = db.Column(db.Integer, db.ForeignKey('user.id')) on the Connection. We should update that.

eriktaubeneck commented 10 years ago

I can do that, I'll ping you @mattupstate when it's up so you can refresh the pythonhosted.org page.

tedmiston commented 10 years ago

@mattupstate So I do not have that on the connection class (and it is not in the docs at https://pythonhosted.org/Flask-Social/).

I took a minute to download the old flask-social-example, and saw this line that wasn't in the docs:

class User(db.Model, UserMixin):
    ...
    connections = db.relationship('Connection',
            backref=db.backref('user', lazy='joined'), cascade="all")

Adding this appears to fix the error on my end. Is this equivalent to what you suggested?

eriktaubeneck commented 10 years ago

Yep, that will work as well.

eriktaubeneck commented 10 years ago

@mattupstate updated on master and merged into develop.

tedmiston commented 10 years ago

Awesome. Thanks for the quick responses!

Edit: I guess shouldn't close this so abruptly in case you guys would like to add any additional comments.

amostsai commented 7 years ago

it's work. thanks a lot