/** * Validates the user access data. */ protected function validateUser() { try { $this->user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($this->username, $this->password); } catch (UserInputException $e) { // TODO: create an option for the authentication with email address if (true) { if ($e->getField() == 'username') { try { $this->user = EmailUserAuthentication::getInstance()->loginManually($this->username, $this->password); } catch (UserInputException $e2) { if ($e2->getField() == 'username') throw $e; throw $e2; } } else { throw $e; } } else { throw $e; } } }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); // user accepted the connection if (isset($_GET['code'])) { try { // fetch access_token $request = new HTTPRequest('https://github.com/login/oauth/access_token', array(), array('client_id' => StringUtil::trim(GITHUB_PUBLIC_KEY), 'client_secret' => StringUtil::trim(GITHUB_PRIVATE_KEY), 'code' => $_GET['code'])); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } // validate state, validation of state is executed after fetching the access_token to invalidate 'code' if (!isset($_GET['state']) || $_GET['state'] != WCF::getSession()->getVar('__githubInit')) { throw new IllegalLinkException(); } WCF::getSession()->unregister('__githubInit'); parse_str($content, $data); // check whether the token is okay if (isset($data['error'])) { throw new IllegalLinkException(); } // check whether a user is connected to this github account $user = $this->getUser($data['access_token']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.github.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { try { // fetch userdata $request = new HTTPRequest('https://api.github.com/user?access_token=' . $data['access_token']); $request->execute(); $reply = $request->getReply(); $userData = JSON::decode(StringUtil::trim($reply['body'])); } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } WCF::getSession()->register('__3rdPartyProvider', 'github'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__githubUsername', $userData['login']); WCF::getSession()->register('__githubToken', $data['access_token']); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { WCF::getSession()->register('__githubData', $userData); WCF::getSession()->register('__username', $userData['login']); // check whether user has entered a public email if (isset($userData) && isset($userData['email']) && $userData['email'] !== null) { WCF::getSession()->register('__email', $userData['email']); } else { try { $request = new HTTPRequest('https://api.github.com/user/emails?access_token=' . $data['access_token']); $request->execute(); $reply = $request->getReply(); $emails = JSON::decode(StringUtil::trim($reply['body'])); // handle future response as well a current response (see. http://developer.github.com/v3/users/emails/) if (is_string($emails[0])) { $email = $emails[0]; } else { $email = $emails[0]['email']; foreach ($emails as $tmp) { if ($tmp['primary']) { $email = $tmp['email']; } break; } } WCF::getSession()->register('__email', $email); } catch (SystemException $e) { } } WCF::getSession()->register('__githubToken', $data['access_token']); // we assume that bots won't register on github first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined or any other error that may occur if (isset($_GET['error'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.github.login.error.' . $_GET['error'])); } // start auth by redirecting to github $token = StringUtil::getRandomID(); WCF::getSession()->register('__githubInit', $token); HeaderUtil::redirect("https://github.com/login/oauth/authorize?client_id=" . rawurlencode(StringUtil::trim(GITHUB_PUBLIC_KEY)) . "&scope=" . rawurlencode('user:email') . "&state=" . $token); $this->executed(); exit; }
/** * login * * @param String $loginName * @param String $password * @return Boolean return true when login success. */ public function login($login = '', $password = '', $anonymous = 0, $push = 0) { /* test bypass for SSO begin */ /* $user = User::getUserByUsername('testuser'); $userSession = (get_class($user) == 'wcf\data\user\User' ? $user : new wcf\data\user\User(null, null, $user)); if ($userSession && $userSession->userID) { WCF::getSession()->changeUser($userSession); HeaderUtil::setCookie('cookieHash', SessionHandler::getInstance()->sessionID); MbqMain::$oMbqAppEnv->oCurrentUser = $userSession; $this->initOCurMbqEtUser(); return true; } else { return false; } */ /* test bypass for SSO end */ //refer wcf\acp\form\LoginForm::validateUser() try { $oUser = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($login, $password); } catch (UserInputException $e) { if ($e->getField() == 'username') { try { $oUser = EmailUserAuthentication::getInstance()->loginManually($login, $password); } catch (UserInputException $e2) { //if ($e2->getField() == 'username') throw $e; //throw $e2; //return $e2->getMessage(); } } return $e->getMessage(); } if (!$oUser || !$oUser->userID) { return false; } //ref wcf\form\LoginForm::save() // set cookies //UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($oUser, $loginName, $password); // change user return $this->doneLogin($oUser); }
/** * Creates a new session. */ protected function create() { $spiderID = null; if ($this->sessionEditorClassName == 'wcf\\data\\session\\SessionEditor') { // get spider information $spiderID = $this->getSpiderID(UserUtil::getUserAgent()); if ($spiderID !== null) { // try to use existing session if (($session = $this->getExistingSpiderSession($spiderID)) !== null) { $this->user = new User(null); $this->session = $session; return; } } } // create new session hash $sessionID = StringUtil::getRandomID(); // get user automatically $this->user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginAutomatically(call_user_func(array($this->sessionClassName, 'supportsPersistentLogins'))); // create user if ($this->user === null) { // no valid user found // create guest user $this->user = new User(null); } else { if (!$this->supportsVirtualSessions) { // delete all other sessions of this user call_user_func(array($this->sessionEditorClassName, 'deleteUserSessions'), array($this->user->userID)); } } $createNewSession = true; if ($this->supportsVirtualSessions) { // find existing session $session = call_user_func(array($this->sessionClassName, 'getSessionByUserID'), $this->user->userID); if ($session !== null) { // inherit existing session $this->session = $session; $this->loadVirtualSession(true); $createNewSession = false; } } if ($createNewSession) { // save session $sessionData = array('sessionID' => $sessionID, 'userID' => $this->user->userID, 'ipAddress' => UserUtil::getIpAddress(), 'userAgent' => UserUtil::getUserAgent(), 'lastActivityTime' => TIME_NOW, 'requestURI' => UserUtil::getRequestURI(), 'requestMethod' => !empty($_SERVER['REQUEST_METHOD']) ? substr($_SERVER['REQUEST_METHOD'], 0, 7) : ''); if ($spiderID !== null) { $sessionData['spiderID'] = $spiderID; } try { $this->session = call_user_func(array($this->sessionEditorClassName, 'create'), $sessionData); } catch (DatabaseException $e) { // MySQL error 23000 = unique key // do not check against the message itself, some weird systems localize them if ($e->getCode() == 23000 && $this->supportsVirtualSessions) { // find existing session $session = call_user_func(array($this->sessionClassName, 'getSessionByUserID'), $this->user->userID); if ($session === null) { // MySQL reported a unique key error, but no corresponding session exists, rethrow exception throw $e; } else { // inherit existing session $this->session = $session; $this->loadVirtualSession(true); } } else { // unrelated to user id throw $e; } } $this->firstVisit = true; $this->loadVirtualSession(true); } }
/** * @see \wcf\page\IPage::assignVariables() */ public function assignVariables() { parent::assignVariables(); WCF::getTPL()->assign(array('useCookies' => $this->useCookies, 'supportsPersistentLogins' => UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins(), 'loginController' => LinkHandler::getInstance()->getLink('Login'))); }
/** * @see \wcf\form\IForm::save() */ public function save() { AbstractForm::save(); // get options $saveOptions = $this->optionHandler->save(); $registerVia3rdParty = true; $avatarURL = ''; if (isset($this->ttid_profile['avatar_url']) && !empty($this->ttid_profile['avatar_url'])) { $avatarURL = $this->ttid_profile['avatar_url']; } $this->additionalFields['languageID'] = $this->languageID; if (LOG_IP_ADDRESS) { $this->additionalFields['registrationIpAddress'] = WCF::getSession()->ipAddress; } // generate activation code $addDefaultGroups = true; if ($this->verified !== true && REGISTER_ACTIVATION_METHOD != 0 || $this->verified === true && REGISTER_ACTIVATION_METHOD == 2 && !WBB_TAPATALK_REG_AUTO_APPROVAL) { $activationCode = UserRegistrationUtil::getActivationCode(); $this->additionalFields['activationCode'] = $activationCode; $addDefaultGroups = false; $this->groupIDs = UserGroup::getGroupIDsByType(array(UserGroup::EVERYONE, UserGroup::GUESTS)); } // check gravatar support if (MODULE_GRAVATAR && Gravatar::test($this->email)) { $this->additionalFields['enableGravatar'] = 1; } // create user $data = array('data' => array_merge($this->additionalFields, array('username' => $this->username, 'email' => $this->email, 'password' => $this->password)), 'groups' => $this->groupIDs, 'languageIDs' => $this->visibleLanguages, 'options' => $saveOptions, 'addDefaultGroups' => $addDefaultGroups); $this->objectAction = new UserAction(array(), 'create', $data); $result = $this->objectAction->executeAction(); $user = $result['returnValues']; $userEditor = new UserEditor($user); // set avatar if provided if (!empty($avatarURL)) { $userAvatarAction = new UserAvatarAction(array(), 'fetchRemoteAvatar', array('url' => $avatarURL, 'userEditor' => $userEditor)); $userAvatarAction->executeAction(); } // update session WCF::getSession()->changeUser($user); // activation management if (REGISTER_ACTIVATION_METHOD == 0) { $this->message = 'wcf.user.register.success'; } else { if (REGISTER_ACTIVATION_METHOD == 1) { // registering via 3rdParty leads to instant activation if ($registerVia3rdParty && $this->verified) { $this->message = 'wcf.user.register.success'; } else { $mail = new Mail(array($this->username => $this->email), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail', array('user' => $user))); $mail->send(); $this->message = 'wcf.user.register.needActivation'; } } else { if (REGISTER_ACTIVATION_METHOD == 2 && (!$this->verified || $this->verified && !WBB_TAPATALK_REG_AUTO_APPROVAL)) { $this->message = 'wcf.user.register.awaitActivation'; } } } // notify admin if (REGISTER_ADMIN_NOTIFICATION) { // get default language $language = LanguageFactory::getInstance()->getLanguage(LanguageFactory::getInstance()->getDefaultLanguageID()); // send mail $mail = new Mail(MAIL_ADMIN_ADDRESS, $language->getDynamicVariable('wcf.user.register.notification.mail.subject'), $language->getDynamicVariable('wcf.user.register.notification.mail', array('user' => $user))); $mail->setLanguage($language); $mail->send(); } if ($this->captchaObjectType) { $this->captchaObjectType->getProcessor()->reset(); } if (WCF::getSession()->getVar('noRegistrationCaptcha')) { WCF::getSession()->unregister('noRegistrationCaptcha'); } // login user UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $this->username, $this->password); WCF::getSession()->unregister('registrationStartTime'); $this->saved(); }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); $callbackURL = LinkHandler::getInstance()->getLink('FacebookAuth'); // Work around Facebook performing an illegal substitution of the Slash // by '%2F' when entering redirect URI (RFC 3986 sect. 2.2, sect. 3.4) $callbackURL = preg_replace_callback('/(?<=\\?).*/', function ($matches) { return rawurlencode($matches[0]); }, $callbackURL); // user accepted the connection if (isset($_GET['code'])) { try { // fetch access_token $request = new HTTPRequest('https://graph.facebook.com/oauth/access_token?client_id=' . StringUtil::trim(FACEBOOK_PUBLIC_KEY) . '&redirect_uri=' . rawurlencode($callbackURL) . '&client_secret=' . StringUtil::trim(FACEBOOK_PRIVATE_KEY) . '&code=' . rawurlencode($_GET['code'])); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } // validate state, validation of state is executed after fetching the access_token to invalidate 'code' if (!isset($_GET['state']) || $_GET['state'] != WCF::getSession()->getVar('__facebookInit')) { throw new IllegalLinkException(); } WCF::getSession()->unregister('__facebookInit'); parse_str($content, $data); try { // fetch userdata $request = new HTTPRequest('https://graph.facebook.com/me?access_token=' . rawurlencode($data['access_token']) . '&fields=birthday,bio,email,gender,id,location,name,picture.type(large),website'); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } $userData = JSON::decode($content); // check whether a user is connected to this facebook account $user = $this->getUser($userData['id']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.facebook.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { WCF::getSession()->register('__3rdPartyProvider', 'facebook'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__facebookUsername', $userData['name']); WCF::getSession()->register('__facebookData', $userData); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { WCF::getSession()->register('__username', $userData['name']); if (isset($userData['email'])) { WCF::getSession()->register('__email', $userData['email']); } WCF::getSession()->register('__facebookData', $userData); // we assume that bots won't register on facebook first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined or any other error that may occur if (isset($_GET['error'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.facebook.login.error.' . $_GET['error'])); } // start auth by redirecting to facebook $token = StringUtil::getRandomID(); WCF::getSession()->register('__facebookInit', $token); HeaderUtil::redirect("https://www.facebook.com/dialog/oauth?client_id=" . StringUtil::trim(FACEBOOK_PUBLIC_KEY) . "&redirect_uri=" . rawurlencode($callbackURL) . "&state=" . $token . "&scope=email,user_about_me,user_birthday,user_location,user_website"); $this->executed(); exit; }
/** * Does the user authentification. */ protected function initAuth() { do { $line = self::getReader()->readLine(WCF::getLanguage()->get('wcf.user.username') . '> '); if ($line === null) { exit; } $username = StringUtil::trim($line); } while ($username === ''); do { $line = self::getReader()->readLine(WCF::getLanguage()->get('wcf.user.password') . '> ', '*'); if ($line === null) { exit; } $password = StringUtil::trim($line); } while ($password === ''); // check credentials and switch user try { $user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($username, $password); WCF::getSession()->changeUser($user); } catch (UserInputException $e) { $message = WCF::getLanguage()->getDynamicVariable('wcf.user.' . $e->getField() . '.error.' . $e->getType(), array('username' => $username)); self::getReader()->println($message); exit(1); } // initialize history $history = new DatabaseCLICommandHistory(); $history->load(); self::getReader()->setHistory($history); // initialize language if (!self::getArgvParser()->language) { $this->initLanguage(); } }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); // user accepted if (isset($_GET['oauth_token']) && isset($_GET['oauth_verifier'])) { // fetch data created in the first step $initData = WCF::getSession()->getVar('__twitterInit'); WCF::getSession()->unregister('__twitterInit'); if (!$initData) { throw new IllegalLinkException(); } // validate oauth_token if ($_GET['oauth_token'] !== $initData['oauth_token']) { throw new IllegalLinkException(); } try { // fetch access_token $oauthHeader = array('oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY), 'oauth_nonce' => StringUtil::getRandomID(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0', 'oauth_token' => $initData['oauth_token']); $postData = array('oauth_verifier' => $_GET['oauth_verifier']); $signature = $this->createSignature('https://api.twitter.com/oauth/access_token', array_merge($oauthHeader, $postData)); $oauthHeader['oauth_signature'] = $signature; $request = new HTTPRequest('https://api.twitter.com/oauth/access_token', array(), $postData); $request->addHeader('Authorization', 'OAuth ' . $this->buildOAuthHeader($oauthHeader)); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } parse_str($content, $data); // check whether a user is connected to this twitter account $user = $this->getUser($data['user_id']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.twitter.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { WCF::getSession()->register('__3rdPartyProvider', 'twitter'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__twitterUsername', $data['screen_name']); WCF::getSession()->register('__twitterData', $data); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { // fetch user data $twitterData = null; try { $request = new HTTPRequest('https://api.twitter.com/1.1/users/show.json?screen_name=' . $data['screen_name']); $request->execute(); $reply = $request->getReply(); $twitterData = json_decode($reply['body'], true); } catch (SystemException $e) { /* ignore errors */ } WCF::getSession()->register('__username', $data['screen_name']); if ($twitterData !== null) { $data = $twitterData; } WCF::getSession()->register('__twitterData', $data); // we assume that bots won't register on twitter first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined if (isset($_GET['denied'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.twitter.login.error.denied')); } // start auth by fetching request_token try { $callbackURL = LinkHandler::getInstance()->getLink('TwitterAuth', array('appendSession' => false)); $oauthHeader = array('oauth_callback' => $callbackURL, 'oauth_consumer_key' => StringUtil::trim(TWITTER_PUBLIC_KEY), 'oauth_nonce' => StringUtil::getRandomID(), 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => TIME_NOW, 'oauth_version' => '1.0'); $signature = $this->createSignature('https://api.twitter.com/oauth/request_token', $oauthHeader); $oauthHeader['oauth_signature'] = $signature; // call api $request = new HTTPRequest('https://api.twitter.com/oauth/request_token', array('method' => 'POST')); $request->addHeader('Authorization', 'OAuth ' . $this->buildOAuthHeader($oauthHeader)); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } parse_str($content, $data); if ($data['oauth_callback_confirmed'] != 'true') { throw new IllegalLinkException(); } WCF::getSession()->register('__twitterInit', $data); // redirect to twitter HeaderUtil::redirect('https://api.twitter.com/oauth/authenticate?oauth_token=' . rawurlencode($data['oauth_token'])); $this->executed(); exit; }
/** * @see \wcf\form\IForm::save() */ public function save() { AbstractForm::save(); // get options $saveOptions = $this->optionHandler->save(); $registerVia3rdParty = false; $avatarURL = ''; if ($this->isExternalAuthentication) { switch (WCF::getSession()->getVar('__3rdPartyProvider')) { case 'github': // GitHub if (WCF::getSession()->getVar('__githubData')) { $githubData = WCF::getSession()->getVar('__githubData'); $this->additionalFields['authData'] = 'github:' . WCF::getSession()->getVar('__githubToken'); WCF::getSession()->unregister('__githubData'); WCF::getSession()->unregister('__githubToken'); if (WCF::getSession()->getVar('__email') && WCF::getSession()->getVar('__email') == $this->email) { $registerVia3rdParty = true; } if (isset($githubData['bio']) && User::getUserOptionID('aboutMe') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $githubData['bio']; } if (isset($githubData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $githubData['location']; } } break; case 'twitter': // Twitter if (WCF::getSession()->getVar('__twitterData')) { $twitterData = WCF::getSession()->getVar('__twitterData'); $this->additionalFields['authData'] = 'twitter:' . $twitterData['user_id']; WCF::getSession()->unregister('__twitterData'); if (isset($twitterData['description']) && User::getUserOptionID('aboutMe') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $twitterData['description']; } if (isset($twitterData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $twitterData['location']; } } break; case 'facebook': // Facebook if (WCF::getSession()->getVar('__facebookData')) { $facebookData = WCF::getSession()->getVar('__facebookData'); $this->additionalFields['authData'] = 'facebook:' . $facebookData['id']; WCF::getSession()->unregister('__facebookData'); if (isset($facebookData['email']) && $facebookData['email'] == $this->email) { $registerVia3rdParty = true; } if (isset($facebookData['gender']) && User::getUserOptionID('gender') !== null) { $saveOptions[User::getUserOptionID('gender')] = $facebookData['gender'] == 'male' ? UserProfile::GENDER_MALE : UserProfile::GENDER_FEMALE; } if (isset($facebookData['birthday']) && User::getUserOptionID('birthday') !== null) { list($month, $day, $year) = explode('/', $facebookData['birthday']); $saveOptions[User::getUserOptionID('birthday')] = $year . '-' . $month . '-' . $day; } if (isset($facebookData['bio']) && User::getUserOptionID('bio') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $facebookData['bio']; } if (isset($facebookData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $facebookData['location']['name']; } if (isset($facebookData['website']) && User::getUserOptionID('website') !== null) { $urls = preg_split('/[\\s,;]/', $facebookData['website'], -1, PREG_SPLIT_NO_EMPTY); if (!empty($urls)) { if (!Regex::compile('^https?://')->match($urls[0])) { $urls[0] = 'http://' . $urls[0]; } $saveOptions[User::getUserOptionID('homepage')] = $urls[0]; } } // avatar if (isset($facebookData['picture']) && !$facebookData['picture']['data']['is_silhouette']) { $avatarURL = $facebookData['picture']['data']['url']; } } break; case 'google': // Google Plus if (WCF::getSession()->getVar('__googleData')) { $googleData = WCF::getSession()->getVar('__googleData'); $this->additionalFields['authData'] = 'google:' . $googleData['id']; WCF::getSession()->unregister('__googleData'); if (isset($googleData['emails'][0]['value']) && $googleData['emails'][0]['value'] == $this->email) { $registerVia3rdParty = true; } if (isset($googleData['gender']) && User::getUserOptionID('gender') !== null) { switch ($googleData['gender']) { case 'male': $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_MALE; break; case 'female': $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_FEMALE; break; } } if (isset($googleData['birthday']) && User::getUserOptionID('birthday') !== null) { $saveOptions[User::getUserOptionID('birthday')] = $googleData['birthday']; } if (isset($googleData['placesLived']) && User::getUserOptionID('location') !== null) { // save primary location $saveOptions[User::getUserOptionID('location')] = current(array_map(function ($element) { return $element['value']; }, array_filter($googleData['placesLived'], function ($element) { return isset($element['primary']) && $element['primary']; }))); } // avatar if (isset($googleData['image']['url'])) { $avatarURL = $googleData['image']['url']; } } break; } // create fake password $this->password = StringUtil::getRandomID(); } $this->additionalFields['languageID'] = $this->languageID; if (LOG_IP_ADDRESS) { $this->additionalFields['registrationIpAddress'] = WCF::getSession()->ipAddress; } // generate activation code $addDefaultGroups = true; if (REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty || REGISTER_ACTIVATION_METHOD == 2) { $activationCode = UserRegistrationUtil::getActivationCode(); $this->additionalFields['activationCode'] = $activationCode; $addDefaultGroups = false; $this->groupIDs = UserGroup::getGroupIDsByType(array(UserGroup::EVERYONE, UserGroup::GUESTS)); } // check gravatar support if (MODULE_GRAVATAR && Gravatar::test($this->email)) { $this->additionalFields['enableGravatar'] = 1; } // create user $data = array('data' => array_merge($this->additionalFields, array('username' => $this->username, 'email' => $this->email, 'password' => $this->password)), 'groups' => $this->groupIDs, 'languageIDs' => $this->visibleLanguages, 'options' => $saveOptions, 'addDefaultGroups' => $addDefaultGroups); $this->objectAction = new UserAction(array(), 'create', $data); $result = $this->objectAction->executeAction(); $user = $result['returnValues']; $userEditor = new UserEditor($user); // update session WCF::getSession()->changeUser($user); // set avatar if provided if (!empty($avatarURL)) { $userAvatarAction = new UserAvatarAction(array(), 'fetchRemoteAvatar', array('url' => $avatarURL, 'userEditor' => $userEditor)); $userAvatarAction->executeAction(); } // activation management if (REGISTER_ACTIVATION_METHOD == 0) { $this->message = 'wcf.user.register.success'; } else { if (REGISTER_ACTIVATION_METHOD == 1) { // registering via 3rdParty leads to instant activation if ($registerVia3rdParty) { $this->message = 'wcf.user.register.success'; } else { $mail = new Mail(array($this->username => $this->email), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail', array('user' => $user))); $mail->send(); $this->message = 'wcf.user.register.needActivation'; } } else { if (REGISTER_ACTIVATION_METHOD == 2) { $this->message = 'wcf.user.register.awaitActivation'; } } } // notify admin if (REGISTER_ADMIN_NOTIFICATION) { // get default language $language = LanguageFactory::getInstance()->getLanguage(LanguageFactory::getInstance()->getDefaultLanguageID()); // send mail $mail = new Mail(MAIL_ADMIN_ADDRESS, $language->getDynamicVariable('wcf.user.register.notification.mail.subject'), $language->getDynamicVariable('wcf.user.register.notification.mail', array('user' => $user))); $mail->setLanguage($language); $mail->send(); } if ($this->captchaObjectType) { $this->captchaObjectType->getProcessor()->reset(); } if (WCF::getSession()->getVar('noRegistrationCaptcha')) { WCF::getSession()->unregister('noRegistrationCaptcha'); } // login user UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $this->username, $this->password); WCF::getSession()->unregister('registrationRandomFieldNames'); WCF::getSession()->unregister('registrationStartTime'); $this->saved(); // forward to index page HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->getDynamicVariable($this->message, array('user' => $user)), 15); exit; }
/** * Creates a new session. */ protected function create() { // create new session hash $sessionID = StringUtil::getRandomID(); // get user automatically $this->user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginAutomatically(call_user_func(array($this->sessionClassName, 'supportsPersistentLogins'))); // create user if ($this->user === null) { // no valid user found // create guest user $this->user = new User(null); } if ($this->user->userID != 0) { // user is no guest // delete all other sessions of this user call_user_func(array($this->sessionEditorClassName, 'deleteUserSessions'), array($this->user->userID)); } // save session $this->session = call_user_func(array($this->sessionEditorClassName, 'create'), array( 'sessionID' => $sessionID, 'userID' => $this->user->userID, 'ipAddress' => UserUtil::getIpAddress(), 'userAgent' => UserUtil::getUserAgent(), 'lastActivityTime' => TIME_NOW, 'requestURI' => UserUtil::getRequestURI(), 'requestMethod' => (!empty($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : '') )); }
/** * login * * @param String $loginName * @param String $password * @return Boolean return true when login success. */ public function login($loginName, $password) { //ref wcf\acp\form\LoginForm::validateUser() try { $oUser = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($loginName, $password); } catch (UserInputException $e) { if ($e->getField() == 'username') { try { $oUser = EmailUserAuthentication::getInstance()->loginManually($loginName, $password); } catch (UserInputException $e2) { //if ($e2->getField() == 'username') throw $e; //throw $e2; return false; } } else { //throw $e; return false; } } if (!$oUser || !$oUser->userID) { return false; } //ref wcf\form\LoginForm::save() // set cookies UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($oUser, $loginName, $password); // change user WCF::getSession()->changeUser($oUser); MbqMain::$oMbqAppEnv->oCurrentUser = $oUser; $this->initOCurMbqEtUser(); return true; }
/** * Validates the user access data. */ protected function validateUser() { try { $this->user = UserAuthenticationFactory::getInstance()->getUserAuthentication()->loginManually($this->username, $this->password); } catch (UserInputException $e) { if ($e->getField() == 'username') { try { $this->user = EmailUserAuthentication::getInstance()->loginManually($this->username, $this->password); } catch (UserInputException $e2) { if ($e2->getField() == 'username') { throw $e; } throw $e2; } } else { throw $e; } } }
/** * @see \wcf\action\IAction::execute() */ public function execute() { parent::execute(); $callbackURL = LinkHandler::getInstance()->getLink('GoogleAuth', array('appendSession' => false)); // user accepted the connection if (isset($_GET['code'])) { try { // fetch access_token $request = new HTTPRequest('https://accounts.google.com/o/oauth2/token', array(), array('code' => $_GET['code'], 'client_id' => StringUtil::trim(GOOGLE_PUBLIC_KEY), 'client_secret' => StringUtil::trim(GOOGLE_PRIVATE_KEY), 'redirect_uri' => $callbackURL, 'grant_type' => 'authorization_code')); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } // validate state, validation of state is executed after fetching the access_token to invalidate 'code' if (!isset($_GET['state']) || $_GET['state'] != WCF::getSession()->getVar('__googleInit')) { throw new IllegalLinkException(); } WCF::getSession()->unregister('__googleInit'); $data = JSON::decode($content); try { // fetch userdata $request = new HTTPRequest('https://www.googleapis.com/plus/v1/people/me'); $request->addHeader('Authorization', 'Bearer ' . $data['access_token']); $request->execute(); $reply = $request->getReply(); $content = $reply['body']; } catch (SystemException $e) { // force logging $e->getExceptionID(); throw new IllegalLinkException(); } $userData = JSON::decode($content); // check whether a user is connected to this google account $user = $this->getUser($userData['id']); if ($user->userID) { // a user is already connected, but we are logged in, break if (WCF::getUser()->userID) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.google.connect.error.inuse')); } else { if (UserAuthenticationFactory::getInstance()->getUserAuthentication()->supportsPersistentLogins()) { $password = StringUtil::getRandomID(); $userEditor = new UserEditor($user); $userEditor->update(array('password' => $password)); // reload user to retrieve salt $user = new User($user->userID); UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $user->username, $password); } WCF::getSession()->changeUser($user); WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink()); } } else { WCF::getSession()->register('__3rdPartyProvider', 'google'); // save data for connection if (WCF::getUser()->userID) { WCF::getSession()->register('__googleUsername', $userData['displayName']); WCF::getSession()->register('__googleData', $userData); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('AccountManagement') . '#3rdParty'); } else { WCF::getSession()->register('__username', $userData['displayName']); if (isset($userData['emails'][0]['value'])) { WCF::getSession()->register('__email', $userData['emails'][0]['value']); } WCF::getSession()->register('__googleData', $userData); // we assume that bots won't register on google first // thus no need for a captcha if (REGISTER_USE_CAPTCHA) { WCF::getSession()->register('noRegistrationCaptcha', true); } WCF::getSession()->update(); HeaderUtil::redirect(LinkHandler::getInstance()->getLink('Register')); } } $this->executed(); exit; } // user declined or any other error that may occur if (isset($_GET['error'])) { throw new NamedUserException(WCF::getLanguage()->get('wcf.user.3rdparty.google.login.error.' . $_GET['error'])); } // start auth by redirecting to google $token = StringUtil::getRandomID(); WCF::getSession()->register('__googleInit', $token); HeaderUtil::redirect("https://accounts.google.com/o/oauth2/auth?client_id=" . rawurlencode(StringUtil::trim(GOOGLE_PUBLIC_KEY)) . "&redirect_uri=" . rawurlencode($callbackURL) . "&state=" . $token . "&scope=profile+email&response_type=code"); $this->executed(); exit; }