Skip to content

Commit

Permalink
Add migration API for readonly classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Slamdunk committed Dec 5, 2024
1 parent 1b7c00a commit 59b291f
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 30 deletions.
8 changes: 4 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ $configuration = Configuration::forSymmetricSigner(
InMemory::base64Encoded('mBC5v1sOKVvbdEitdSBenu59nfNfhwkedkJVNabosTw=')
);

$configuration->setBuilderFactory(
$configuration = $configuration->withBuilderFactory(
static function (ClaimsFormatter $formatter): Builder {
// This assumes `MyCustomBuilder` is an existing class
return new MyCustomBuilder(new JoseEncoder(), $formatter);
Expand Down Expand Up @@ -165,7 +165,7 @@ $configuration = Configuration::forSymmetricSigner(
);

// This assumes `MyParser` is an existing class
$configuration->setParser(new MyParser());
$configuration = $configuration->withParser(new MyParser());
```

### Validator
Expand All @@ -189,7 +189,7 @@ $configuration = Configuration::forSymmetricSigner(
);

// This assumes `MyValidator` is an existing class
$configuration->setValidator(new MyValidator());
$configuration = $configuration->withValidator(new MyValidator());
```

### Validation constraints
Expand All @@ -216,7 +216,7 @@ $configuration = Configuration::forSymmetricSigner(
InMemory::base64Encoded('mBC5v1sOKVvbdEitdSBenu59nfNfhwkedkJVNabosTw=')
);

$configuration->setValidationConstraints(
$configuration = $configuration->withValidationConstraints(
new SignedWith($configuration->signer(), $configuration->signingKey()),
new StrictValidAt(SystemClock::fromUTC()),
new IssuedBy('https://api.my-awesome-company.com')
Expand Down
6 changes: 3 additions & 3 deletions docs/extending-the-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use Lcobucci\JWT\Configuration;
$config = $container->get(Configuration::class);
assert($config instanceof Configuration);

$config->setBuilderFactory(
$configuration = $configuration->withBuilderFactory(
static function (ClaimsFormatter $formatter): Builder {
return new MyCustomTokenBuilder($formatter);
}
Expand Down Expand Up @@ -99,7 +99,7 @@ use Lcobucci\JWT\Configuration;
$config = $container->get(Configuration::class);
assert($config instanceof Configuration);

$config->setParser(new MyCustomTokenParser());
$configuration = $configuration->withParser(new MyCustomTokenParser());
```

## Signer
Expand Down Expand Up @@ -157,7 +157,7 @@ use Lcobucci\JWT\Configuration;
$config = $container->get(Configuration::class);
assert($config instanceof Configuration);

$config->setValidator(new MyCustomTokenValidator());
$configuration = $configuration->withValidator(new MyCustomTokenValidator());
```

## Validation constraints
Expand Down
4 changes: 2 additions & 2 deletions docs/issuing-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use Lcobucci\JWT\Token\Builder;

require 'vendor/autoload.php';

$tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
$tokenBuilder = Builder::new(new JoseEncoder(), ChainedFormatter::default());
$algorithm = new Sha256();
$signingKey = InMemory::plainText(random_bytes(32));

Expand Down Expand Up @@ -58,7 +58,7 @@ use Lcobucci\JWT\Token\Builder;

require 'vendor/autoload.php';

$tokenBuilder = (new Builder(new JoseEncoder(), ChainedFormatter::default()));
$tokenBuilder = Builder::new(new JoseEncoder(), ChainedFormatter::default());
$algorithm = new Sha256();
$signingKey = InMemory::plainText(random_bytes(32));

Expand Down
100 changes: 91 additions & 9 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,29 @@ final class Configuration
private Closure $builderFactory;

/** @var Constraint[] */
private array $validationConstraints = [];
private array $validationConstraints;

/** @param Closure(ClaimsFormatter $claimFormatter): Builder|null $builderFactory */
private function __construct(
private readonly Signer $signer,
private readonly Key $signingKey,
private readonly Key $verificationKey,
Encoder $encoder,
Decoder $decoder,
private readonly Encoder $encoder,
private readonly Decoder $decoder,
?Parser $parser,
?Validator $validator,
?Closure $builderFactory,
Constraint ...$validationConstraints,
) {
$this->parser = new Token\Parser($decoder);
$this->validator = new Validation\Validator();
$this->parser = $parser ?? new Token\Parser($decoder);
$this->validator = $validator ?? new Validation\Validator();

$this->builderFactory = static function (ClaimsFormatter $claimFormatter) use ($encoder): Builder {
return new Token\Builder($encoder, $claimFormatter);
};
$this->builderFactory = $builderFactory
?? static function (ClaimsFormatter $claimFormatter) use ($encoder): Builder {
return Token\Builder::new($encoder, $claimFormatter);
};

$this->validationConstraints = $validationConstraints;
}

public static function forAsymmetricSigner(
Expand All @@ -54,6 +62,9 @@ public static function forAsymmetricSigner(
$verificationKey,
$encoder,
$decoder,
null,
null,
null,
);
}

Expand All @@ -69,15 +80,38 @@ public static function forSymmetricSigner(
$key,
$encoder,
$decoder,
null,
null,
null,
);
}

/** @param callable(ClaimsFormatter): Builder $builderFactory */
/**
* @deprecated Deprecated since v5.5, please use {@see self::withBuilderFactory()} instead
*
* @param callable(ClaimsFormatter): Builder $builderFactory
*/
public function setBuilderFactory(callable $builderFactory): void
{
$this->builderFactory = $builderFactory(...);
}

/** @param callable(ClaimsFormatter): Builder $builderFactory */
public function withBuilderFactory(callable $builderFactory): self
{
return new self(
$this->signer,
$this->signingKey,
$this->verificationKey,
$this->encoder,
$this->decoder,
$this->parser,
$this->validator,
$builderFactory(...),
...$this->validationConstraints,
);
}

public function builder(?ClaimsFormatter $claimFormatter = null): Builder
{
return ($this->builderFactory)($claimFormatter ?? ChainedFormatter::default());
Expand All @@ -88,11 +122,27 @@ public function parser(): Parser
return $this->parser;
}

/** @deprecated Deprecated since v5.5, please use {@see self::withParser()} instead */
public function setParser(Parser $parser): void
{
$this->parser = $parser;
}

public function withParser(Parser $parser): self
{
return new self(
$this->signer,
$this->signingKey,
$this->verificationKey,
$this->encoder,
$this->decoder,
$parser,
$this->validator,
$this->builderFactory,
...$this->validationConstraints,
);
}

public function signer(): Signer
{
return $this->signer;
Expand All @@ -113,19 +163,51 @@ public function validator(): Validator
return $this->validator;
}

/** @deprecated Deprecated since v5.5, please use {@see self::withValidator()} instead */
public function setValidator(Validator $validator): void
{
$this->validator = $validator;
}

public function withValidator(Validator $validator): self
{
return new self(
$this->signer,
$this->signingKey,
$this->verificationKey,
$this->encoder,
$this->decoder,
$this->parser,
$validator,
$this->builderFactory,
...$this->validationConstraints,
);
}

/** @return Constraint[] */
public function validationConstraints(): array
{
return $this->validationConstraints;
}

/** @deprecated Deprecated since v5.5, please use {@see self::withValidationConstraints()} instead */
public function setValidationConstraints(Constraint ...$validationConstraints): void
{
$this->validationConstraints = $validationConstraints;
}

public function withValidationConstraints(Constraint ...$validationConstraints): self
{
return new self(
$this->signer,
$this->signingKey,
$this->verificationKey,
$this->encoder,
$this->decoder,
$this->parser,
$this->validator,
$this->builderFactory,
...$validationConstraints,
);
}
}
2 changes: 1 addition & 1 deletion src/JwtFacade.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function issue(
Key $signingKey,
Closure $customiseBuilder,
): UnencryptedToken {
$builder = new Token\Builder(new JoseEncoder(), ChainedFormatter::withUnixTimestampDates());
$builder = Token\Builder::new(new JoseEncoder(), ChainedFormatter::withUnixTimestampDates());

$now = $this->clock->now();
$builder = $builder
Expand Down
6 changes: 6 additions & 0 deletions src/Token/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ final class Builder implements BuilderInterface
/** @var array<non-empty-string, mixed> */
private array $claims = [];

/** @deprecated Deprecated since v5.5, please use {@see self::new()} instead */
public function __construct(private readonly Encoder $encoder, private readonly ClaimsFormatter $claimFormatter)
{
}

public static function new(Encoder $encoder, ClaimsFormatter $claimFormatter): self
{
return new self($encoder, $claimFormatter);
}

/**
* @inheritDoc
* @pure
Expand Down
Loading

0 comments on commit 59b291f

Please sign in to comment.