Rev 6849 | 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\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 \Laminas\Db\Adapter\AdapterInterface
*/
private $adapter;
/**
*
* @var \LeadersLinked\Cache\CacheInterface
*/
private $cache;
/**
*
* @var \Laminas\Log\LoggerInterface
*/
private $logger;
/**
*
* @var array
*/
private $config;
/**
*
* @var \Laminas\Mvc\I18n\Translator
*/
private $translator;
/**
*
* @param \Laminas\Db\Adapter\AdapterInterface $adapter
* @param \LeadersLinked\Cache\CacheInterface $cache
* @param \Laminas\Log\LoggerInterface LoggerInterface $logger
* @param array $config
* @param \Laminas\Mvc\I18n\Translator $translator
*/
public function __construct($adapter, $cache, $logger, $config, $translator)
{
$this->adapter = $adapter;
$this->cache = $cache;
$this->logger = $logger;
$this->config = $config;
$this->translator = $translator;
}
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 usuario
if($userProvider) {
$user = $userMapper->fetchOne($userProvider->user_id);
} else {
//Buscamos si esta registrado el usuario por email
$user = $userMapper->fetchOneByEmail($email);
//Creamos un usuario
if(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 = Functions::sanitizeFilterString($_GET['code']);
$state = Functions::sanitizeFilterString($_GET['state']);
$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 = Functions::sanitizeFilterString($fb_user->getId());
$name = Functions::sanitizeFilterString($fb_user->getName());
$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 = $_POST['signed_request'] ? Functions::sanitizeFilterString($_POST['signed_request']) : '';
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(Functions::sanitizeFilterString($_GET['code']));
$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 = Functions::sanitizeFilterString($userInfo['sub']);
$name =Functions::sanitizeFilterString($userInfo['name']);
$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 [prof
ile_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 = $response->id ? Functions::sanitizeFilterString($response->id) : '';
$name = $response->name ? Functions::sanitizeFilterString($response->name) : '';
$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 = Functions::utf8_decode($record->city->name);
$userIp->state_code = Functions::utf8_decode($record->mostSpecificSubdivision->isoCode);
$userIp->state_name = Functions::utf8_decode($record->mostSpecificSubdivision->name);
$userIp->country_code = Functions::utf8_decode($record->country->isoCode);
$userIp->country_name = Functions::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);
}
}
}