Skip to content

Commit 3d6ea16

Browse files
authored
Merge pull request #104 from DoclerLabs/add-support-for-api-key-security
add support for api key security and X-WSSE
2 parents e663eaf + 03126d0 commit 3d6ea16

33 files changed

+1159
-142
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [10.6.0] - 2024.01.10
8+
### Added
9+
- Api key authentication strategy added
10+
- X-WSSE authentication strategy added
11+
712
## [10.5.0] - 2023.12.22
813
### Added
914
- `oneOf` schema support

composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"psr/http-message": "^1.0",
3232
"symfony/console": "^5.1",
3333
"symfony/yaml": "^5.1",
34-
"twig/twig": "^3.0"
34+
"twig/twig": "^3.0",
35+
"webmozart/assert": "^1.11"
3536
},
3637
"require-dev": {
3738
"composer/composer": "^2.1",

composer.lock

+59-59
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/PetStoreApiConsumer/PetStoreApiConsumer.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ public function findPetsByStatus(): Pet
3535
return $result->first();
3636
}
3737

38-
public function getPetById(int $petId): Pet
38+
public function getPetById(int $petId, string $apiKey): Pet
3939
{
40-
$request = new GetPetByIdRequest($petId);
40+
$request = new GetPetByIdRequest($petId, $apiKey);
4141
$result = $this->petClient->getPetById($request);
4242
if ($result === null) {
4343
throw new UnexpectedValueException('getPetById should not be null');

example/PetStoreClient/src/Request/GetInventoryRequest.php

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ class GetInventoryRequest implements RequestInterface
1414
{
1515
private string $contentType = '';
1616

17+
private string $apiKey;
18+
19+
public function __construct(string $apiKey)
20+
{
21+
$this->apiKey = $apiKey;
22+
}
23+
1724
public function getContentType(): string
1825
{
1926
return $this->contentType;
@@ -46,7 +53,7 @@ public function getCookies(): array
4653

4754
public function getHeaders(): array
4855
{
49-
return [];
56+
return ['api_key' => $this->apiKey];
5057
}
5158

5259
public function getBody()

example/PetStoreClient/src/Request/GetPetByIdRequest.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@ class GetPetByIdRequest implements RequestInterface
1616

1717
private string $contentType = '';
1818

19-
public function __construct(int $petId)
19+
private string $apiKey;
20+
21+
public function __construct(int $petId, string $apiKey)
2022
{
21-
$this->petId = $petId;
23+
$this->petId = $petId;
24+
$this->apiKey = $apiKey;
2225
}
2326

2427
public function getContentType(): string
@@ -53,7 +56,7 @@ public function getCookies(): array
5356

5457
public function getHeaders(): array
5558
{
56-
return [];
59+
return ['api_key' => $this->apiKey];
5760
}
5861

5962
public function getBody()

example/test-example.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
$firstPet = $consumer->findPetsByStatus();
1717

1818
$mock->mockGetPetById();
19-
$pet = $consumer->getPetById($firstPet->getId());
19+
$pet = $consumer->getPetById($firstPet->getId(), 'some-api-key');
2020

2121
$mock->mockUpdatePet();
2222
$consumer->updatePet($pet, XmlContentTypeSerializer::MIME_TYPE);

src/Generator/RequestGenerator.php

+63-21
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use DoclerLabs\ApiClientGenerator\Entity\Field;
1212
use DoclerLabs\ApiClientGenerator\Entity\Operation;
1313
use DoclerLabs\ApiClientGenerator\Entity\Request;
14-
use DoclerLabs\ApiClientGenerator\Generator\Security\SecurityStrategyAbstract;
14+
use DoclerLabs\ApiClientGenerator\Generator\Security\SecurityStrategyInterface;
1515
use DoclerLabs\ApiClientGenerator\Input\InvalidSpecificationException;
1616
use DoclerLabs\ApiClientGenerator\Input\Specification;
1717
use DoclerLabs\ApiClientGenerator\Naming\CopiedNamespace;
@@ -27,14 +27,14 @@ class RequestGenerator extends MutatorAccessorClassGeneratorAbstract
2727

2828
public const SUBDIRECTORY = 'Request/';
2929

30-
/** @var SecurityStrategyAbstract[] */
30+
/** @var SecurityStrategyInterface[] */
3131
private array $securityStrategies;
3232

3333
public function __construct(
3434
string $baseNamespace,
3535
CodeBuilder $builder,
3636
PhpVersion $phpVersion,
37-
SecurityStrategyAbstract ...$securityStrategies
37+
SecurityStrategyInterface ...$securityStrategies
3838
) {
3939
parent::__construct($baseNamespace, $builder, $phpVersion);
4040

@@ -292,27 +292,22 @@ private function generateGetParametersMethods(
292292
Operation $operation,
293293
Specification $specification
294294
): array {
295-
$methods = [];
296-
$fields = $request->fields;
297-
$methods[] = $this->generateGetParametersMethod(
298-
'getQueryParameters',
299-
$fields->getQueryFields()
300-
);
301-
$methods[] = $this->generateGetRawParametersMethod(
302-
'getRawQueryParameters',
303-
$fields->getQueryFields()
304-
);
305-
$methods[] = $this->generateGetParametersMethod(
306-
'getCookies',
307-
$fields->getCookieFields()
308-
);
295+
$methods = [];
296+
$fields = $request->fields;
297+
298+
$securityQueryFields = $this->getSecurityQueryParameters($operation, $specification);
299+
$securityCookies = $this->getSecurityCookies($operation, $specification);
300+
301+
$methods[] = $this->generateGetParametersMethod('getQueryParameters', $fields->getQueryFields(), $securityQueryFields);
302+
$methods[] = $this->generateGetRawParametersMethod('getRawQueryParameters', $fields->getQueryFields(), $securityQueryFields);
303+
$methods[] = $this->generateGetParametersMethod('getCookies', $fields->getCookieFields(), $securityCookies);
309304
$methods[] = $this->generateGetHeadersMethod($request, $fields->getHeaderFields(), $operation, $specification);
310305
$methods[] = $this->generateGetBody($fields->getBody());
311306

312307
return $methods;
313308
}
314309

315-
private function generateGetParametersMethod(string $methodName, array $fields): ClassMethod
310+
private function generateGetParametersMethod(string $methodName, array $fields, array $securityFields): ClassMethod
316311
{
317312
$returnVal = $this->builder->array([]);
318313
$fieldsArr = [];
@@ -322,7 +317,19 @@ private function generateGetParametersMethod(string $methodName, array $fields):
322317
}
323318

324319
if (!empty($fieldsArr)) {
325-
$returnVal = $this->generateParametersFromFields($fieldsArr);
320+
if (empty($securityFields)) {
321+
$returnVal = $this->generateParametersFromFields($fieldsArr);
322+
} else {
323+
$returnVal = $this->builder->funcCall(
324+
'array_merge',
325+
[
326+
$this->generateParametersFromFields($fieldsArr),
327+
$securityFields,
328+
]
329+
);
330+
}
331+
} else {
332+
$returnVal = $this->builder->array($securityFields);
326333
}
327334

328335
return $this
@@ -335,7 +342,7 @@ private function generateGetParametersMethod(string $methodName, array $fields):
335342
->getNode();
336343
}
337344

338-
private function generateGetRawParametersMethod(string $methodName, array $fields): ClassMethod
345+
private function generateGetRawParametersMethod(string $methodName, array $fields, array $securityFields): ClassMethod
339346
{
340347
$fieldsArr = [];
341348
$returnType = 'array';
@@ -347,7 +354,7 @@ private function generateGetRawParametersMethod(string $methodName, array $field
347354
->builder
348355
->method($methodName)
349356
->makePublic()
350-
->addStmt($this->builder->return($this->builder->array($fieldsArr)))
357+
->addStmt($this->builder->return($this->builder->array(array_merge($fieldsArr, $securityFields))))
351358
->setReturnType($returnType)
352359
->composeDocBlock([], $returnType)
353360
->getNode();
@@ -381,6 +388,7 @@ private function generateGetHeadersMethod(
381388
Operation $operation,
382389
Specification $specification
383390
): ClassMethod {
391+
$stmts = $this->getSecurityHeadersStmts($operation, $specification);
384392
$headers = $this->getSecurityHeaders($operation, $specification);
385393
if (!empty($request->bodyContentTypes)) {
386394
$headers['Content-Type'] = $this->builder->localPropertyFetch('contentType');
@@ -403,12 +411,24 @@ private function generateGetHeadersMethod(
403411
->builder
404412
->method('getHeaders')
405413
->makePublic()
414+
->addStmts($stmts)
406415
->addStmt($this->builder->return($returnVal))
407416
->setReturnType($returnType)
408417
->composeDocBlock([], $returnType)
409418
->getNode();
410419
}
411420

421+
private function getSecurityHeadersStmts(Operation $operation, Specification $specification): array
422+
{
423+
$stmts = [];
424+
425+
foreach ($this->securityStrategies as $securityStrategy) {
426+
$stmts = array_merge($stmts, $securityStrategy->getSecurityHeadersStmts($operation, $specification));
427+
}
428+
429+
return $stmts;
430+
}
431+
412432
private function getSecurityHeaders(Operation $operation, Specification $specification): array
413433
{
414434
$headers = [];
@@ -420,6 +440,28 @@ private function getSecurityHeaders(Operation $operation, Specification $specifi
420440
return $headers;
421441
}
422442

443+
private function getSecurityCookies(Operation $operation, Specification $specification): array
444+
{
445+
$cookies = [];
446+
447+
foreach ($this->securityStrategies as $securityStrategy) {
448+
$cookies += $securityStrategy->getSecurityCookies($operation, $specification);
449+
}
450+
451+
return $cookies;
452+
}
453+
454+
private function getSecurityQueryParameters(Operation $operation, Specification $specification): array
455+
{
456+
$queryParameters = [];
457+
458+
foreach ($this->securityStrategies as $securityStrategy) {
459+
$queryParameters += $securityStrategy->getSecurityQueryParameters($operation, $specification);
460+
}
461+
462+
return $queryParameters;
463+
}
464+
423465
private function generateParametersFromFields(array $fields): FuncCall
424466
{
425467
$filterCallbackBody = $this->builder->return(

0 commit comments

Comments
 (0)