[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/phpbb/auth/provider/oauth/ -> oauth.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb\auth\provider\oauth;
  15  
  16  use OAuth\Common\Consumer\Credentials;
  17  
  18  /**
  19  * OAuth authentication provider for phpBB3
  20  */
  21  class oauth extends \phpbb\auth\provider\base
  22  {
  23      /**
  24      * Database driver
  25      *
  26      * @var \phpbb\db\driver\driver_interface
  27      */
  28      protected $db;
  29  
  30      /**
  31      * phpBB config
  32      *
  33      * @var \phpbb\config\config
  34      */
  35      protected $config;
  36  
  37      /**
  38      * phpBB passwords manager
  39      *
  40      * @var \phpbb\passwords\manager
  41      */
  42      protected $passwords_manager;
  43  
  44      /**
  45      * phpBB request object
  46      *
  47      * @var \phpbb\request\request_interface
  48      */
  49      protected $request;
  50  
  51      /**
  52      * phpBB user
  53      *
  54      * @var \phpbb\user
  55      */
  56      protected $user;
  57  
  58      /**
  59      * OAuth token table
  60      *
  61      * @var string
  62      */
  63      protected $auth_provider_oauth_token_storage_table;
  64  
  65      /**
  66      * OAuth state table
  67      *
  68      * @var string
  69      */
  70      protected $auth_provider_oauth_state_table;
  71  
  72      /**
  73      * OAuth account association table
  74      *
  75      * @var string
  76      */
  77      protected $auth_provider_oauth_token_account_assoc;
  78  
  79      /**
  80      * All OAuth service providers
  81      *
  82      * @var \phpbb\di\service_collection Contains \phpbb\auth\provider\oauth\service_interface
  83      */
  84      protected $service_providers;
  85  
  86      /**
  87      * Users table
  88      *
  89      * @var string
  90      */
  91      protected $users_table;
  92  
  93      /**
  94      * Cached current uri object
  95      *
  96      * @var \OAuth\Common\Http\Uri\UriInterface|null
  97      */
  98      protected $current_uri;
  99  
 100      /**
 101      * DI container
 102      *
 103      * @var \Symfony\Component\DependencyInjection\ContainerInterface
 104      */
 105      protected $phpbb_container;
 106  
 107      /**
 108      * phpBB event dispatcher
 109      *
 110      * @var \phpbb\event\dispatcher_interface
 111      */
 112      protected $dispatcher;
 113  
 114      /**
 115      * phpBB root path
 116      *
 117      * @var string
 118      */
 119      protected $phpbb_root_path;
 120  
 121      /**
 122      * PHP file extension
 123      *
 124      * @var string
 125      */
 126      protected $php_ext;
 127  
 128      /**
 129      * OAuth Authentication Constructor
 130      *
 131      * @param    \phpbb\db\driver\driver_interface    $db
 132      * @param    \phpbb\config\config    $config
 133      * @param    \phpbb\passwords\manager    $passwords_manager
 134      * @param    \phpbb\request\request_interface    $request
 135      * @param    \phpbb\user        $user
 136      * @param    string            $auth_provider_oauth_token_storage_table
 137      * @param    string            $auth_provider_oauth_state_table
 138      * @param    string            $auth_provider_oauth_token_account_assoc
 139      * @param    \phpbb\di\service_collection    $service_providers Contains \phpbb\auth\provider\oauth\service_interface
 140      * @param    string            $users_table
 141      * @param    \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
 142      * @param    \phpbb\event\dispatcher_interface $dispatcher phpBB event dispatcher
 143      * @param    string            $phpbb_root_path
 144      * @param    string            $php_ext
 145      */
 146  	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_state_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $php_ext)
 147      {
 148          $this->db = $db;
 149          $this->config = $config;
 150          $this->passwords_manager = $passwords_manager;
 151          $this->request = $request;
 152          $this->user = $user;
 153          $this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table;
 154          $this->auth_provider_oauth_state_table = $auth_provider_oauth_state_table;
 155          $this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc;
 156          $this->service_providers = $service_providers;
 157          $this->users_table = $users_table;
 158          $this->phpbb_container = $phpbb_container;
 159          $this->dispatcher = $dispatcher;
 160          $this->phpbb_root_path = $phpbb_root_path;
 161          $this->php_ext = $php_ext;
 162      }
 163  
 164      /**
 165      * {@inheritdoc}
 166      */
 167  	public function init()
 168      {
 169          // This does not test whether or not the key and secret provided are valid.
 170          foreach ($this->service_providers as $service_provider)
 171          {
 172              $credentials = $service_provider->get_service_credentials();
 173  
 174              if (($credentials['key'] && !$credentials['secret']) || (!$credentials['key'] && $credentials['secret']))
 175              {
 176                  return $this->user->lang['AUTH_PROVIDER_OAUTH_ERROR_ELEMENT_MISSING'];
 177              }
 178          }
 179          return false;
 180      }
 181  
 182      /**
 183      * {@inheritdoc}
 184      */
 185  	public function login($username, $password)
 186      {
 187          // Temporary workaround for only having one authentication provider available
 188          if (!$this->request->is_set('oauth_service'))
 189          {
 190              $provider = new \phpbb\auth\provider\db($this->db, $this->config, $this->passwords_manager, $this->request, $this->user, $this->phpbb_container, $this->phpbb_root_path, $this->php_ext);
 191              return $provider->login($username, $password);
 192          }
 193  
 194          // Request the name of the OAuth service
 195          $service_name_original = $this->request->variable('oauth_service', '', false);
 196          $service_name = 'auth.provider.oauth.service.' . strtolower($service_name_original);
 197          if ($service_name_original === '' || !array_key_exists($service_name, $this->service_providers))
 198          {
 199              return array(
 200                  'status'        => LOGIN_ERROR_EXTERNAL_AUTH,
 201                  'error_msg'        => 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST',
 202                  'user_row'        => array('user_id' => ANONYMOUS),
 203              );
 204          }
 205  
 206          // Get the service credentials for the given service
 207          $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
 208  
 209          $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
 210          $query = 'mode=login&login=external&oauth_service=' . $service_name_original;
 211          $service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope());
 212  
 213          if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
 214              || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
 215          {
 216              $this->service_providers[$service_name]->set_external_service_provider($service);
 217              $unique_id = $this->service_providers[$service_name]->perform_auth_login();
 218  
 219              /**
 220               * Check to see if this provider is already associated with an account.
 221               *
 222               * Enforcing a data type to make data contains strings and not integers,
 223               * so values are quoted in the SQL WHERE statement.
 224               */
 225              $data = array(
 226                  'provider'            => (string) $service_name_original,
 227                  'oauth_provider_id'    => (string) $unique_id
 228              );
 229  
 230              $sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
 231                  WHERE ' . $this->db->sql_build_array('SELECT', $data);
 232              $result = $this->db->sql_query($sql);
 233              $row = $this->db->sql_fetchrow($result);
 234              $this->db->sql_freeresult($result);
 235  
 236              $redirect_data = array(
 237                  'auth_provider'                => 'oauth',
 238                  'login_link_oauth_service'    => $service_name_original,
 239              );
 240  
 241              /**
 242              * Event is triggered before check if provider is already associated with an account
 243              *
 244              * @event core.oauth_login_after_check_if_provider_id_has_match
 245              * @var    array                                    row                User row
 246              * @var    array                                    data            Provider data
 247              * @var    array                                    redirect_data    Data to be appended to the redirect url
 248              * @var    \OAuth\Common\Service\ServiceInterface    service            OAuth service
 249              * @since 3.2.3-RC1
 250              * @changed 3.2.6-RC1 Added redirect_data
 251              */
 252              $vars = array(
 253                  'row',
 254                  'data',
 255                  'redirect_data',
 256                  'service',
 257              );
 258              extract($this->dispatcher->trigger_event('core.oauth_login_after_check_if_provider_id_has_match', compact($vars)));
 259  
 260              if (!$row)
 261              {
 262                  // The user does not yet exist, ask to link or create profile
 263                  return array(
 264                      'status'        => LOGIN_SUCCESS_LINK_PROFILE,
 265                      'error_msg'        => 'LOGIN_OAUTH_ACCOUNT_NOT_LINKED',
 266                      'user_row'        => array(),
 267                      'redirect_data'    => $redirect_data,
 268                  );
 269              }
 270  
 271              // Retrieve the user's account
 272              $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_ip, user_type, user_login_attempts
 273                  FROM ' . $this->users_table . '
 274                      WHERE user_id = ' . (int) $row['user_id'];
 275              $result = $this->db->sql_query($sql);
 276              $row = $this->db->sql_fetchrow($result);
 277              $this->db->sql_freeresult($result);
 278  
 279              if (!$row)
 280              {
 281                  throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
 282              }
 283  
 284              /**
 285               * Check if the user is banned.
 286               * The fourth parameter, return, has to be true,
 287               * otherwise the OAuth login is still called and
 288               * an uncaught exception is thrown as there is no
 289               * token stored in the database.
 290               */
 291              $ban = $this->user->check_ban($row['user_id'], $row['user_ip'], $row['user_email'], true);
 292              if (!empty($ban))
 293              {
 294                  $till_date = !empty($ban['ban_end']) ? $this->user->format_date($ban['ban_end']) : '';
 295                  $message = !empty($ban['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
 296  
 297                  $contact_link = phpbb_get_board_contact_link($this->config, $this->phpbb_root_path, $this->php_ext);
 298                  $message = $this->user->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
 299                  $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->user->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
 300                  $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->user->lang('BAN_TRIGGERED_BY_' . strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
 301  
 302                  return array(
 303                      'status'    => LOGIN_BREAK,
 304                      'error_msg'    => $message,
 305                      'user_row'    => $row,
 306                  );
 307              }
 308  
 309              // Update token storage to store the user_id
 310              $storage->set_user_id($row['user_id']);
 311  
 312              /**
 313              * Event is triggered after user is successfully logged in via OAuth.
 314              *
 315              * @event core.auth_oauth_login_after
 316              * @var    array    row    User row
 317              * @since 3.1.11-RC1
 318              */
 319              $vars = array(
 320                  'row',
 321              );
 322              extract($this->dispatcher->trigger_event('core.auth_oauth_login_after', compact($vars)));
 323  
 324              // The user is now authenticated and can be logged in
 325              return array(
 326                  'status'        => LOGIN_SUCCESS,
 327                  'error_msg'        => false,
 328                  'user_row'        => $row,
 329              );
 330          }
 331          else
 332          {
 333              if ($service::OAUTH_VERSION === 1)
 334              {
 335                  $token = $service->requestRequestToken();
 336                  $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
 337              }
 338              else
 339              {
 340                  $url = $service->getAuthorizationUri();
 341              }
 342              header('Location: ' . $url);
 343          }
 344      }
 345  
 346      /**
 347      * Returns the cached current_uri object or creates and caches it if it is
 348      * not already created. In each case the query string is updated based on
 349      * the $query parameter.
 350      *
 351      * @param    string    $service_name    The name of the service
 352      * @param    string    $query            The query string of the current_uri
 353      *                                    used in redirects
 354      * @return    \OAuth\Common\Http\Uri\UriInterface
 355      */
 356  	protected function get_current_uri($service_name, $query)
 357      {
 358          if ($this->current_uri)
 359          {
 360              $this->current_uri->setQuery($query);
 361              return $this->current_uri;
 362          }
 363  
 364          $uri_factory = new \OAuth\Common\Http\Uri\UriFactory();
 365          $super_globals = $this->request->get_super_global(\phpbb\request\request_interface::SERVER);
 366          if (!empty($super_globals['HTTP_X_FORWARDED_PROTO']) && $super_globals['HTTP_X_FORWARDED_PROTO'] === 'https')
 367          {
 368              $super_globals['HTTPS'] = 'on';
 369              $super_globals['SERVER_PORT'] = 443;
 370          }
 371          $current_uri = $uri_factory->createFromSuperGlobalArray($super_globals);
 372          $current_uri->setQuery($query);
 373  
 374          $this->current_uri = $current_uri;
 375          return $current_uri;
 376      }
 377  
 378      /**
 379      * Returns a new service object
 380      *
 381      * @param    string    $service_name            The name of the service
 382      * @param    \phpbb\auth\provider\oauth\token_storage $storage
 383      * @param    array    $service_credentials    {@see \phpbb\auth\provider\oauth\oauth::get_service_credentials}
 384      * @param    string    $query                    The query string of the
 385      *                                            current_uri used in redirection
 386      * @param    array    $scopes                    The scope of the request against
 387      *                                            the api.
 388      * @return    \OAuth\Common\Service\ServiceInterface
 389      * @throws    \Exception
 390      */
 391  	protected function get_service($service_name, \phpbb\auth\provider\oauth\token_storage $storage, array $service_credentials, $query, array $scopes = array())
 392      {
 393          $current_uri = $this->get_current_uri($service_name, $query);
 394  
 395          // Setup the credentials for the requests
 396          $credentials = new Credentials(
 397              $service_credentials['key'],
 398              $service_credentials['secret'],
 399              $current_uri->getAbsoluteUri()
 400          );
 401  
 402          $service_factory = new \OAuth\ServiceFactory();
 403          $service = $service_factory->createService($service_name, $credentials, $storage, $scopes);
 404  
 405          if (!$service)
 406          {
 407              throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED');
 408          }
 409  
 410          return $service;
 411      }
 412  
 413      /**
 414      * {@inheritdoc}
 415      */
 416  	public function get_login_data()
 417      {
 418          $login_data = array(
 419              'TEMPLATE_FILE'        => 'login_body_oauth.html',
 420              'BLOCK_VAR_NAME'    => 'oauth',
 421              'BLOCK_VARS'        => array(),
 422          );
 423  
 424          foreach ($this->service_providers as $service_name => $service_provider)
 425          {
 426              // Only include data if the credentials are set
 427              $credentials = $service_provider->get_service_credentials();
 428              if ($credentials['key'] && $credentials['secret'])
 429              {
 430                  $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
 431                  $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $actual_name;
 432                  $login_data['BLOCK_VARS'][$service_name] = array(
 433                      'REDIRECT_URL'    => redirect($redirect_url, true),
 434                      'SERVICE_NAME'    => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
 435                  );
 436              }
 437          }
 438  
 439          return $login_data;
 440      }
 441  
 442      /**
 443      * {@inheritdoc}
 444      */
 445  	public function acp()
 446      {
 447          $ret = array();
 448  
 449          foreach ($this->service_providers as $service_name => $service_provider)
 450          {
 451              $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
 452              $ret[] = 'auth_oauth_' . $actual_name . '_key';
 453              $ret[] = 'auth_oauth_' . $actual_name . '_secret';
 454          }
 455  
 456          return $ret;
 457      }
 458  
 459      /**
 460      * {@inheritdoc}
 461      */
 462  	public function get_acp_template($new_config)
 463      {
 464          $ret = array(
 465              'BLOCK_VAR_NAME'    => 'oauth_services',
 466              'BLOCK_VARS'        => array(),
 467              'TEMPLATE_FILE'        => 'auth_provider_oauth.html',
 468              'TEMPLATE_VARS'        => array(),
 469          );
 470  
 471          foreach ($this->service_providers as $service_name => $service_provider)
 472          {
 473              $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
 474              $ret['BLOCK_VARS'][$actual_name] = array(
 475                  'ACTUAL_NAME'    => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
 476                  'KEY'            => $new_config['auth_oauth_' . $actual_name . '_key'],
 477                  'NAME'            => $actual_name,
 478                  'SECRET'        => $new_config['auth_oauth_' . $actual_name . '_secret'],
 479              );
 480          }
 481  
 482          return $ret;
 483      }
 484  
 485      /**
 486      * {@inheritdoc}
 487      */
 488  	public function login_link_has_necessary_data($login_link_data)
 489      {
 490          if (empty($login_link_data))
 491          {
 492              return 'LOGIN_LINK_NO_DATA_PROVIDED';
 493          }
 494  
 495          if (!array_key_exists('oauth_service', $login_link_data) || !$login_link_data['oauth_service'] ||
 496              !array_key_exists('link_method', $login_link_data) || !$login_link_data['link_method'])
 497          {
 498              return 'LOGIN_LINK_MISSING_DATA';
 499          }
 500  
 501          return null;
 502      }
 503  
 504      /**
 505      * {@inheritdoc}
 506      */
 507  	public function link_account(array $link_data)
 508      {
 509          // Check for a valid link method (auth_link or login_link)
 510          if (!array_key_exists('link_method', $link_data) ||
 511              !in_array($link_data['link_method'], array(
 512                  'auth_link',
 513                  'login_link',
 514              )))
 515          {
 516              return 'LOGIN_LINK_MISSING_DATA';
 517          }
 518  
 519          // We must have an oauth_service listed, check for it two ways
 520          if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service'])
 521          {
 522              $link_data['oauth_service'] = $this->request->variable('oauth_service', '');
 523  
 524              if (!$link_data['oauth_service'])
 525              {
 526                  return 'LOGIN_LINK_MISSING_DATA';
 527              }
 528          }
 529  
 530          $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
 531          if (!array_key_exists($service_name, $this->service_providers))
 532          {
 533              return 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST';
 534          }
 535  
 536          switch ($link_data['link_method'])
 537          {
 538              case 'auth_link':
 539                  return $this->link_account_auth_link($link_data, $service_name);
 540              case 'login_link':
 541                  return $this->link_account_login_link($link_data, $service_name);
 542          }
 543      }
 544  
 545      /**
 546      * Performs the account linking for login_link
 547      *
 548      * @param    array    $link_data        The same variable given to {@see \phpbb\auth\provider\provider_interface::link_account}
 549      * @param    string    $service_name    The name of the service being used in
 550      *                                    linking.
 551      * @return    string|null    Returns a language constant (string) if an error is
 552      *                        encountered, or null on success.
 553      */
 554  	protected function link_account_login_link(array $link_data, $service_name)
 555      {
 556          $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
 557  
 558          // Check for an access token, they should have one
 559          if (!$storage->has_access_token_by_session($service_name))
 560          {
 561              return 'LOGIN_LINK_ERROR_OAUTH_NO_ACCESS_TOKEN';
 562          }
 563  
 564          // Prepare the query string
 565          $query = 'mode=login_link&login_link_oauth_service=' . strtolower($link_data['oauth_service']);
 566  
 567          // Prepare for an authentication request
 568          $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
 569          $scopes = $this->service_providers[$service_name]->get_auth_scope();
 570          $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
 571          $this->service_providers[$service_name]->set_external_service_provider($service);
 572  
 573          // The user has already authenticated successfully, request to authenticate again
 574          $unique_id = $this->service_providers[$service_name]->perform_token_auth();
 575  
 576          // Insert into table, they will be able to log in after this
 577          $data = array(
 578              'user_id'            => $link_data['user_id'],
 579              'provider'            => strtolower($link_data['oauth_service']),
 580              'oauth_provider_id'    => $unique_id,
 581          );
 582  
 583          $this->link_account_perform_link($data);
 584          // Update token storage to store the user_id
 585          $storage->set_user_id($link_data['user_id']);
 586      }
 587  
 588      /**
 589      * Performs the account linking for auth_link
 590      *
 591      * @param    array    $link_data        The same variable given to {@see \phpbb\auth\provider\provider_interface::link_account}
 592      * @param    string    $service_name    The name of the service being used in
 593      *                                    linking.
 594      * @return    string|null    Returns a language constant (string) if an error is
 595      *                        encountered, or null on success.
 596      */
 597  	protected function link_account_auth_link(array $link_data, $service_name)
 598      {
 599          $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
 600          $query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']);
 601          $service_credentials = $this->service_providers[$service_name]->get_service_credentials();
 602          $scopes = $this->service_providers[$service_name]->get_auth_scope();
 603          $service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
 604  
 605          if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
 606              || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
 607          {
 608              $this->service_providers[$service_name]->set_external_service_provider($service);
 609              $unique_id = $this->service_providers[$service_name]->perform_auth_login();
 610  
 611              // Insert into table, they will be able to log in after this
 612              $data = array(
 613                  'user_id'            => $this->user->data['user_id'],
 614                  'provider'            => strtolower($link_data['oauth_service']),
 615                  'oauth_provider_id'    => $unique_id,
 616              );
 617  
 618              $this->link_account_perform_link($data);
 619          }
 620          else
 621          {
 622              if ($service::OAUTH_VERSION === 1)
 623              {
 624                  $token = $service->requestRequestToken();
 625                  $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
 626              }
 627              else
 628              {
 629                  $url = $service->getAuthorizationUri();
 630              }
 631              header('Location: ' . $url);
 632          }
 633      }
 634  
 635      /**
 636      * Performs the query that inserts an account link
 637      *
 638      * @param    array    $data    This array is passed to db->sql_build_array
 639      */
 640  	protected function link_account_perform_link(array $data)
 641      {
 642          // Check if the external account is already associated with other user
 643          $sql = 'SELECT user_id
 644              FROM ' . $this->auth_provider_oauth_token_account_assoc . "
 645              WHERE provider = '" . $this->db->sql_escape($data['provider']) . "'
 646                  AND oauth_provider_id = '" . $this->db->sql_escape($data['oauth_provider_id']) . "'";
 647          $result = $this->db->sql_query($sql);
 648          $row = $this->db->sql_fetchrow($result);
 649          $this->db->sql_freeresult($result);
 650  
 651          if ($row)
 652          {
 653              trigger_error('AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED');
 654          }
 655  
 656          // Link account
 657          $sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . '
 658              ' . $this->db->sql_build_array('INSERT', $data);
 659          $this->db->sql_query($sql);
 660  
 661          /**
 662           * Event is triggered after user links account.
 663           *
 664           * @event core.auth_oauth_link_after
 665           * @var    array    data    User row
 666           * @since 3.1.11-RC1
 667           */
 668          $vars = array(
 669              'data',
 670          );
 671          extract($this->dispatcher->trigger_event('core.auth_oauth_link_after', compact($vars)));
 672      }
 673  
 674      /**
 675      * {@inheritdoc}
 676      */
 677  	public function logout($data, $new_session)
 678      {
 679          // Clear all tokens belonging to the user
 680          $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
 681          $storage->clearAllTokens();
 682  
 683          return;
 684      }
 685  
 686      /**
 687      * {@inheritdoc}
 688      */
 689  	public function get_auth_link_data($user_id = 0)
 690      {
 691          $block_vars = array();
 692  
 693          // Get all external accounts tied to the current user
 694          $data = array(
 695              'user_id' => ($user_id <= 0) ? (int) $this->user->data['user_id'] : (int) $user_id,
 696          );
 697          $sql = 'SELECT oauth_provider_id, provider FROM ' . $this->auth_provider_oauth_token_account_assoc . '
 698              WHERE ' . $this->db->sql_build_array('SELECT', $data);
 699          $result = $this->db->sql_query($sql);
 700          $rows = $this->db->sql_fetchrowset($result);
 701          $this->db->sql_freeresult($result);
 702  
 703          $oauth_user_ids = array();
 704  
 705          if ($rows !== false && count($rows))
 706          {
 707              foreach ($rows as $row)
 708              {
 709                  $oauth_user_ids[$row['provider']] = $row['oauth_provider_id'];
 710              }
 711          }
 712          unset($rows);
 713  
 714          foreach ($this->service_providers as $service_name => $service_provider)
 715          {
 716              // Only include data if the credentials are set
 717              $credentials = $service_provider->get_service_credentials();
 718              if ($credentials['key'] && $credentials['secret'])
 719              {
 720                  $actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
 721  
 722                  $block_vars[$service_name] = array(
 723                      'HIDDEN_FIELDS'    => array(
 724                          'link'            => (!isset($oauth_user_ids[$actual_name])),
 725                          'oauth_service' => $actual_name,
 726                      ),
 727  
 728                      'SERVICE_ID'    => $actual_name,
 729                      'SERVICE_NAME'    => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
 730                      'UNIQUE_ID'        => (isset($oauth_user_ids[$actual_name])) ? $oauth_user_ids[$actual_name] : null,
 731                  );
 732              }
 733          }
 734  
 735          return array(
 736              'BLOCK_VAR_NAME'    => 'oauth',
 737              'BLOCK_VARS'        => $block_vars,
 738  
 739              'TEMPLATE_FILE'    => 'ucp_auth_link_oauth.html',
 740          );
 741      }
 742  
 743      /**
 744      * {@inheritdoc}
 745      */
 746  	public function unlink_account(array $link_data)
 747      {
 748          if (!array_key_exists('oauth_service', $link_data) || !$link_data['oauth_service'])
 749          {
 750              return 'LOGIN_LINK_MISSING_DATA';
 751          }
 752  
 753          // Remove user specified in $link_data if possible
 754          $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id'];
 755  
 756          // Remove the link
 757          $sql = 'DELETE FROM ' . $this->auth_provider_oauth_token_account_assoc . "
 758              WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "'
 759                  AND user_id = " . (int) $user_id;
 760          $this->db->sql_query($sql);
 761  
 762          // Clear all tokens belonging to the user on this service
 763          $service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
 764          $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
 765          $storage->clearToken($service_name);
 766      }
 767  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1