[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/lcobucci/jwt/src/ -> Builder.php (source)

   1  <?php
   2  /**
   3   * This file is part of Lcobucci\JWT, a simple library to handle JWT and JWS
   4   *
   5   * @license http://opensource.org/licenses/BSD-3-Clause BSD-3-Clause
   6   */
   7  
   8  namespace Lcobucci\JWT;
   9  
  10  use DateTimeImmutable;
  11  use Lcobucci\JWT\Claim\Factory as ClaimFactory;
  12  use Lcobucci\JWT\Parsing\Encoder;
  13  use Lcobucci\JWT\Signer\Key;
  14  use Lcobucci\JWT\Token\DataSet;
  15  use Lcobucci\JWT\Token\RegisteredClaimGiven;
  16  use Lcobucci\JWT\Token\RegisteredClaims;
  17  
  18  use function array_diff;
  19  use function array_filter;
  20  use function array_key_exists;
  21  use function array_merge;
  22  use function array_shift;
  23  use function count;
  24  use function current;
  25  use function in_array;
  26  use function is_array;
  27  use function is_bool;
  28  use function trigger_error;
  29  use const E_USER_DEPRECATED;
  30  
  31  /**
  32   * This class makes easier the token creation process
  33   *
  34   * @author Luís Otávio Cobucci Oblonczyk <[email protected]>
  35   * @since 0.1.0
  36   */
  37  class Builder
  38  {
  39      /**
  40       * The token header
  41       *
  42       * @var array
  43       */
  44      private $headers = ['typ'=> 'JWT', 'alg' => 'none'];
  45  
  46      /**
  47       * The token claim set
  48       *
  49       * @var array
  50       */
  51      private $claims = [];
  52  
  53      /**
  54       * The data encoder
  55       *
  56       * @var Encoder
  57       */
  58      private $encoder;
  59  
  60      /**
  61       * The factory of claims
  62       *
  63       * @var ClaimFactory
  64       */
  65      private $claimFactory;
  66  
  67      /**
  68       * @var Signer|null
  69       */
  70      private $signer;
  71  
  72      /**
  73       * @var Key|null
  74       */
  75      private $key;
  76  
  77      /**
  78       * Initializes a new builder
  79       *
  80       * @param Encoder $encoder
  81       * @param ClaimFactory $claimFactory
  82       */
  83      public function __construct(
  84          Encoder $encoder = null,
  85          ClaimFactory $claimFactory = null
  86      ) {
  87          $this->encoder = $encoder ?: new Encoder();
  88          $this->claimFactory = $claimFactory ?: new ClaimFactory();
  89      }
  90  
  91      /**
  92       * Configures the audience
  93       *
  94       * @deprecated This method has been wrongly added and doesn't exist on v4
  95       * @see Builder::permittedFor()
  96       *
  97       * @param string $audience
  98       * @param bool $replicateAsHeader
  99       *
 100       * @return Builder
 101       */
 102      public function canOnlyBeUsedBy($audience, $replicateAsHeader = false)
 103      {
 104          return $this->permittedFor($audience, $replicateAsHeader);
 105      }
 106  
 107      /**
 108       * Configures the audience
 109       *
 110       * @param list<string|bool> $audiences A list of audiences and, optionally, the instruction to replicate as header
 111       *
 112       * @return Builder
 113       */
 114      public function permittedFor(...$audiences)
 115      {
 116          $claim = RegisteredClaims::AUDIENCE;
 117  
 118          $replicateAsHeader = false;
 119  
 120          if ($audiences !== [] && is_bool($audiences[count($audiences) - 1])) {
 121              $replicateAsHeader = array_pop($audiences);
 122          }
 123  
 124          $audiences = array_filter($audiences, 'is_string');
 125  
 126          $configured = array_key_exists($claim, $this->claims) ? $this->claims[$claim] : [];
 127          $toAppend   = array_diff($audiences, $configured);
 128  
 129          return $this->setRegisteredClaim($claim, array_merge($configured, $toAppend), $replicateAsHeader);
 130      }
 131  
 132      /**
 133       * Configures the audience
 134       *
 135       * @deprecated This method will be removed on v4
 136       * @see Builder::permittedFor()
 137       *
 138       * @param string $audience
 139       * @param boolean $replicateAsHeader
 140       *
 141       * @return Builder
 142       */
 143      public function setAudience($audience, $replicateAsHeader = false)
 144      {
 145          return $this->permittedFor($audience, $replicateAsHeader);
 146      }
 147  
 148      /**
 149       * Configures the expiration time
 150       *
 151       * @param int|DateTimeImmutable $expiration
 152       * @param boolean $replicateAsHeader
 153       *
 154       * @return Builder
 155       */
 156      public function expiresAt($expiration, $replicateAsHeader = false)
 157      {
 158          return $this->setRegisteredClaim('exp', $this->convertToDate($expiration), $replicateAsHeader);
 159      }
 160  
 161      /**
 162       * @param int|DateTimeImmutable $value
 163       *
 164       * @return DateTimeImmutable
 165       */
 166      private function convertToDate($value)
 167      {
 168          if (! $value instanceof DateTimeImmutable) {
 169              trigger_error('Using integers for registered date claims is deprecated, please use DateTimeImmutable objects instead.', E_USER_DEPRECATED);
 170  
 171              return new DateTimeImmutable('@' . $value);
 172          }
 173  
 174          return $value;
 175      }
 176  
 177      /**
 178       * Configures the expiration time
 179       *
 180       * @deprecated This method will be removed on v4
 181       * @see Builder::expiresAt()
 182       *
 183       * @param int|DateTimeImmutable $expiration
 184       * @param boolean $replicateAsHeader
 185       *
 186       * @return Builder
 187       */
 188      public function setExpiration($expiration, $replicateAsHeader = false)
 189      {
 190          return $this->expiresAt($expiration, $replicateAsHeader);
 191      }
 192  
 193      /**
 194       * Configures the token id
 195       *
 196       * @param string $id
 197       * @param boolean $replicateAsHeader
 198       *
 199       * @return Builder
 200       */
 201      public function identifiedBy($id, $replicateAsHeader = false)
 202      {
 203          return $this->setRegisteredClaim('jti', (string) $id, $replicateAsHeader);
 204      }
 205  
 206      /**
 207       * Configures the token id
 208       *
 209       * @deprecated This method will be removed on v4
 210       * @see Builder::identifiedBy()
 211       *
 212       * @param string $id
 213       * @param boolean $replicateAsHeader
 214       *
 215       * @return Builder
 216       */
 217      public function setId($id, $replicateAsHeader = false)
 218      {
 219          return $this->identifiedBy($id, $replicateAsHeader);
 220      }
 221  
 222      /**
 223       * Configures the time that the token was issued
 224       *
 225       * @param int|DateTimeImmutable $issuedAt
 226       * @param boolean $replicateAsHeader
 227       *
 228       * @return Builder
 229       */
 230      public function issuedAt($issuedAt, $replicateAsHeader = false)
 231      {
 232          return $this->setRegisteredClaim('iat', $this->convertToDate($issuedAt), $replicateAsHeader);
 233      }
 234  
 235      /**
 236       * Configures the time that the token was issued
 237       *
 238       * @deprecated This method will be removed on v4
 239       * @see Builder::issuedAt()
 240       *
 241       * @param int|DateTimeImmutable $issuedAt
 242       * @param boolean $replicateAsHeader
 243       *
 244       * @return Builder
 245       */
 246      public function setIssuedAt($issuedAt, $replicateAsHeader = false)
 247      {
 248          return $this->issuedAt($issuedAt, $replicateAsHeader);
 249      }
 250  
 251      /**
 252       * Configures the issuer
 253       *
 254       * @param string $issuer
 255       * @param boolean $replicateAsHeader
 256       *
 257       * @return Builder
 258       */
 259      public function issuedBy($issuer, $replicateAsHeader = false)
 260      {
 261          return $this->setRegisteredClaim('iss', (string) $issuer, $replicateAsHeader);
 262      }
 263  
 264      /**
 265       * Configures the issuer
 266       *
 267       * @deprecated This method will be removed on v4
 268       * @see Builder::issuedBy()
 269       *
 270       * @param string $issuer
 271       * @param boolean $replicateAsHeader
 272       *
 273       * @return Builder
 274       */
 275      public function setIssuer($issuer, $replicateAsHeader = false)
 276      {
 277          return $this->issuedBy($issuer, $replicateAsHeader);
 278      }
 279  
 280      /**
 281       * Configures the time before which the token cannot be accepted
 282       *
 283       * @param int|DateTimeImmutable $notBefore
 284       * @param boolean $replicateAsHeader
 285       *
 286       * @return Builder
 287       */
 288      public function canOnlyBeUsedAfter($notBefore, $replicateAsHeader = false)
 289      {
 290          return $this->setRegisteredClaim('nbf', $this->convertToDate($notBefore), $replicateAsHeader);
 291      }
 292  
 293      /**
 294       * Configures the time before which the token cannot be accepted
 295       *
 296       * @deprecated This method will be removed on v4
 297       * @see Builder::canOnlyBeUsedAfter()
 298       *
 299       * @param int|DateTimeImmutable $notBefore
 300       * @param boolean $replicateAsHeader
 301       *
 302       * @return Builder
 303       */
 304      public function setNotBefore($notBefore, $replicateAsHeader = false)
 305      {
 306          return $this->canOnlyBeUsedAfter($notBefore, $replicateAsHeader);
 307      }
 308  
 309      /**
 310       * Configures the subject
 311       *
 312       * @param string $subject
 313       * @param boolean $replicateAsHeader
 314       *
 315       * @return Builder
 316       */
 317      public function relatedTo($subject, $replicateAsHeader = false)
 318      {
 319          return $this->setRegisteredClaim('sub', (string) $subject, $replicateAsHeader);
 320      }
 321  
 322      /**
 323       * Configures the subject
 324       *
 325       * @deprecated This method will be removed on v4
 326       * @see Builder::relatedTo()
 327       *
 328       * @param string $subject
 329       * @param boolean $replicateAsHeader
 330       *
 331       * @return Builder
 332       */
 333      public function setSubject($subject, $replicateAsHeader = false)
 334      {
 335          return $this->relatedTo($subject, $replicateAsHeader);
 336      }
 337  
 338      /**
 339       * Configures a registered claim
 340       *
 341       * @param string $name
 342       * @param mixed $value
 343       * @param boolean $replicate
 344       *
 345       * @return Builder
 346       */
 347      protected function setRegisteredClaim($name, $value, $replicate)
 348      {
 349          $this->configureClaim($name, $value);
 350  
 351          if ($replicate) {
 352              trigger_error('Replicating claims as headers is deprecated and will removed from v4.0. Please manually set the header if you need it replicated.', E_USER_DEPRECATED);
 353  
 354              $this->headers[$name] = $value;
 355          }
 356  
 357          return $this;
 358      }
 359  
 360      /**
 361       * Configures a header item
 362       *
 363       * @param string $name
 364       * @param mixed $value
 365       *
 366       * @return Builder
 367       */
 368      public function withHeader($name, $value)
 369      {
 370          $this->headers[(string) $name] = $value;
 371  
 372          return $this;
 373      }
 374  
 375      /**
 376       * Configures a header item
 377       *
 378       * @deprecated This method will be removed on v4
 379       * @see Builder::withHeader()
 380       *
 381       * @param string $name
 382       * @param mixed $value
 383       *
 384       * @return Builder
 385       */
 386      public function setHeader($name, $value)
 387      {
 388          return $this->withHeader($name, $value);
 389      }
 390  
 391      /**
 392       * Configures a claim item
 393       *
 394       * @deprecated This method has been wrongly added and doesn't exist on v4
 395       * @see Builder::withClaim()
 396       *
 397       * @param string $name
 398       * @param mixed $value
 399       *
 400       * @return Builder
 401       */
 402      public function with($name, $value)
 403      {
 404          return $this->withClaim($name, $value);
 405      }
 406  
 407      /**
 408       * @param string $name
 409       * @param mixed $value
 410       *
 411       * @return Builder
 412       */
 413      private function configureClaim($name, $value)
 414      {
 415          $this->claims[(string) $name] = $value;
 416  
 417          return $this;
 418      }
 419  
 420      /**
 421       * Configures a claim item
 422       *
 423       * @param string $name
 424       * @param mixed $value
 425       *
 426       * @return Builder
 427       *
 428       * @throws RegisteredClaimGiven
 429       */
 430      public function withClaim($name, $value)
 431      {
 432          if (in_array($name, RegisteredClaims::ALL, true)) {
 433              trigger_error('The use of the method "withClaim" is deprecated for registered claims. Please use dedicated method instead.', E_USER_DEPRECATED);
 434          }
 435  
 436          return $this->forwardCallToCorrectClaimMethod($name, $value);
 437      }
 438  
 439      private function forwardCallToCorrectClaimMethod($name, $value)
 440      {
 441          switch ($name) {
 442              case RegisteredClaims::ID:
 443                  return $this->identifiedBy($value);
 444              case RegisteredClaims::EXPIRATION_TIME:
 445                  return $this->expiresAt($value);
 446              case RegisteredClaims::NOT_BEFORE:
 447                  return $this->canOnlyBeUsedAfter($value);
 448              case RegisteredClaims::ISSUED_AT:
 449                  return $this->issuedAt($value);
 450              case RegisteredClaims::ISSUER:
 451                  return $this->issuedBy($value);
 452              case RegisteredClaims::AUDIENCE:
 453                  return $this->permittedFor($value);
 454              default:
 455                  return $this->configureClaim($name, $value);
 456          }
 457      }
 458  
 459      /**
 460       * Configures a claim item
 461       *
 462       * @deprecated This method will be removed on v4
 463       * @see Builder::withClaim()
 464       *
 465       * @param string $name
 466       * @param mixed $value
 467       *
 468       * @return Builder
 469       */
 470      public function set($name, $value)
 471      {
 472          return $this->forwardCallToCorrectClaimMethod($name, $value);
 473      }
 474  
 475      /**
 476       * Signs the data
 477       *
 478       * @deprecated This method will be removed on v4
 479       * @see Builder::getToken()
 480       *
 481       * @param Signer $signer
 482       * @param Key|string $key
 483       *
 484       * @return Builder
 485       */
 486      public function sign(Signer $signer, $key)
 487      {
 488          if (! $key instanceof Key) {
 489              trigger_error('Implicit conversion of keys from strings is deprecated. Please use InMemory or LocalFileReference classes.', E_USER_DEPRECATED);
 490  
 491              $key = new Key($key);
 492          }
 493  
 494          $this->signer = $signer;
 495          $this->key = $key;
 496  
 497          return $this;
 498      }
 499  
 500      /**
 501       * Removes the signature from the builder
 502       *
 503       * @deprecated This method will be removed on v4
 504       * @see Builder::getToken()
 505       *
 506       * @return Builder
 507       */
 508      public function unsign()
 509      {
 510          $this->signer = null;
 511          $this->key = null;
 512  
 513          return $this;
 514      }
 515  
 516      /**
 517       * Returns the resultant token
 518       *
 519       * @return Token
 520       */
 521      public function getToken(Signer $signer = null, Key $key = null)
 522      {
 523          if ($signer === null || $key === null) {
 524              trigger_error('Not specifying the signer and key to Builder#getToken() is deprecated. Please move the arguments from Builder#sign() to Builder#getToken().', E_USER_DEPRECATED);
 525          }
 526  
 527          $signer = $signer ?: $this->signer;
 528          $key = $key ?: $this->key;
 529  
 530          if ($signer instanceof Signer) {
 531              $signer->modifyHeader($this->headers);
 532          }
 533  
 534          $headers = new DataSet(
 535              $this->headers,
 536              $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->convertItems($this->headers)))
 537          );
 538  
 539          $claims = new DataSet(
 540              $this->claims,
 541              $this->encoder->base64UrlEncode($this->encoder->jsonEncode($this->convertItems($this->claims)))
 542          );
 543  
 544          return new Token(
 545              $headers,
 546              $claims,
 547              $this->createSignature($headers->toString() . '.' . $claims->toString(), $signer, $key),
 548              ['', ''],
 549              $this->claimFactory
 550          );
 551      }
 552  
 553      /**
 554       * @param array<string, mixed> $items
 555       *
 556       * @return array<string, mixed>
 557       */
 558      private function convertItems(array $items)
 559      {
 560          foreach (RegisteredClaims::DATE_CLAIMS as $name) {
 561              if (! array_key_exists($name, $items) || ! $items[$name] instanceof DateTimeImmutable) {
 562                  continue;
 563              }
 564  
 565              $items[$name] = $items[$name]->getTimestamp();
 566          }
 567  
 568          $audience = RegisteredClaims::AUDIENCE;
 569  
 570          if (array_key_exists($audience, $items) && is_array($items[$audience]) && count($items[$audience]) === 1) {
 571              $items[$audience] = current($items[$audience]);
 572          }
 573  
 574          return $items;
 575      }
 576  
 577      /**
 578       * @param string $payload
 579       *
 580       * @return Signature
 581       */
 582      private function createSignature($payload, Signer $signer = null, Key $key = null)
 583      {
 584          if ($signer === null || $key === null) {
 585              return Signature::fromEmptyData();
 586          }
 587  
 588          $hash = $signer->sign($payload, $key)->hash();
 589  
 590          return new Signature($hash, $this->encoder->base64UrlEncode($hash));
 591      }
 592  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer