TZM / tzm-blade

ZMGC Application empowers members with on-line tools, by providing a free infrastructure to easily exchange, analyse and disseminate information in a scalable, non-blocking manner using only Open Source software build by the community for the community. It is about building lasting and deep solidarity versus cheap and fast Facebook or Twitter campaigns
www.zmgc.net
GNU General Public License v3.0
4 stars 8 forks source link

Federated Login does not work correctly #40

Open nkhine opened 10 years ago

nkhine commented 10 years ago

currently this does not work too well in that the Federated Login give errors and when a user uses the local registration they are unable to set their password, so we need to:

1/. fix the local registration process - so that: a) an email is sent with verification string - this works. b) when a user clicks on verification link, they are authenticated - this also works - but i want the user to be taken to the set password page so that they can set their password c) if user already exists on the database, a reset password verification link is sent - this also works - but again when they click on this, they should be taken to the reset password page

2/. Federated login - ensure all federated login works - currently only Mozilla Personna works

In the current MongoDB i have a field provider, which keeps a list of the authentication providers, so:

> db.users.find().pretty()
{
  "__v" : 0,
  "_id" : ObjectId("5254540e75b4990704000001"),
  "active" : true,
  "email" : "norman@domain.tld",
  "groups" : "member",
 "lockUntil" : 0,
 "loginAttempts" : 0,
 "name" : "First Name",
 "password" : "$2a$10$eSGqa6qAuzVmoevqrtmXBunzJA/3ix4CmnMww/6SySnET5c.CKmCe",
 "provider" : [
    "local",
    "github",
    "google"
  ],
"surname" : "Last Name",
"tokenExpires" : 1381346239856,
"tokenString" : "QnBLPUcgCPQD6XXub4HWhXrLIfPluxQSPOTv8c9ujBTC81fTB79NtIdbW0t_DwzM"
}

this way if a user logins with local and a Federated Login, we don't create duplicate record in the database but simply update the existing record.

mikeumus commented 10 years ago

So local, github and google are the federated logins that need to be working as per point 2 above? May you link to the file and/or line that deals with federated logins? Thanks.

nkhine commented 10 years ago

well it uses the node passport module and the config is here https://github.com/TZM/tzm-blade/blob/master/app/config/passport.coffee

then you have https://github.com/TZM/tzm-blade/blob/master/app/config/apps.coffee#L149 which uses the user model https://github.com/TZM/tzm-blade/blob/master/app/models/user/user.coffee

ofShard commented 10 years ago

I highly recommend making the password step entirely optional. Allow users to use only the federated login without the need for creating a password. And if you also want to provide the option of logging in through email (username)/password, then you can allow users to configure this on a Create/Change your Password page in the admin interface.

The user could potentially add other providers to their account in a similar fashion as well.

nkhine commented 10 years ago

i like to keep the process as it is, similar to how it is at http://stackoverflow.com/users/login

the user is presented with both options, to either login using Federated Logins or Create and account http://stackoverflow.com/users/login#create-account

although the difference is that we verify the email whereas on stackoverflow they add their password on the Registration Form - perhaps we could do this, but we have to take account of when a user forgets their password.

ofShard commented 10 years ago

Well that was quite an effort getting the repo to build and run on my local machine, haha. Which federated logins would you like me to test? I have google, yahoo, and persona auth working so far in my local tests.

Also, is the user supposed to be emailed a password reset link when they login (and create an account) via oauth/passport, or only when the login through the Local strategy? I noticed a password is being created in the DB for the user regardless of account creation method.

nkhine commented 10 years ago

can you test github, persona, google, yahoo, facebook, linkedin for the federated logins. see - https://github.com/TZM/tzm-blade/blob/master/app/config/passport.coffee also please look at the twitter, although twitter does not send the email address back so we won't be able to store this, this is why it has been commented out!

no, the user is not suppose to get a reset password link when they login/register using Federated Login. this is used only when a user checks the forgot password checkbox then the application checks if the email exists in the Db if it exists the application sends a reset password link and if not then it creates an account and adds the user to the Db.

one use case is when a user uses a Federated Login to first create an account and then tries to register/login using local strategy, by checking forgot password/ create account checkbox, in this case we will need to set the local strategy as being the current login method and send a verification email token and then set a password.

nkhine commented 10 years ago

github still returns a number instead of the email

{
    "tokenExpires": 1392409945102,
    "tokenString": "UxH-hsSnGnHHYYITlJgsU8ROMykQ0lge_f65Ara169IQQ24EqfQlXXRSn1SGH9v8",
    "email": "85080",
    "_id": {
        "$oid": "52fd2bd8bfd7090f00bb3a5d"
    },
    "provider": [
        "github"
    ],
    "lockUntil": 0,
    "loginAttempts": 0,
    "groups": "member",
    "surname": "",
    "name": "Norman Khine",
    "active": true,
    "password": "$2a$10$S43v06nfTYqVix4VS.Q.S.BzYLTk4oYkWv.o/QZcAP4hW7aw8am56",
    "__v": 0
}
nkhine commented 10 years ago

