2nd thoughts, here's the missing function in db.py One can't get an email back from LinkedIn so I set the email field to the user's LinkedIn id it also returns to set the registration_key so that my registration key can fire off (and clear this field once completed) - it is in the function registerLinkedInAgent() that it fails to clear this field.
from gluon.contrib.login_methods.oauth10a_account import OAuthAccount class LinkedInAccount(OAuthAccount): def get_user(self): import oauth2 as oauth if self.accessToken() is None: return None else: client = oauth.Client(self.consumer, self.accessToken()) resp, content = client.request('https://api.linkedin.com/ v1/people/~:(id,first-name,last-name)') if resp['status'] != '200': return None # TODO: check status; cannot get user info from gluon.contrib.login_methods.linkedin import Profile p = Profile() profile = p.create(content) # email must be unique return dict(first_name=profile.first_name, last_name=profile.last_name, registration_id=profile.id, registration_key=profile.id, email=profile.id) On Oct 28, 4:25 pm, Carl <carl.ro...@gmail.com> wrote: > I am trying to add a registration step when users login using OAuth > (LinkedIn in my example). > > a) am I taking a good approach? > b) why am I getting an exception when I try to write to my user table? > > From db.py: > auth.settings.table_user = db.define_table( > auth.settings.table_user_name, > db.Field('email', 'string', length=254, unique=True, notnull=True, > required=True, > requires = [IS_LOWER(), > IS_EMAIL(), > > IS_NOT_IN_DB(db,'%s.email'%auth.settings.table_user_name)]), > db.Field('password', 'password', length=512, readable=False, > label='Password', > requires = [CRYPT(key='***')]), > db.Field('registration_id', length=512, writable=False, > readable=False, default=''), > db.Field('registration_key', length=512, writable=False, > readable=False, default=''), > db.Field('first_name', 'string', length=128), > db.Field('last_name', 'string', length=128)) > > The rest is in default.py: > > def user: > auth.settings.login_next = > URL(r=request,f='registerLinkedInAgent') > > auth.settings.login_form=LinkedInAccount(globals(),CLIENT_ID,CLIENT_SECRET, > AUTH_URL, TOKEN_URL, ACCESS_TOKEN_URL) > return dict(form=auth()) > > I won't include LinkedInAccount() here but the issue I have is in > registerAgent(form) > > def registerLinkedInAgent(): > if auth.user.registration_key and len(auth.user.registration_key): > auth.add_membership(auth.id_group( 'agent'), auth.user.id) > > # here I do my once-on-registration calls > do_registration_stuff() > > # find current user's record and update registration key to an > empty string so this code isn't called again > users = > db(db.auth_user.id==auth.user.id).select(db.auth_user.ALL) > if users and len(users): > users[0].update_record({'registration_key''}) > redirect(URL('account')) > > The problem is I get "ValueError: need more than 1 value to unpack" . > Full trackback is below: > > Traceback (most recent call last): > File "E:\projects\workspace\TestEnvoy\web2py\gluon\restricted.py", > line 188, in restricted > exec ccode in environment > File "E:/projects/workspace/TestEnvoy/web2py/applications/init/ > controllers/default.py", line 1528, in <module> > File "E:\projects\workspace\TestEnvoy\web2py\gluon\globals.py", line > 96, in <lambda> > self._caller = lambda f: f() > File "E:/projects/workspace/TestEnvoy/web2py/applications/init/ > controllers/default.py", line 1132, in registerLinkedInAgent > users[0].update_record({'registration_key' : ''}) > File "E:\projects\workspace\TestEnvoy\web2py\gluon\sql.py", line > 3381, in <lambda> > colset.update_record = lambda _ = (colset, table, id), **a: > update_record(_, a) > File "E:\projects\workspace\TestEnvoy\web2py\gluon\sql.py", line > 3508, in update_record > (colset, table, id) = pack > ValueError: need more than 1 value to unpack > > If anyone needs greater explanation please complain and I'll add > more! :)