Skip to content

Commit

Permalink
Move security requirements to a dedicated attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
Starfox64 authored Jan 22, 2025
1 parent 2856adf commit 32fdf79
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 31 deletions.
22 changes: 1 addition & 21 deletions src/Attributes/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,22 @@ class Operation
/** @var array<string> */
public array $tags;

public ?string $security;

public ?string $method;

public ?array $servers;

/**
* @param string|null $id
* @param array $tags
* @param \Vyuldashev\LaravelOpenApi\Factories\SecuritySchemeFactory|string|null $security
* @param string|null $method
*
* @throws InvalidArgumentException
*/
public function __construct(string $id = null, array $tags = [], string $security = null, string $method = null, array $servers = null)
public function __construct(string $id = null, array $tags = [], string $method = null, array $servers = null)
{
$this->id = $id;
$this->tags = $tags;
$this->method = $method;
$this->servers = $servers;

if ($security === '') {
//user wants to turn off security on this operation
$this->security = $security;

return;
}

if ($security) {
$this->security = class_exists($security) ? $security : app()->getNamespace().'OpenApi\\SecuritySchemes\\'.$security;

if (! is_a($this->security, SecuritySchemeFactory::class, true)) {
throw new InvalidArgumentException(
sprintf('Security class is either not declared or is not an instance of %s', SecuritySchemeFactory::class)
);
}
}
}
}
38 changes: 38 additions & 0 deletions src/Attributes/SecurityRequirement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Vyuldashev\LaravelOpenApi\Attributes;

use Attribute;
use InvalidArgumentException;
use Vyuldashev\LaravelOpenApi\Factories\SecuritySchemeFactory;

#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
class SecurityRequirement
{
public ?string $scheme;

/** @var array<string> */
public ?array $scopes;

/**
* @param string|null $scheme
* @param array $scopes
*
* @throws InvalidArgumentException
*/
public function __construct(string|null $scheme, array $scopes = [])
{
if ($scheme) {
$factory = class_exists($scheme) ? $scheme : app()->getNamespace().'OpenApi\\SecuritySchemes\\'.$scheme;

if (! is_a($factory, SecuritySchemeFactory::class, true)) {
throw new InvalidArgumentException(
sprintf('Security class is either not declared or is not an instance of %s', SecuritySchemeFactory::class)
);
}
}

$this->scheme = $scheme;
$this->scopes = $scopes;
}
}
24 changes: 14 additions & 10 deletions src/Builders/Paths/Operation/SecurityBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,31 @@
namespace Vyuldashev\LaravelOpenApi\Builders\Paths\Operation;

use GoldSpecDigital\ObjectOrientedOAS\Objects\SecurityRequirement;
use Vyuldashev\LaravelOpenApi\Attributes\Operation as OperationAttribute;
use Vyuldashev\LaravelOpenApi\Attributes\SecurityRequirement as SecurityRequirementAttribute;
use Vyuldashev\LaravelOpenApi\RouteInformation;

class SecurityBuilder
{
public function build(RouteInformation $route): array
{
return $route->actionAttributes
->filter(static fn (object $attribute) => $attribute instanceof OperationAttribute)
->filter(static fn (OperationAttribute $attribute) => isset($attribute->security))
->map(static function (OperationAttribute $attribute) {
// return a null scheme if the security is set to ''
if ($attribute->security === '') {
->filter(static fn (object $attribute) => $attribute instanceof SecurityRequirementAttribute)
->map(static function (SecurityRequirementAttribute $attribute) {
if (!$attribute->scheme) {
return SecurityRequirement::create()->securityScheme(null);
}
$security = app($attribute->security);
$scheme = $security->build();
$factory = app($attribute->scheme);
$scheme = $factory->build();

return SecurityRequirement::create()->securityScheme($scheme);
$requirement = SecurityRequirement::create()->securityScheme($scheme);

if ($attribute->scopes) {
$requirement = $requirement->scopes(...$attribute->scopes);
}

return $requirement;
})
->values()
->toArray();
}
}
}

0 comments on commit 32fdf79

Please sign in to comment.