AuthTokenResult AuthService::processAuthToken(const std::string& token, AbstractUserDatabase& users) const { AUTO_PTR<AbstractUserDatabase::Transaction> t(users.startTransaction()); std::string hash = tokenHashFunction()->compute(token, std::string()); User user = users.findWithAuthToken(hash); if (user.isValid()) { std::string newToken = WRandom::generateId(tokenLength_); std::string newHash = tokenHashFunction()->compute(newToken, std::string()); int validity = user.updateAuthToken(hash, newHash); if (validity < 0) { /* * Old API, this is bad since we always extend the lifetime of the * token. */ user.removeAuthToken(hash); newToken = createAuthToken(user); validity = authTokenValidity_ * 60; } if (t.get()) t->commit(); return AuthTokenResult(AuthTokenResult::Valid, user, newToken, validity); } else { if (t.get()) t->commit(); return AuthTokenResult(AuthTokenResult::Invalid); } }
EmailTokenResult AuthService::processEmailToken(const std::string& token, AbstractUserDatabase& users) const { std::auto_ptr<AbstractUserDatabase::Transaction> tr(users.startTransaction()); std::string hash = tokenHashFunction()->compute(token, std::string()); User user = users.findWithEmailToken(hash); if (user.isValid()) { Token t = user.emailToken(); if (t.expirationTime() < WDateTime::currentDateTime()) { user.clearEmailToken(); if (tr.get()) tr->commit(); return EmailTokenResult::Expired; } switch (user.emailTokenRole()) { case User::LostPassword: user.clearEmailToken(); if (tr.get()) tr->commit(); return EmailTokenResult(EmailTokenResult::UpdatePassword, user); case User::VerifyEmail: user.clearEmailToken(); user.setEmail(user.unverifiedEmail()); user.setUnverifiedEmail(std::string()); if (tr.get()) tr->commit(); return EmailTokenResult(EmailTokenResult::EmailConfirmed, user); default: if (tr.get()) tr->commit(); return EmailTokenResult::Invalid; // Unreachable } } else { if (tr.get()) tr->commit(); return EmailTokenResult::Invalid; } }
User AuthService::identifyUser(const Identity& identity, AbstractUserDatabase& users) const { std::auto_ptr<AbstractUserDatabase::Transaction> t(users.startTransaction()); User user = users.findWithIdentity(identity.provider(), WString::fromUTF8(identity.id())); if (user.isValid()) { if (t.get()) t->commit(); return user; } /* * Scenarios to handle with respect to the email address. * * - in case we are doing email address verification * - existing user has same email address * - new email address is verified -> merge new identity and * simply login as that user [X] * - new email address is not verified -> send email to confirm * to merge the accounts when registring -> TODO * - in case we are not doing email address verification * - we'll simply error on a duplicate email address [X] */ if (!identity.email().empty()) { if (emailVerification_ && identity.emailVerified()) { user = users.findWithEmail(identity.email()); if (user.isValid()) { user.addIdentity(identity.provider(), identity.id()); if (t.get()) t->commit(); return user; } } } if (t.get()) t->commit(); return User(); }
AuthTokenResult AuthService::processAuthToken(const std::string& token, AbstractUserDatabase& users) const { std::auto_ptr<AbstractUserDatabase::Transaction> t(users.startTransaction()); std::string hash = tokenHashFunction()->compute(token, std::string()); User user = users.findWithAuthToken(hash); if (user.isValid()) { user.removeAuthToken(hash); std::string newToken = createAuthToken(user); if (t.get()) t->commit(); return AuthTokenResult(AuthTokenResult::Valid, user, newToken); } else return AuthTokenResult(AuthTokenResult::Invalid); }
void AuthService::lostPassword(const std::string& emailAddress, AbstractUserDatabase& users) const { /* * This will check that a user exists in the database, and if so, * send an email. */ User user = users.findWithEmail(emailAddress); if (user.isValid()) { std::string random = WRandom::generateId(randomTokenLength()); std::string hash = tokenHashFunction()->compute(random, std::string()); WDateTime expires = WDateTime::currentDateTime(); expires = expires.addSecs(emailTokenValidity() * 60); Token t(hash, expires); user.setEmailToken(t, User::LostPassword); sendLostPasswordMail(emailAddress, user, random); } }