Example #1
0
 public function saveSocialNetworkPrivacySettings()
 {
     $settings = array('facebook' => $this->parameters['facebook'], 'google' => $this->parameters['google'], 'reddit' => $this->parameters['reddit'], 'twitter' => $this->parameters['twitter']);
     $userEditor = new UserEditor(WCF::getUser());
     $userEditor->update(array('socialNetworkPrivacySettings' => serialize($settings)));
     return array('settings' => $settings);
 }
Example #2
0
 /**
  * Deletes this session and it's related data.
  */
 public function delete()
 {
     // clear storage
     if ($this->user->userID) {
         self::resetSessions(array($this->user->userID));
         // update last activity time
         if (!class_exists('\\wcf\\system\\WCFACP', false)) {
             $editor = new UserEditor($this->user);
             $editor->update(array('lastActivityTime' => TIME_NOW));
         }
     }
     // 1st: Change user to guest, otherwise other the entire session, including
     // all virtual sessions of the user will be deleted
     $this->changeUser(new User(null));
     // 2nd: Actually remove session
     $sessionEditor = new $this->sessionEditorClassName($this->session);
     $sessionEditor->delete();
     // disable update
     $this->disableUpdate();
 }
Example #3
0
 /**
  * @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;
 }
 /**
  * @see	\wcf\action\IAction::execute()
  */
 public function execute()
 {
     parent::execute();
     if ($this->user->enableGravatar) {
         $fileExtension = $this->user->gravatarFileExtension ?: 'png';
         // try to use cached gravatar
         $cachedFilename = sprintf(Gravatar::GRAVATAR_CACHE_LOCATION, md5(mb_strtolower($this->user->email)), $this->size, $fileExtension);
         if (file_exists(WCF_DIR . $cachedFilename) && filemtime(WCF_DIR . $cachedFilename) > TIME_NOW - Gravatar::GRAVATAR_CACHE_EXPIRE * 86400) {
             @header('Content-Type: image/png');
             @readfile(WCF_DIR . $cachedFilename);
             exit;
         }
         // try to download new version
         $gravatarURL = sprintf(Gravatar::GRAVATAR_BASE, md5(mb_strtolower($this->user->email)), $this->size, GRAVATAR_DEFAULT_TYPE);
         try {
             $request = new HTTPRequest($gravatarURL);
             $request->execute();
             $reply = $request->getReply();
             // get mime type and file extension
             $fileExtension = 'png';
             $mimeType = 'image/png';
             if (isset($reply['headers']['Content-Type'])) {
                 switch ($reply['headers']['Content-Type']) {
                     case 'image/jpeg':
                         $mimeType = 'image/jpeg';
                         $fileExtension = 'jpg';
                         break;
                     case 'image/gif':
                         $mimeType = 'image/gif';
                         $fileExtension = 'gif';
                         break;
                 }
             }
             // save file
             $cachedFilename = sprintf(Gravatar::GRAVATAR_CACHE_LOCATION, md5(mb_strtolower($this->user->email)), $this->size, $fileExtension);
             file_put_contents(WCF_DIR . $cachedFilename, $reply['body']);
             FileUtil::makeWritable(WCF_DIR . $cachedFilename);
             // update file extension
             if ($fileExtension != $this->user->gravatarFileExtension) {
                 $editor = new UserEditor($this->user);
                 $editor->update(array('gravatarFileExtension' => $fileExtension));
             }
             @header('Content-Type: ' . $mimeType);
             @readfile(WCF_DIR . $cachedFilename);
             exit;
         } catch (SystemException $e) {
             // disable gravatar
             $editor = new UserEditor($this->user);
             $editor->update(array('enableGravatar' => 0));
         }
     }
     // fallback to default avatar
     @header('Content-Type: image/svg+xml');
     @readfile(WCF_DIR . 'images/avatars/avatar-default.svg');
     exit;
 }
 /**
  * @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;
 }
Example #6
0
	/**
	 * Returns true if the given password is the correct password for this user.
	 * 
	 * @param	string		$password
	 * @return	boolean		password correct
	 */
	public function checkPassword($password) {
		$isValid = false;
		$rebuild = false;
		
		// check if password is a valid bcrypt hash
		if (PasswordUtil::isBlowfish($this->password)) {
			if (PasswordUtil::isDifferentBlowfish($this->password)) {
				$rebuild = true;
			}
			
			// password is correct
			if (PasswordUtil::secureCompare($this->password, PasswordUtil::getDoubleSaltedHash($password, $this->password))) {
				$isValid = true;
			}
		}
		else {
			// different encryption type
			if (PasswordUtil::checkPassword($this->username, $password, $this->password)) {
				$isValid = true;
				$rebuild = true;
			}
		}
		
		// create new password hash, either different encryption or different blowfish cost factor
		if ($rebuild) {
			$userEditor = new UserEditor($this);
			$userEditor->update(array(
				'password' => $password
			));
		}
		
		return $isValid;
	}
 /**
  * @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;
 }
 /**
  * Sends the mail notification.
  * 
  * @param	\wcf\data\user\notification\UserNotification			$notification
  * @param	\wcf\data\user\User						$user
  * @param	\wcf\system\user\notification\event\IUserNotificationEvent	$event
  */
 public function sendInstantMailNotification(UserNotification $notification, User $user, IUserNotificationEvent $event)
 {
     // no notifications for disabled or banned users
     if ($user->activationCode) {
         return;
     }
     if ($user->banned) {
         return;
     }
     // recipient's language
     $event->setLanguage($user->getLanguage());
     // add mail header
     $message = $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.header', array('user' => $user)) . "\n\n";
     // get message
     $message .= $event->getEmailMessage();
     // append notification mail footer
     $token = $user->notificationMailToken;
     if (!$token) {
         // generate token if not present
         $token = mb_substr(StringUtil::getHash(serialize(array($user->userID, StringUtil::getRandomID()))), 0, 20);
         $editor = new UserEditor($user);
         $editor->update(array('notificationMailToken' => $token));
     }
     $message .= "\n\n" . $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.footer', array('user' => $user, 'token' => $token, 'notification' => $notification));
     // build mail
     $mail = new Mail(array($user->username => $user->email), $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.subject', array('title' => $event->getEmailTitle())), $message);
     $mail->setLanguage($user->getLanguage());
     $mail->send();
 }
 /**
  * Handles uploaded attachments.
  */
 public function upload()
 {
     // save files
     $files = $this->parameters['__files']->getFiles();
     $userID = !empty($this->parameters['userID']) ? intval($this->parameters['userID']) : WCF::getUser()->userID;
     $user = $userID != WCF::getUser()->userID ? new User($userID) : WCF::getUser();
     $file = $files[0];
     try {
         if (!$file->getValidationErrorType()) {
             // shrink avatar if necessary
             $fileLocation = $this->enforceDimensions($file->getLocation());
             $imageData = getimagesize($fileLocation);
             $data = array('avatarName' => $file->getFilename(), 'avatarExtension' => $file->getFileExtension(), 'width' => $imageData[0], 'height' => $imageData[1], 'userID' => $userID, 'fileHash' => sha1_file($fileLocation));
             // create avatar
             $avatar = UserAvatarEditor::create($data);
             // check avatar directory
             // and create subdirectory if necessary
             $dir = dirname($avatar->getLocation());
             if (!@file_exists($dir)) {
                 FileUtil::makePath($dir, 0777);
             }
             // move uploaded file
             if (@copy($fileLocation, $avatar->getLocation())) {
                 @unlink($fileLocation);
                 // create thumbnails
                 $action = new UserAvatarAction(array($avatar), 'generateThumbnails');
                 $action->executeAction();
                 // delete old avatar
                 if ($user->avatarID) {
                     $action = new UserAvatarAction(array($user->avatarID), 'delete');
                     $action->executeAction();
                 }
                 // update user
                 $userEditor = new UserEditor($user);
                 $userEditor->update(array('avatarID' => $avatar->avatarID, 'enableGravatar' => 0));
                 // reset user storage
                 UserStorageHandler::getInstance()->reset(array($userID), 'avatar');
                 // return result
                 return array('avatarID' => $avatar->avatarID, 'canCrop' => $avatar->canCrop(), 'url' => $avatar->getURL(96));
             } else {
                 // moving failed; delete avatar
                 $editor = new UserAvatarEditor($avatar);
                 $editor->delete();
                 throw new UserInputException('avatar', 'uploadFailed');
             }
         }
     } catch (UserInputException $e) {
         $file->setValidationErrorType($e->getType());
     }
     return array('errorType' => $file->getValidationErrorType());
 }
 /**
  * @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;
 }
 /**
  * @see	\wcf\system\cronjob\ICronjob::execute()
  */
 public function execute(Cronjob $cronjob)
 {
     parent::execute($cronjob);
     // get user ids
     $userIDs = array();
     $sql = "SELECT\tDISTINCT userID\n\t\t\tFROM\twcf" . WCF_N . "_user_notification\n\t\t\tWHERE\tmailNotified = ?\n\t\t\t\tAND time < ?\n\t\t\t\tAND confirmTime = ?";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array(0, TIME_NOW - 3600 * 23, 0));
     while ($row = $statement->fetchArray()) {
         $userIDs[] = $row['userID'];
     }
     if (empty($userIDs)) {
         return;
     }
     // get users
     $userList = new UserList();
     $userList->setObjectIDs($userIDs);
     $userList->readObjects();
     $users = $userList->getObjects();
     // get notifications
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("notification.userID IN (?)", array($userIDs));
     $conditions->add("notification.mailNotified = ?", array(0));
     $conditions->add("notification.confirmTime = ?", array(0));
     $sql = "SELECT\t\tnotification.*, notification_event.eventID, object_type.objectType\n\t\t\tFROM\t\twcf" . WCF_N . "_user_notification notification\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_user_notification_event notification_event\n\t\t\tON\t\t(notification_event.eventID = notification.eventID)\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_object_type object_type\n\t\t\tON\t\t(object_type.objectTypeID = notification_event.objectTypeID)\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\tnotification.time";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     // mark notifications as done
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("userID IN (?)", array($userIDs));
     $conditions->add("mailNotified = ?", array(0));
     $sql = "UPDATE\twcf" . WCF_N . "_user_notification\n\t\t\tSET\tmailNotified = 1\n\t\t\t" . $conditions;
     $statement2 = WCF::getDB()->prepareStatement($sql);
     $statement2->execute($conditions->getParameters());
     // collect data
     $eventsToUser = $objectTypes = $eventIDs = $notificationObjects = array();
     $availableObjectTypes = UserNotificationHandler::getInstance()->getAvailableObjectTypes();
     while ($row = $statement->fetchArray()) {
         if (!isset($eventsToUser[$row['userID']])) {
             $eventsToUser[$row['userID']] = array();
         }
         $eventsToUser[$row['userID']][] = $row['notificationID'];
         // cache object types
         if (!isset($objectTypes[$row['objectType']])) {
             $objectTypes[$row['objectType']] = array('objectType' => $availableObjectTypes[$row['objectType']], 'objectIDs' => array(), 'objects' => array());
         }
         $objectTypes[$row['objectType']]['objectIDs'][] = $row['objectID'];
         $eventIDs[] = $row['eventID'];
         $notificationObjects[$row['notificationID']] = new UserNotification(null, $row);
     }
     // load authors
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("notificationID IN (?)", array(array_keys($notificationObjects)));
     $sql = "SELECT\t\tnotificationID, authorID\n\t\t\tFROM\t\twcf" . WCF_N . "_user_notification_author\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\ttime ASC";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $authorIDs = $authorToNotification = array();
     while ($row = $statement->fetchArray()) {
         if ($row['authorID']) {
             $authorIDs[] = $row['authorID'];
         }
         if (!isset($authorToNotification[$row['notificationID']])) {
             $authorToNotification[$row['notificationID']] = array();
         }
         $authorToNotification[$row['notificationID']][] = $row['authorID'];
     }
     // load authors
     $authors = UserProfile::getUserProfiles($authorIDs);
     $unknownAuthor = new UserProfile(new User(null, array('userID' => null, 'username' => WCF::getLanguage()->get('wcf.user.guest'))));
     // load objects associated with each object type
     foreach ($objectTypes as $objectType => $objectData) {
         $objectTypes[$objectType]['objects'] = $objectData['objectType']->getObjectsByIDs($objectData['objectIDs']);
     }
     // load required events
     $eventList = new UserNotificationEventList();
     $eventList->getConditionBuilder()->add("user_notification_event.eventID IN (?)", array($eventIDs));
     $eventList->readObjects();
     $eventObjects = $eventList->getObjects();
     foreach ($eventsToUser as $userID => $events) {
         if (!isset($users[$userID])) {
             continue;
         }
         $user = $users[$userID];
         // no notifications for disabled or banned users
         if ($user->activationCode) {
             continue;
         }
         if ($user->banned) {
             continue;
         }
         // add mail header
         $message = $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.header', array('user' => $user));
         foreach ($events as $notificationID) {
             $notification = $notificationObjects[$notificationID];
             $className = $eventObjects[$notification->eventID]->className;
             $class = new $className($eventObjects[$notification->eventID]);
             $class->setObject($notification, $objectTypes[$notification->objectType]['objects'][$notification->objectID], isset($authors[$notification->authorID]) ? $authors[$notification->authorID] : $unknownAuthor, $notification->additionalData);
             $class->setLanguage($user->getLanguage());
             if (isset($authorToNotification[$notification->notificationID])) {
                 $eventAuthors = array();
                 foreach ($authorToNotification[$notification->notificationID] as $userID) {
                     if (!$userID) {
                         $eventAuthors[0] = $unknownAuthor;
                     } else {
                         if (isset($authors[$userID])) {
                             $eventAuthors[$userID] = $authors[$userID];
                         }
                     }
                 }
                 if (!empty($eventAuthors)) {
                     $class->setAuthors($eventAuthors);
                 }
             }
             $message .= "\n\n";
             $message .= $class->getEmailMessage('daily');
         }
         // append notification mail footer
         $token = $user->notificationMailToken;
         if (!$token) {
             // generate token if not present
             $token = mb_substr(StringUtil::getHash(serialize(array($user->userID, StringUtil::getRandomID()))), 0, 20);
             $editor = new UserEditor($user);
             $editor->update(array('notificationMailToken' => $token));
         }
         $message .= "\n\n";
         $message .= $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.daily.footer', array('user' => $user, 'token' => $token));
         // build mail
         $mail = new Mail(array($user->username => $user->email), $user->getLanguage()->getDynamicVariable('wcf.user.notification.mail.daily.subject', array('count' => count($events))), $message);
         $mail->setLanguage($user->getLanguage());
         $mail->send();
     }
 }
Example #12
0
 /**
  * update email
  */
 public function updateEmail($password, $email, &$resultMessage)
 {
     try {
         $oExttMbqUserAddForm = new ExttMbqUserAddForm();
         try {
             $oUser = WCF::getSession()->getUser();
             if ($oUser->checkPassword($password)) {
                 $userEditor = new UserEditor($oUser);
                 $userEditor->update(array('email' => $email));
             } else {
                 return "password is not valid";
             }
         } catch (UserInputException $e) {
             return $e->getType();
         }
     } catch (Exception $e) {
         return $e->getMessage();
     }
     return true;
 }