[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/phpbb/auth/provider/oauth/ -> token_storage.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\OAuth1\Token\StdOAuth1Token;
  17  use OAuth\Common\Token\TokenInterface;
  18  use OAuth\Common\Storage\TokenStorageInterface;
  19  use OAuth\Common\Storage\Exception\TokenNotFoundException;
  20  use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
  21  
  22  /**
  23  * OAuth storage wrapper for phpbb's cache
  24  */
  25  class token_storage implements TokenStorageInterface
  26  {
  27      /**
  28      * Cache driver.
  29      *
  30      * @var \phpbb\db\driver\driver_interface
  31      */
  32      protected $db;
  33  
  34      /**
  35      * phpBB user
  36      *
  37      * @var \phpbb\user
  38      */
  39      protected $user;
  40  
  41      /**
  42      * OAuth token table
  43      *
  44      * @var string
  45      */
  46      protected $oauth_token_table;
  47  
  48      /**
  49      * OAuth state table
  50      *
  51      * @var string
  52      */
  53      protected $oauth_state_table;
  54  
  55      /**
  56      * @var object|TokenInterface
  57      */
  58      protected $cachedToken;
  59  
  60      /**
  61      * @var string
  62      */
  63      protected $cachedState;
  64  
  65      /**
  66      * Creates token storage for phpBB.
  67      *
  68      * @param    \phpbb\db\driver\driver_interface    $db
  69      * @param    \phpbb\user        $user
  70      * @param    string            $oauth_token_table
  71      * @param    string            $oauth_state_table
  72      */
  73  	public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $oauth_token_table, $oauth_state_table)
  74      {
  75          $this->db = $db;
  76          $this->user = $user;
  77          $this->oauth_token_table = $oauth_token_table;
  78          $this->oauth_state_table = $oauth_state_table;
  79      }
  80  
  81      /**
  82      * {@inheritdoc}
  83      */
  84  	public function retrieveAccessToken($service)
  85      {
  86          $service = $this->get_service_name_for_db($service);
  87  
  88          if ($this->cachedToken instanceof TokenInterface)
  89          {
  90              return $this->cachedToken;
  91          }
  92  
  93          $data = array(
  94              'user_id'    => (int) $this->user->data['user_id'],
  95              'provider'    => $service,
  96          );
  97  
  98          if ((int) $this->user->data['user_id'] === ANONYMOUS)
  99          {
 100              $data['session_id']    = $this->user->data['session_id'];
 101          }
 102  
 103          return $this->_retrieve_access_token($data);
 104      }
 105  
 106      /**
 107      * {@inheritdoc}
 108      */
 109  	public function storeAccessToken($service, TokenInterface $token)
 110      {
 111          $service = $this->get_service_name_for_db($service);
 112  
 113          $this->cachedToken = $token;
 114  
 115          $data = array(
 116              'oauth_token'    => $this->json_encode_token($token),
 117          );
 118  
 119          $sql = 'UPDATE ' . $this->oauth_token_table . '
 120                  SET ' . $this->db->sql_build_array('UPDATE', $data) . '
 121                  WHERE user_id = ' . (int) $this->user->data['user_id'] . '
 122                      ' . ((int) $this->user->data['user_id'] === ANONYMOUS ? "AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'" : '') . "
 123                      AND provider = '" . $this->db->sql_escape($service) . "'";
 124          $this->db->sql_query($sql);
 125  
 126          if (!$this->db->sql_affectedrows())
 127          {
 128              $data = array(
 129                  'user_id'        => (int) $this->user->data['user_id'],
 130                  'provider'        => $service,
 131                  'oauth_token'    => $this->json_encode_token($token),
 132                  'session_id'    => $this->user->data['session_id'],
 133              );
 134  
 135              $sql = 'INSERT INTO ' . $this->oauth_token_table . $this->db->sql_build_array('INSERT', $data);
 136  
 137              $this->db->sql_query($sql);
 138          }
 139  
 140          return $this;
 141      }
 142  
 143      /**
 144      * {@inheritdoc}
 145      */
 146  	public function hasAccessToken($service)
 147      {
 148          $service = $this->get_service_name_for_db($service);
 149  
 150          if ($this->cachedToken)
 151          {
 152              return true;
 153          }
 154  
 155          $data = array(
 156              'user_id'    => (int) $this->user->data['user_id'],
 157              'provider'    => $service,
 158          );
 159  
 160          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 161          {
 162              $data['session_id']    = $this->user->data['session_id'];
 163          }
 164  
 165          return $this->_has_acess_token($data);
 166      }
 167  
 168      /**
 169      * {@inheritdoc}
 170      */
 171  	public function clearToken($service)
 172      {
 173          $service = $this->get_service_name_for_db($service);
 174  
 175          $this->cachedToken = null;
 176  
 177          $sql = 'DELETE FROM ' . $this->oauth_token_table . '
 178              WHERE user_id = ' . (int) $this->user->data['user_id'] . "
 179                  AND provider = '" . $this->db->sql_escape($service) . "'";
 180  
 181          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 182          {
 183              $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
 184          }
 185  
 186          $this->db->sql_query($sql);
 187  
 188          return $this;
 189      }
 190  
 191      /**
 192      * {@inheritdoc}
 193      */
 194  	public function clearAllTokens()
 195      {
 196          $this->cachedToken = null;
 197  
 198          $sql = 'DELETE FROM ' . $this->oauth_token_table . '
 199              WHERE user_id = ' . (int) $this->user->data['user_id'];
 200  
 201          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 202          {
 203              $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
 204          }
 205  
 206          $this->db->sql_query($sql);
 207  
 208          return $this;
 209      }
 210  
 211      /**
 212      * {@inheritdoc}
 213      */
 214  	public function storeAuthorizationState($service, $state)
 215      {
 216          $service = $this->get_service_name_for_db($service);
 217  
 218          $this->cachedState = $state;
 219  
 220          $data = array(
 221              'user_id'        => (int) $this->user->data['user_id'],
 222              'provider'        => $service,
 223              'oauth_state'    => $state,
 224              'session_id'    => $this->user->data['session_id'],
 225          );
 226  
 227          $sql = 'INSERT INTO ' . $this->oauth_state_table . '
 228              ' . $this->db->sql_build_array('INSERT', $data);
 229          $this->db->sql_query($sql);
 230  
 231          return $this;
 232      }
 233  
 234      /**
 235      * {@inheritdoc}
 236      */
 237  	public function hasAuthorizationState($service)
 238      {
 239          $service = $this->get_service_name_for_db($service);
 240  
 241          if ($this->cachedState)
 242          {
 243              return true;
 244          }
 245  
 246          $data = array(
 247              'user_id'    => (int) $this->user->data['user_id'],
 248              'provider'    => $service,
 249          );
 250  
 251          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 252          {
 253              $data['session_id']    = $this->user->data['session_id'];
 254          }
 255  
 256          return (bool) $this->get_state_row($data);
 257      }
 258  
 259      /**
 260      * {@inheritdoc}
 261      */
 262  	public function retrieveAuthorizationState($service)
 263      {
 264          $service = $this->get_service_name_for_db($service);
 265  
 266          if ($this->cachedState)
 267          {
 268              return $this->cachedState;
 269          }
 270  
 271          $data = array(
 272              'user_id'    => (int) $this->user->data['user_id'],
 273              'provider'    => $service,
 274          );
 275  
 276          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 277          {
 278              $data['session_id']    = $this->user->data['session_id'];
 279          }
 280  
 281          return $this->get_state_row($data);
 282      }
 283  
 284      /**
 285      * {@inheritdoc}
 286      */
 287  	public function clearAuthorizationState($service)
 288      {
 289          $service = $this->get_service_name_for_db($service);
 290  
 291          $this->cachedState = null;
 292  
 293          $sql = 'DELETE FROM ' . $this->oauth_state_table . '
 294              WHERE user_id = ' . (int) $this->user->data['user_id'] . "
 295                  AND provider = '" . $this->db->sql_escape($service) . "'";
 296  
 297          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 298          {
 299              $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
 300          }
 301  
 302          $this->db->sql_query($sql);
 303  
 304          return $this;
 305      }
 306  
 307      /**
 308      * {@inheritdoc}
 309      */
 310  	public function clearAllAuthorizationStates()
 311      {
 312          $this->cachedState = null;
 313  
 314          $sql = 'DELETE FROM ' . $this->oauth_state_table . '
 315              WHERE user_id = ' . (int) $this->user->data['user_id'];
 316  
 317          if ((int) $this->user->data['user_id'] === ANONYMOUS)
 318          {
 319              $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
 320          }
 321  
 322          $this->db->sql_query($sql);
 323  
 324          return $this;
 325      }
 326  
 327      /**
 328      * Updates the user_id field in the database assosciated with the token
 329      *
 330      * @param    int    $user_id
 331      */
 332  	public function set_user_id($user_id)
 333      {
 334          if (!$this->cachedToken)
 335          {
 336              return;
 337          }
 338  
 339          $sql = 'UPDATE ' . $this->oauth_token_table . '
 340              SET ' . $this->db->sql_build_array('UPDATE', array(
 341                      'user_id' => (int) $user_id
 342                  )) . '
 343                  WHERE user_id = ' . (int) $this->user->data['user_id'] . "
 344                      AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
 345          $this->db->sql_query($sql);
 346      }
 347  
 348      /**
 349      * Checks to see if an access token exists solely by the session_id of the user
 350      *
 351      * @param    string    $service    The name of the OAuth service
 352      * @return    bool    true if they have token, false if they don't
 353      */
 354  	public function has_access_token_by_session($service)
 355      {
 356          $service = $this->get_service_name_for_db($service);
 357  
 358          if ($this->cachedToken)
 359          {
 360              return true;
 361          }
 362  
 363          $data = array(
 364              'session_id'    => $this->user->data['session_id'],
 365              'provider'        => $service,
 366          );
 367  
 368          return $this->_has_acess_token($data);
 369      }
 370  
 371      /**
 372      * Checks to see if a state exists solely by the session_id of the user
 373      *
 374      * @param    string    $service    The name of the OAuth service
 375      * @return    bool    true if they have state, false if they don't
 376      */
 377  	public function has_state_by_session($service)
 378      {
 379          $service = $this->get_service_name_for_db($service);
 380  
 381          if ($this->cachedState)
 382          {
 383              return true;
 384          }
 385  
 386          $data = array(
 387              'session_id'    => $this->user->data['session_id'],
 388              'provider'        => $service,
 389          );
 390  
 391          return (bool) $this->get_state_row($data);
 392      }
 393  
 394      /**
 395      * A helper function that performs the query for has access token functions
 396      *
 397      * @param    array    $data
 398      * @return    bool
 399      */
 400  	protected function _has_acess_token($data)
 401      {
 402          return (bool) $this->get_access_token_row($data);
 403      }
 404  
 405  	public function retrieve_access_token_by_session($service)
 406      {
 407          $service = $this->get_service_name_for_db($service);
 408  
 409          if ($this->cachedToken instanceof TokenInterface)
 410          {
 411              return $this->cachedToken;
 412          }
 413  
 414          $data = array(
 415              'session_id'    => $this->user->data['session_id'],
 416              'provider'    => $service,
 417          );
 418  
 419          return $this->_retrieve_access_token($data);
 420      }
 421  
 422  	public function retrieve_state_by_session($service)
 423      {
 424          $service = $this->get_service_name_for_db($service);
 425  
 426          if ($this->cachedState)
 427          {
 428              return $this->cachedState;
 429          }
 430  
 431          $data = array(
 432              'session_id'    => $this->user->data['session_id'],
 433              'provider'    => $service,
 434          );
 435  
 436          return $this->_retrieve_state($data);
 437      }
 438  
 439      /**
 440      * A helper function that performs the query for retrieve access token functions
 441      * Also checks if the token is a valid token
 442      *
 443      * @param    array    $data
 444      * @return    mixed
 445      * @throws \OAuth\Common\Storage\Exception\TokenNotFoundException
 446      */
 447  	protected function _retrieve_access_token($data)
 448      {
 449          $row = $this->get_access_token_row($data);
 450  
 451          if (!$row)
 452          {
 453              throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_NOT_STORED');
 454          }
 455  
 456          $token = $this->json_decode_token($row['oauth_token']);
 457  
 458          // Ensure that the token was serialized/unserialized correctly
 459          if (!($token instanceof TokenInterface))
 460          {
 461              $this->clearToken($data['provider']);
 462              throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED');
 463          }
 464  
 465          $this->cachedToken = $token;
 466          return $token;
 467      }
 468  
 469      /**
 470       * A helper function that performs the query for retrieve state functions
 471       *
 472       * @param    array    $data
 473       * @return    mixed
 474       * @throws \OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException
 475       */
 476  	protected function _retrieve_state($data)
 477      {
 478          $row = $this->get_state_row($data);
 479  
 480          if (!$row)
 481          {
 482              throw new AuthorizationStateNotFoundException();
 483          }
 484  
 485          $this->cachedState = $row['oauth_state'];
 486          return $this->cachedState;
 487      }
 488  
 489      /**
 490      * A helper function that performs the query for retrieving an access token
 491      *
 492      * @param    array    $data
 493      * @return    mixed
 494      */
 495  	protected function get_access_token_row($data)
 496      {
 497          $sql = 'SELECT oauth_token FROM ' . $this->oauth_token_table . '
 498              WHERE ' . $this->db->sql_build_array('SELECT', $data);
 499          $result = $this->db->sql_query($sql);
 500          $row = $this->db->sql_fetchrow($result);
 501          $this->db->sql_freeresult($result);
 502  
 503          return $row;
 504      }
 505  
 506      /**
 507       * A helper function that performs the query for retrieving a state
 508       *
 509       * @param    array    $data
 510       * @return    mixed
 511       */
 512  	protected function get_state_row($data)
 513      {
 514          $sql = 'SELECT oauth_state FROM ' . $this->oauth_state_table . '
 515              WHERE ' . $this->db->sql_build_array('SELECT', $data);
 516          $result = $this->db->sql_query($sql);
 517          $row = $this->db->sql_fetchrow($result);
 518          $this->db->sql_freeresult($result);
 519  
 520          return $row;
 521      }
 522  
 523  	public function json_encode_token(TokenInterface $token)
 524      {
 525          $members = array(
 526              'accessToken'    => $token->getAccessToken(),
 527              'endOfLife'        => $token->getEndOfLife(),
 528              'extraParams'    => $token->getExtraParams(),
 529              'refreshToken'    => $token->getRefreshToken(),
 530  
 531              'token_class'    => get_class($token),
 532          );
 533  
 534          // Handle additional data needed for OAuth1 tokens
 535          if ($token instanceof StdOAuth1Token)
 536          {
 537              $members['requestToken']        = $token->getRequestToken();
 538              $members['requestTokenSecret']    = $token->getRequestTokenSecret();
 539              $members['accessTokenSecret']    = $token->getAccessTokenSecret();
 540          }
 541  
 542          return json_encode($members);
 543      }
 544  
 545  	public function json_decode_token($json)
 546      {
 547          $token_data = json_decode($json, true);
 548  
 549          if ($token_data === null)
 550          {
 551              throw new TokenNotFoundException('AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED');
 552          }
 553  
 554          $token_class    = $token_data['token_class'];
 555          $access_token    = $token_data['accessToken'];
 556          $refresh_token    = $token_data['refreshToken'];
 557          $endOfLife        = $token_data['endOfLife'];
 558          $extra_params    = $token_data['extraParams'];
 559  
 560          // Create the token
 561          $token = new $token_class($access_token, $refresh_token, TokenInterface::EOL_NEVER_EXPIRES, $extra_params);
 562          $token->setEndOfLife($endOfLife);
 563  
 564          // Handle OAuth 1.0 specific elements
 565          if ($token instanceof StdOAuth1Token)
 566          {
 567              $token->setRequestToken($token_data['requestToken']);
 568              $token->setRequestTokenSecret($token_data['requestTokenSecret']);
 569              $token->setAccessTokenSecret($token_data['accessTokenSecret']);
 570          }
 571  
 572          return $token;
 573      }
 574  
 575      /**
 576      * Returns the name of the service as it must be stored in the database.
 577      *
 578      * @param    string    $service    The name of the OAuth service
 579      * @return    string    The name of the OAuth service as it needs to be stored
 580      *                    in the database.
 581      */
 582  	protected function get_service_name_for_db($service)
 583      {
 584          // Enforce the naming convention for oauth services
 585          if (strpos($service, 'auth.provider.oauth.service.') !== 0)
 586          {
 587              $service = 'auth.provider.oauth.service.' . strtolower($service);
 588          }
 589  
 590          return $service;
 591      }
 592  }


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