[ Index ]

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


Generated: Sun Jun 23 12:25:44 2024 Cross-referenced by PHPXref 0.7.1