Skip to content

Commit 84e9aca

Browse files
committed
feat[internal-api-php-client]: Unify JobObjectEncryptor with the one in docker-bundle
1 parent 76d759d commit 84e9aca

File tree

3 files changed

+78
-28
lines changed

3 files changed

+78
-28
lines changed

src/JobFactory/JobObjectEncryptor.php

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,40 @@
44

55
namespace Keboola\JobQueueInternalClient\JobFactory;
66

7+
use InvalidArgumentException;
78
use Keboola\ObjectEncryptor\ObjectEncryptor;
89
use Keboola\PermissionChecker\BranchType;
910
use stdClass;
1011

1112
class JobObjectEncryptor
1213
{
13-
private ObjectEncryptor $objectEncryptor;
14+
private const PROTECTED_DEFAULT_BRANCH_FEATURE = 'protected-default-branch';
1415

15-
public function __construct(ObjectEncryptor $objectEncryptor)
16-
{
17-
$this->objectEncryptor = $objectEncryptor;
16+
public function __construct(
17+
private readonly ObjectEncryptor $objectEncryptor,
18+
) {
1819
}
1920

2021
/**
2122
* @template T of string|array|stdClass
2223
* @param T $data
2324
* @return T
2425
*/
25-
public function encrypt($data, string $componentId, string $projectId, ?BranchType $branchType)
26-
{
27-
if ($branchType !== null) {
26+
public function encrypt(
27+
string|array|stdClass $data,
28+
string $componentId,
29+
string $projectId,
30+
?BranchType $branchType,
31+
array $projectFeatures,
32+
): string|array|stdClass {
33+
$hasProtectedDefaultBranch = in_array(self::PROTECTED_DEFAULT_BRANCH_FEATURE, $projectFeatures, true);
34+
if ($hasProtectedDefaultBranch && $branchType === null) {
35+
throw new InvalidArgumentException(
36+
'Protected default branch feature is enabled, but branch type is not set.',
37+
);
38+
}
39+
40+
if ($hasProtectedDefaultBranch) {
2841
return $this->objectEncryptor->encryptForBranchType(
2942
$data,
3043
$componentId,
@@ -45,8 +58,13 @@ public function encrypt($data, string $componentId, string $projectId, ?BranchTy
4558
* @param T $data
4659
* @return T
4760
*/
48-
public function decrypt($data, string $componentId, string $projectId, ?string $configId, BranchType $branchType)
49-
{
61+
public function decrypt(
62+
string|array|stdClass $data,
63+
string $componentId,
64+
string $projectId,
65+
?string $configId,
66+
BranchType $branchType,
67+
): string|array|stdClass {
5068
/* When configId is null, the decryptForBranchType has to be used, because configId is required parameter.
5169
This is what drives the logic here, not the contents of the cipher! The contents of any cipher can be
5270
decrypted with decryptForBranchTypeConfiguration which encapsulates all wrappers that might come in use

src/NewJobFactory.php

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,13 @@ public function createNewJob(array $data): JobInterface
9191
];
9292
$jobData = $this->jobRuntimeResolver->resolveJobData($jobData, $tokenInfo);
9393

94-
if (in_array(self::PROTECTED_DEFAULT_BRANCH_FEATURE, $tokenInfo['owner']['features'])) {
95-
$data = $this->objectEncryptor->encrypt(
96-
$jobData,
97-
(string) $data['componentId'],
98-
(string) $tokenInfo['owner']['id'],
99-
BranchType::from($jobData['branchType']),
100-
);
101-
} else {
102-
$data = $this->objectEncryptor->encrypt(
103-
$jobData,
104-
(string) $data['componentId'],
105-
(string) $tokenInfo['owner']['id'],
106-
null,
107-
);
108-
}
94+
$data = $this->objectEncryptor->encrypt(
95+
$jobData,
96+
(string) $data['componentId'],
97+
(string) $tokenInfo['owner']['id'],
98+
BranchType::from($jobData['branchType']),
99+
$tokenInfo['owner']['features'],
100+
);
109101

110102
$data = $this->validateJobData($data, FullJobDefinition::class);
111103
return new Job($this->objectEncryptor, $this->storageClientFactory, $data);

tests/ObjectEncryptor/JobObjectEncryptorTest.php

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@
44

55
namespace Keboola\JobQueueInternalClient\Tests\ObjectEncryptor;
66

7+
use InvalidArgumentException;
78
use Keboola\JobQueueInternalClient\JobFactory\JobObjectEncryptor;
89
use Keboola\ObjectEncryptor\ObjectEncryptor;
910
use Keboola\PermissionChecker\BranchType;
1011
use PHPUnit\Framework\TestCase;
1112

1213
class JobObjectEncryptorTest extends TestCase
1314
{
14-
public function testEncryptWithoutBranch(): void
15+
public function testEncryptWithoutBranchAndNoProtectedFeature(): void
1516
{
1617
$internalEncryptor = $this->createMock(ObjectEncryptor::class);
1718
$internalEncryptor->expects(self::once())
@@ -21,12 +22,45 @@ public function testEncryptWithoutBranch(): void
2122
;
2223

2324
$encryptor = new JobObjectEncryptor($internalEncryptor);
24-
$result = $encryptor->encrypt('data', 'componentId', 'projectId', null);
25+
$result = $encryptor->encrypt('data', 'componentId', 'projectId', null, []);
2526

2627
self::assertSame('encryptedData', $result);
2728
}
2829

29-
public function testEncryptWithBranch(): void
30+
public function testEncryptWithBranchAndNoProtectedFeature(): void
31+
{
32+
$internalEncryptor = $this->createMock(ObjectEncryptor::class);
33+
$internalEncryptor->expects(self::once())
34+
->method('encryptForProject')
35+
->with('data', 'componentId', 'projectId')
36+
->willReturn('encryptedData')
37+
;
38+
39+
$encryptor = new JobObjectEncryptor($internalEncryptor);
40+
$result = $encryptor->encrypt('data', 'componentId', 'projectId', BranchType::DEFAULT, []);
41+
42+
self::assertSame('encryptedData', $result);
43+
}
44+
45+
public function testEncryptWithProtectedDefaultBranchFeatureAndNoBranch(): void
46+
{
47+
$internalEncryptor = $this->createMock(ObjectEncryptor::class);
48+
$internalEncryptor->expects(self::never())
49+
->method('encryptForProject')
50+
;
51+
$internalEncryptor->expects(self::never())
52+
->method('encryptForBranchType')
53+
;
54+
55+
$encryptor = new JobObjectEncryptor($internalEncryptor);
56+
57+
$this->expectException(InvalidArgumentException::class);
58+
$this->expectExceptionMessage('Protected default branch feature is enabled, but branch type is not set.');
59+
60+
$encryptor->encrypt('data', 'componentId', 'projectId', null, ['protected-default-branch']);
61+
}
62+
63+
public function testEncryptWithProtectedDefaultBranchFeatureAndBranch(): void
3064
{
3165
$internalEncryptor = $this->createMock(ObjectEncryptor::class);
3266
$internalEncryptor->expects(self::once())
@@ -36,7 +70,13 @@ public function testEncryptWithBranch(): void
3670
;
3771

3872
$encryptor = new JobObjectEncryptor($internalEncryptor);
39-
$result = $encryptor->encrypt('data', 'componentId', 'projectId', BranchType::DEFAULT);
73+
$result = $encryptor->encrypt(
74+
'data',
75+
'componentId',
76+
'projectId',
77+
BranchType::DEFAULT,
78+
['protected-default-branch'],
79+
);
4080

4181
self::assertSame('encryptedData', $result);
4282
}

0 commit comments

Comments
 (0)