Rev 6803 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php/**** Este controllador agrupa las funciones de Callback para todas las operaciones de OAUTH*/namespace LeadersLinked\Controller;use Laminas\Db\Adapter\AdapterInterface;use Laminas\Cache\Storage\Adapter\AbstractAdapter;use Laminas\Mvc\Controller\AbstractActionController;use Laminas\Log\LoggerInterface;use Laminas\View\Model\JsonModel;use GeoIp2\Database\Reader As GeoIp2Reader;use LeadersLinked\Model\UserProvider;use LeadersLinked\Mapper\UserMapper;use LeadersLinked\Mapper\UserProviderMapper;use LeadersLinked\Model\User;use LeadersLinked\Model\UserType;use LeadersLinked\Authentication\AuthSocialAdapter;use LeadersLinked\Library\Functions;use LeadersLinked\Library\Image;use LeadersLinked\Library\Facebook;use LeadersLinked\Model\Provider;use LeadersLinked\Mapper\UserBrowserMapper;use LeadersLinked\Model\UserBrowser;use LeadersLinked\Mapper\UserIpMapper;use LeadersLinked\Model\UserIp;class OauthController extends AbstractActionController{/**** @var AdapterInterface*/private $adapter;/**** @var AbstractAdapter*/private $cache;/**** @var LoggerInterface*/private $logger;/**** @var array*/private $config;/**** @param AdapterInterface $adapter* @param AbstractAdapter $cache* @param LoggerInterface $logger* @param array $config*/public function __construct($adapter, $cache , $logger, $config){$this->adapter = $adapter;$this->cache = $cache;$this->logger = $logger;$this->config = $config;}public function indexAction(){return new JsonModel(['success' => false, 'error' => 'Missing authentication']);}/**** @param string $id* @param string $name* @param string $email* @param string $picture* @param string $provider*/private function process($id , $name, $email, $picture, $provider){$flashMessenger = $this->plugin('FlashMessenger');if(empty($id) || empty($name) || empty($email)){if($provider == UserProvider::PROVIDER_FACEBOOK) {$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');}if($provider == UserProvider::PROVIDER_TWITTER) {$flashMessenger->addErrorMessage('ERROR_TWITTER_AUTH');}if($provider == UserProvider::PROVIDER_GOOGLE) {$flashMessenger->addErrorMessage('ERROR_GOOGLE_AUTH');}$this->logger->err('Parámetro(s) inválido(s) [id = ' . $id . ' email = ' . $email .' name = ' . $name . ' picture = ' . $picture, ['ip' => Functions::getUserIP()]);return $this->redirect()->toRoute('home');}$userMapper = UserMapper::getInstance($this->adapter);$userProviderMapper = UserProviderMapper::getInstance($this->adapter);$userProvider = $userProviderMapper->fetchOneByIdAndProdiver($id, $provider);//El usuario tiene una sesión activa$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();if($currentUser) {if(!$currentUser->image) {$this->downloadImage($picture, $currentUser, $userMapper);}if(!$userProvider) {$userProvider = new UserProvider();$userProvider->user_id = $currentUser->id;$userProvider->id = $id;$userProvider->name = $name;$userProvider->email = $email;$userProvider->image = $picture;$userProvider->provider = $provider;if($userProviderMapper->insert($userProvider)) {if($provider == UserProvider::PROVIDER_FACEBOOK) {$this->logger->info('Registro del token de Facebook', ['user_id' => $currentUser->id, 'ip' => Functions::getUserIP()]);}if($provider == UserProvider::PROVIDER_TWITTER) {$this->logger->info('Registro del token de Twitter', ['user_id' => $currentUser->id, 'ip' => Functions::getUserIP()]);}if($provider == UserProvider::PROVIDER_GOOGLE) {$this->logger->info('Registro del token de Google', ['user_id' => $currentUser->id, 'ip' => Functions::getUserIP()]);}} else {$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');}}$this->registerBroserAndIp($currentUser);return $this->redirect()->toRoute('account-settings', [], ['query'=>['tab'=>'nav-social-networks']]);} else {//El usuario no tiene sesión activa//Si existe la cuenta del provider en el sistema recuperamos el usuarioif($userProvider) {$user = $userMapper->fetchOne($userProvider->user_id);} else {//Buscamos si esta registrado el usuario por email$user = $userMapper->fetchOneByEmail($email);//Creamos un usuarioif(empty($user)){$names = explode(' ', $name);$user = new User();$user->email = $email;$user->first_name = $names[0];$user->last_name = count($names) > 1 ? implode(' ', array_slice($names, 1)) : '';$user->usertype_id = UserType::USER;$user->password = '';$user->activation_key = '';$user->status = User::STATUS_ACTIVE;$user->blocked = User::BLOCKED_NO;$user->email_verified = User::EMAIL_VERIFIED_YES;$user->login_attempt = 0;$user->balance = 0;if($userMapper->insert($user)) {$this->logger->info('Creamos el usuario usando los datos del provider', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);} else {$flashMessenger->addErrorMessage($userMapper->getError());return $this->redirect()->toRoute('home');}$user = $userMapper->fetchOne($user->id);}if($user) {if(!$user->image) {$this->downloadImage($picture, $user, $userMapper);}$userProvider = new UserProvider();$userProvider->user_id = $user->id;$userProvider->id = $id;$userProvider->name = $name;$userProvider->email = $email;$userProvider->image = $picture;$userProvider->provider = $provider;if($userProviderMapper->insert($userProvider)) {if($provider == UserProvider::PROVIDER_FACEBOOK) {$this->logger->info('Registro del token de Facebook', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);}if($provider == UserProvider::PROVIDER_TWITTER) {$this->logger->info('Registro del token de Twitter', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);}if($provider == UserProvider::PROVIDER_GOOGLE) {$this->logger->info('Registro del token de Google', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);}}}}$authSocialAdapter = new AuthSocialAdapter($this->adapter, $this->logger);$authSocialAdapter->setData($id, $provider);$authService = new \Laminas\Authentication\AuthenticationService();$authService->setAdapter($authSocialAdapter);$result = $authService->authenticate();if($result->getCode() == \Laminas\Authentication\Result::SUCCESS){if($provider == UserProvider::PROVIDER_FACEBOOK) {$this->logger->info('Acceso Facebook', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);}if($provider == UserProvider::PROVIDER_TWITTER) {$this->logger->info('Acceso Twitter', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);}if($provider == UserProvider::PROVIDER_GOOGLE) {$this->logger->info('Acceso Google', ['user_id' => $user->id, 'ip' => Functions::getUserIP()]);}$this->registerBroserAndIp($user);return $this->redirect()->toRoute('dashboard');}else{$message = $result->getMessages()[0];$flashMessenger->addErrorMessage($message);return $this->redirect()->toRoute('home');}}}/**** @param string $picture* @param User $user* @param UserMapper $userMapper*/private function downloadImage($picture, $user, $userMapper){$target_path = $this->config['leaderslinked.fullpath.user'] . $user->uuid;$picture_content = file_get_contents($picture);if($picture_content) {$temp_file = tempnam(sys_get_temp_dir(), 'Tux');file_put_contents($temp_file, $picture_content);$target_filename = 'user-' . uniqid() . '.png';list( $target_width, $target_height ) = explode('x', $this->config['leaderslinked.image_sizes.user_size']);$source = $temp_file;$crop_to_dimensions = true;if(Image::uploadImage($source, $target_path, $target_filename, $target_width, $target_height, $crop_to_dimensions)) {$user->image = $target_filename;$userMapper->updateImage($user);}}}public function facebookAction(){$flashMessenger = $this->plugin('FlashMessenger');$app_id = $this->config['leaderslinked.facebook.app_id'];$app_password = $this->config['leaderslinked.facebook.app_password'];$app_graph_version = $this->config['leaderslinked.facebook.app_graph_version'];if(!isset($_GET['code']) && !isset($_GET['state'])){$flashMessenger->addErrorMessage('Facebook code or state not available');return $this->redirect()->toRoute('home');}//$code = trim(filter_var($_GET['code'], FILTER_SANITIZE_STRING));$state = trim(filter_var($_GET['state'], FILTER_SANITIZE_STRING));$fb = new \Facebook\Facebook(['app_id' => $app_id,'app_secret' => $app_password,'default_graph_version' => $app_graph_version]);$helper = $fb->getRedirectLoginHelper();$helper->getPersistentDataHandler()->set('state', $state);$accessToken = null;try {$accessToken = $helper->getAccessToken();}catch(\Facebook\Exceptions\FacebookResponseException $e){$this->logger->err('Facebook Graph: ' . $e->getMessage(), ['ip' => Functions::getUserIP()]);$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');return $this->redirect()->toRoute('home');}catch(\Facebook\Exceptions\FacebookSDKException $e){$this->logger->err('Facebook SDK: ' . $e->getMessage(), ['ip' => Functions::getUserIP()]);$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');return $this->redirect()->toRoute('home');}if (!$accessToken) {if ($helper->getError()) {$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');$this->logger->err($helper->getErrorDescription(), ['ip' => Functions::getUserIP()]);return $this->redirect()->toRoute('home');} else {$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');$this->logger->err('Facebook Bad request', ['ip' => Functions::getUserIP()]);return $this->redirect()->toRoute('home');}}try {$response = $fb->get('/me?fields=id,name,email,picture', $accessToken->getValue());} catch(\Facebook\Exceptions\FacebookResponseException $e) {$this->logger->err('Facebook Graph: ' . $e->getMessage(), ['ip' => Functions::getUserIP()]);$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');} catch(\Facebook\Exceptions\FacebookSDKException $e) {$this->logger->err('Facebook SDK: ' . $e->getMessage(), ['ip' => Functions::getUserIP()]);$flashMessenger->addErrorMessage('ERROR_FACEBOOK_AUTH');return $this->redirect()->toRoute('home');}$fb_user = $response->getGraphUser();if(is_object($fb_user)) {$id = filter_var($fb_user->getId(), FILTER_SANITIZE_STRING);$name = filter_var($fb_user->getName(), FILTER_SANITIZE_STRING);$email = filter_var($fb_user->getEmail(), FILTER_SANITIZE_EMAIL);$picture = $fb_user->getPicture();if(is_array($picture)) {$picture = filter_var($picture['url'], FILTER_SANITIZE_URL);} else if(is_object($picture)) {$picture = filter_var($picture->getUrl(), FILTER_SANITIZE_URL);} else {$picture = filter_var($picture, FILTER_SANITIZE_URL);}}return $this->process($id, $name, $email, $picture, UserProvider::PROVIDER_FACEBOOK);}public function facebookDeleteAction(){error_log('---START FACEBOOK DELETE---');error_log('GET');error_log(print_r($_GET, true));error_log('POST');error_log(print_r($_POST, true));error_log('---END FACEBOOK DELETE---');return new JsonModel(['success' => true,]);}public function facebookCancelAction(){$signed_request = isset($_POST['signed_request']) ? trim(filter_var($_POST['signed_request'], FILTER_SANITIZE_STRING)) : '';if($signed_request) {$facebook = new \LeadersLinked\Library\Facebook($this->config);$data = $facebook->parse_signed_request($signed_request);if($data && $data['user_id']) {$userProviderMapper = UserProviderMapper::getInstance($this->adapter);$userProvider = $userProviderMapper->fetchOneByIdAndProdiver($data['user_id'], Provider::FACEBOOK);if($userProvider) {if($userProviderMapper->deleteByIdAndProvider($userProvider->id, $userProvider->provider)) {$this->logger->info('Se borro la cuenta de Facebook');return new JsonModel(['success' => true,]);}}}}return new JsonModel(['success' => false,]);}public function googleAction(){$currentUserPlugin = $this->plugin('currentUserPlugin');$currentUser = $currentUserPlugin->getUser();$google = new \Google_Client();$google->setAuthConfig('data/google/auth-leaderslinked/apps.google.com_secreto_cliente.json');$google->setAccessType("offline"); // offline access$google->setIncludeGrantedScopes(true); // incremental auth$google->addScope('profile');$google->addScope('email');if (! isset($_GET['code'])) {$auth_url = $google->createAuthUrl();return $this->redirect()->toUrl(filter_var($auth_url, FILTER_SANITIZE_URL));}$google->authenticate(filter_var($_GET['code'], FILTER_SANITIZE_STRING));$accessToken = $google->getAccessToken();if(empty($accessToken)) {$flashMessenger = $this->plugin('FlashMessenger');$flashMessenger->addErrorMessage('Google access token is wrong');return $this->redirect()->toRoute('home');}$userInfo = $google->verifyIdToken();if(!is_array($userInfo) || empty($userInfo['sub']) || empty($userInfo['name']) || empty($userInfo['email']) || empty($userInfo['picture'])) {$flashMessenger = $this->plugin('FlashMessenger');$flashMessenger->addErrorMessage('Google verify token is wrong');return $this->redirect()->toRoute('home');}$id = filter_var($userInfo['sub'], FILTER_SANITIZE_STRING);$name = filter_var($userInfo['name'], FILTER_SANITIZE_STRING);$email = filter_var($userInfo['email'], FILTER_SANITIZE_EMAIL);$picture = filter_var($userInfo['picture'], FILTER_SANITIZE_URL);;return $this->process($id, $name, $email, $picture, UserProvider::PROVIDER_GOOGLE);}public function twitterAction(){if($this->config['leaderslinked.runmode.sandbox']) {$twitter_api_key = $this->config['leaderslinked.twitter.sandbox_api_key'];$twitter_api_secret = $this->config['leaderslinked.twitter.sandbox_api_secret'];} else {$twitter_api_key = $this->config['leaderslinked.twitter.production_api_key'];$twitter_api_secret = $this->config['leaderslinked.twitter.production_api_secret'];}$twitterSession = new \Laminas\Session\Container('twitter');$request_token = [];$request_token['oauth_token'] = $twitterSession->oauth_token;$request_token['oauth_token_secret'] = $twitterSession->oauth_token_secret;if (isset($_GET['oauth_token']) && $request_token['oauth_token'] !== $_GET['oauth_token']) {// Abort! Something is wrong.$flashMessenger = $this->plugin('FlashMessenger');$flashMessenger->addErrorMessage('Twitter Oauth token is wrong');return $this->redirect()->toRoute('home');}$twitter = new \Abraham\TwitterOAuth\TwitterOAuth($twitter_api_key, $twitter_api_secret, $request_token['oauth_token'], $request_token['oauth_token_secret']);$access_token = $twitter->oauth('oauth/access_token', ['oauth_verifier' => $_GET['oauth_verifier']]);$oauth_token = $access_token['oauth_token'];$oauth_token_secret = $access_token['oauth_token_secret'];/*stdClass Object ( [id] => 144499524 [id_str] => 144499524 [name] => Efrain Yanez R [screen_name] => eyanezve [location] => [description] => [url] => [entities] => stdClass Object ( [description] => stdClass Object ( [urls] => Array ( ) ) ) [protected] => 1 [followers_count] => 30 [friends_count] => 44 [listed_count] => 0 [created_at] => Sun May 16 13:36:21 +0000 2010 [favourites_count] => 5 [utc_offset] => [time_zone] => [geo_enabled] => [verified] => [statuses_count] => 0 [lang] => [contributors_enabled] => [is_translator] => [is_translation_enabled] => [profile_background_color] => C0DEED [profile_background_image_url] => http://abs.twimg.com/images/themes/theme1/bg.png [profile_background_image_url_https] => https://abs.twimg.com/images/themes/theme1/bg.png [profile_background_tile] => [profile_image_url] => http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png [profile_image_url_https] => https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png [profile_link_color] => 1DA1F2 [profile_sidebar_border_color] => C0DEED [profile_sidebar_fill_color] => DDEEF6 [profile_text_color] => 333333 [profile_use_background_image] => 1 [has_extended_profile] => 1 [default_profile] => 1 [default_profile_image] => 1 [following] => [follow_request_sent] => [notifications] => [translator_type] => none [suspended] => [needs_phone_verification] => [email] => eyanezve@gmail.com )*/$twitter = new \Abraham\TwitterOAuth\TwitterOAuth($twitter_api_key, $twitter_api_secret, $oauth_token, $oauth_token_secret);$response = $twitter->get('account/verify_credentials', ['include_entities' => true, 'skip_status' => true, 'include_email' => true]);$id = isset($response->id) ? filter_var($response->id, FILTER_SANITIZE_STRING) : '';$name = isset($response->name) ? filter_var($response->name, FILTER_SANITIZE_STRING) : '';$email = isset($response->email) ? filter_var($response->email, FILTER_SANITIZE_EMAIL) : '';$picture = isset($response->profile_image_url_https) ? filter_var($response->profile_image_url_https, FILTER_SANITIZE_URL) : '';return $this->process($id, $name, $email, $picture, UserProvider::PROVIDER_TWITTER);}private function registerBroserAndIp($user){$navigator = get_browser(null, true);$device_type = $navigator['device_type'];$platform = $navigator['platform'];$browser = $navigator['browser'];$userBrowserMapper = UserBrowserMapper::getInstance($this->adapter);$userBrowser = $userBrowserMapper->fetch($user->id, $device_type, $platform, $browser);if($userBrowser) {$userBrowserMapper->update($userBrowser);} else {$userBrowser = new UserBrowser();$userBrowser->user_id = $user->id;$userBrowser->browser = $browser;$userBrowser->platform = $platform;$userBrowser->device_type = $device_type;$userBrowser->is_tablet = intval( $navigator['istablet']);$userBrowser->is_mobile_device = intval( $navigator['ismobiledevice']);$userBrowser->version = $navigator['version'];$userBrowserMapper->insert($userBrowser);}//$ip = Functions::getUserIP();$ip = $ip == '127.0.0.1' ? '148.240.211.148' : $ip;$userIpMapper = UserIpMapper::getInstance($this->adapter);$userIp = $userIpMapper->fetch($user->id, $ip);if(empty($userIp)) {if($this->config['leaderslinked.runmode.sandbox']) {$filename = $this->config['leaderslinked.geoip2.production_database'];} else {$filename = $this->config['leaderslinked.geoip2.sandbox_database'];}$reader = new GeoIp2Reader($filename); //GeoIP2-City.mmdb');$record = $reader->city($ip);if($record) {$userIp = new UserIp();$userIp->user_id = $user->id;$userIp->city = utf8_decode($record->city->name);$userIp->state_code = utf8_decode($record->mostSpecificSubdivision->isoCode);$userIp->state_name = utf8_decode($record->mostSpecificSubdivision->name);$userIp->country_code = utf8_decode($record->country->isoCode);$userIp->country_name = utf8_decode($record->country->name);$userIp->ip = $ip;$userIp->latitude = $record->location->latitude;$userIp->longitude = $record->location->longitude;$userIp->postal_code = $record->postal->code;$userIpMapper->insert($userIp);}} else {$userIpMapper->update($userIp);}}}