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 <[email protected]> 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! :)