alsoi get this error when i try to login using the Facebook federated login:

2014-02-13T20:51:12.845816+00:00 app[web.1]: req.session._csrf is deprecated, use req.csrfToken() instead
2014-02-13T20:51:12.938929+00:00 app[web.1]: [Function]
2014-02-13T20:51:12.948014+00:00 app[web.1]: GET /social/facebook 302 111ms - 372b
2014-02-13T20:51:13.604466+00:00 app[web.1]: req.session._csrf is deprecated, use req.csrfToken() instead
2014-02-13T20:51:13.604873+00:00 app[web.1]: [Function]
2014-02-13T20:51:13.605064+00:00 app[web.1]: FACEBOOK CALLBACK  true
2014-02-13T20:51:14.155782+00:00 app[web.1]:
2014-02-13T20:51:14.156041+00:00 app[web.1]: /app/app/config/passport.coffee:95
2014-02-13T20:51:14.156391+00:00 app[web.1]:         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
2014-02-13T20:51:14.156457+00:00 app[web.1]:                                 ^
2014-02-13T20:51:14.325190+00:00 app[web.1]: TypeError: Cannot read property 'length' of undefined
2014-02-13T20:51:14.325190+00:00 app[web.1]:   at /app/app/config/passport.coffee:66:17
2014-02-13T20:51:14.325190+00:00 app[web.1]:   at process._tickCallback (node.js:415:13)
2014-02-13T20:51:14.325190+00:00 app[web.1]:
2014-02-13T20:51:14.357644+00:00 app[web.1]: worker 14 died

and for yahoo, if you already login as a user with a yahoo email and then use federated login, you get:

2014-02-13T20:55:10.647759+00:00 app[web.1]: GET / 200 45ms - 25.24kb
2014-02-13T20:55:12.863546+00:00 app[web.1]: req.session._csrf is deprecated, use req.csrfToken() instead
2014-02-13T20:55:12.863546+00:00 app[web.1]: [Function]
2014-02-13T20:55:12.966270+00:00 app[web.1]: arguments in yahoo strategy
2014-02-13T20:55:12.967835+00:00 app[web.1]: [ { value: 'aqoon88@yahoo.fr' } ]
2014-02-13T20:55:12.967835+00:00 app[web.1]: { '0': 'https://me.yahoo.com/a/2ctJIVJxvJYXHVbFaewLAoGyOpw-#da52c',
2014-02-13T20:55:12.967835+00:00 app[web.1]:   '1':
2014-02-13T20:55:12.967835+00:00 app[web.1]:    { displayName: 'Yevgeny Zamyatin',
2014-02-13T20:55:12.967835+00:00 app[web.1]:      emails: [ [Object] ],
2014-02-13T20:55:12.967835+00:00 app[web.1]:      name: { familyName: undefined, givenName: undefined } },
2014-02-13T20:55:12.967835+00:00 app[web.1]:   '2': [Function: verified] }
2014-02-13T20:55:13.183593+00:00 app[web.1]: MongoError: E11000 duplicate key error index: heroku_app16459358.users.$email_1  dup key: { : "aqoon88@yahoo.fr" }
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at Object.toError (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/utils.js:110:11)
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at /app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/collection/core.js:212:24
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at Server.Base._callHandler (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:442:41)
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at /app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:485:18
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at [object Object].MongoReply.parseBody (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at [object Object].<anonymous> (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:443:20)
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at [object Object].EventEmitter.emit (events.js:95:17)
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at [object Object].<anonymous> (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:191:13)
2014-02-13T20:55:13.183593+00:00 app[web.1]:   at [object Object].EventEmitter.emit (events.js:98:17)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at Socket.<anonymous> (/app/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:418:22)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at Socket.EventEmitter.emit (events.js:95:17)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at Socket.<anonymous> (_stream_readable.js:746:14)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at Socket.EventEmitter.emit (events.js:92:17)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at emitReadable_ (_stream_readable.js:408:10)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at emitReadable (_stream_readable.js:404:5)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at readableAddChunk (_stream_readable.js:165:9)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at Socket.Readable.push (_stream_readable.js:127:10)
2014-02-13T20:55:13.183915+00:00 app[web.1]:   at TCP.onread (net.js:526:21)
2014-02-13T20:55:13.183915+00:00 app[web.1]:
2014-02-13T20:55:13.186172+00:00 app[web.1]: GET /social/yahoocallback?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&openid.return_to=http%3A%2F%2Fwww.zmgc.net%2Fsocial%2Fyahoocallback&openid.claimed_id=https%3A%2F%2Fme.yahoo.com%2Fa%2F2ctJIVJxvJYXHVbFaewLAoGyOpw-%23da52c&openid.identity=https%3A%2F%2Fme.yahoo.com%2Fa%2F2ctJIVJxvJYXHVbFaewLAoGyOpw-&openid.assoc_handle=VyxtGUhoNFWISumDKNc6LO9inNhH_E3SuB9P5.04wJaezRjRxwHeKOQrf4cSzb11KDCuT3phMxexHDuL3pk9U2efkJsMm5Dsrt9cbCgzE1Jfgov_X0eP7EU6B02vZSZoYaI5XQ--&openid.realm=http%3A%2F%2Fwww.zmgc.net&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ax.mode=fetch_response&openid.ax.value.fullname=Yevgeny%20Zamyatin&openid.ax.value.email=aqoon88%40yahoo.fr&openid.response_nonce=2014-02-13T20%3A55%3A12ZURt3lL2Y1l4MjTV5j0bWpec6eyXzJqu1KQ--&openid.signed=assoc_handle%2Cclaimed_id%2Cidentity%2Cmode%2Cns%2Cop_endpoint%2Cresponse_nonce%2Creturn_to%2Csigned%2Cax.value.fullname%2Cax.type.fullname%2Cax.value.email%2Cax.type.email%2Cns.ax%2Cax.mode%2Cpape.auth_level.nist&openid.op_
2014-02-13T20:55:13.186172+00:00 app[web.1]: endpoint=https%3A%2F%2Fopen.login.yahooapis.com%2Fopenid%2Fop%2Fauth&openid.ax.type.fullname=http%3A%2F%2Faxschema.org%2FnamePerson&openid.ax.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.pape.auth_level.nist=0&openid.sig=92WWhvDE0RMto8pDzHKk6tVNFTz6mdeZJfbF9%2BjrTMQ%3D 500 515ms - 21b
2014-02-13T20:55:13.185612+00:00 heroku[router]: at=info method=GET path=/social/yahoocallback?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&openid.return_to=http%3A%2F%2Fwww.zmgc.net%2Fsocial%2Fyahoocallback&openid.claimed_id=https%3A%2F%2Fme.yahoo.com%2Fa%2F2ctJIVJxvJYXHVbFaewLAoGyOpw-%23da52c&openid.identity=https%3A%2F%2Fme.yahoo.com%2Fa%2F2ctJIVJxvJYXHVbFaewLAoGyOpw-&openid.assoc_handle=VyxtGUhoNFWISumDKNc6LO9inNhH_E3SuB9P5.04wJaezRjRxwHeKOQrf4cSzb11KDCuT3phMxexHDuL3pk9U2efkJsMm5Dsrt9cbCgzE1Jfgov_X0eP7EU6B02vZSZoYaI5XQ--&openid.realm=http%3A%2F%2Fwww.zmgc.net&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ax.mode=fetch_response&openid.ax.value.fullname=Yevgeny%20Zamyatin&openid.ax.value.email=aqoon88%40yahoo.fr&openid.response_nonce=2014-02-13T20%3A55%3A12ZURt3lL2Y1l4MjTV5j0bWpec6eyXzJqu1KQ--&openid.signed=assoc_handle%2Cclaimed_id%2Cidentity%2Cmode%2Cns%2Cop_endpoint%2Cresponse_nonce%2Creturn_to%2Csigned%2Cax.value.fullname%2Cax.type.fullname%2Cax.value.email%2Cax.type.email%2Cns.ax%2Cax.mode%2Cpape.auth_level.nist&openid.op_endpoint=https%3A%2F%2Fopen.login.yahooapis.com%2Fopenid%2Fop%2Fauth&openid.ax.type.fullname=http%3A%2F%2Faxschema.org%2FnamePerson&openid.ax.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.pape.auth_level.nist=0&openid.sig=92WWhvDE0RMto8pDzHKk6tVNFTz6mdeZJfbF9%2BjrTMQ%3D host=www.zmgc.net request_id=5cedd49d-0ec2-42a0-b76a-47df18df5195 fwd="92.40.121.107" dyno=web.1 connect=2ms service=529ms status=500 bytes=21
nkhine commented 10 years ago

there is one more issue, in that if a user uses a Federated Login to register for the first time, their account is setup and the 'provider' is filled with the name of the provider.

if then for some reason they choose to request or create an account, the application will check that the user exists on the db, and will then send a resetpassword link - this is OK and correct although when the user resets their password, the provider list does not include the local provider.

for completeness, please fix this

ofShard commented 10 years ago

Note that I've only fixed the github email login. I haven't touched any other login yet.