Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

diff: https://github.com/transloadit/php-sdk/compare/3.3.0...main

- Default Assembly signatures to `sha384` and include the algorithm prefix (`sha384:...`)
- Add request/client-level `signatureAlgorithm` configuration for legacy `sha1` compatibility
- Extend tests to cover default `sha384` signing, legacy override, and Node CLI parity

## [3.3.0](https://github.com/transloadit/php-sdk/tree/3.3.0)

- Replace the custom Node parity helper with the official `transloadit` CLI for Smart CDN signatures
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,12 @@ The auth key of your Transloadit account.

The auth secret of your Transloadit account.

#### $Transloadit->signatureAlgorithm = 'sha384';

Controls which HMAC algorithm is used for Assembly request signing.
The default is `'sha384'` (recommended). If you need compatibility with a legacy key,
you can set this to `'sha1'`.

#### $Transloadit->request($options = [], $execute = true);

Creates a new `TransloaditRequest` using the `$Transloadit->key` and
Expand Down Expand Up @@ -444,6 +450,12 @@ The auth key of your Transloadit account.

The auth secret of your Transloadit account.

#### $TransloaditRequest->signatureAlgorithm = 'sha384';

Controls which HMAC algorithm is used when preparing the Assembly request signature.
The generated `signature` field uses the `<algorithm>:<digest>` format, for example:
`sha384:...`.

#### $TransloaditRequest->method = 'GET';

Inherited from `CurlRequest`. Can be used to set the type of request to be
Expand Down
2 changes: 2 additions & 0 deletions lib/transloadit/Transloadit.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class Transloadit {
public $key = null;
public $secret = null;
public $signatureAlgorithm = 'sha384';
public $endpoint = 'https://api2.transloadit.com';

public function __construct($attributes = []) {
Expand All @@ -17,6 +18,7 @@ public function request($options = [], $execute = true) {
$options = $options + [
'key' => $this->key,
'secret' => $this->secret,
'signatureAlgorithm' => $this->signatureAlgorithm,
'endpoint' => $this->endpoint,
'waitForCompletion' => false,
];
Expand Down
20 changes: 18 additions & 2 deletions lib/transloadit/TransloaditRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class TransloaditRequest extends CurlRequest {

public $params = [];
public $expires = '+2 hours';
public $signatureAlgorithm = 'sha384';

public $headers = [
'Expect:',
Expand Down Expand Up @@ -42,12 +43,27 @@ public function getParamsString() {
return json_encode($params);
}

public function signString($string) {
public function signString($string, $algorithm = null) {
if (empty($this->secret)) {
return null;
}

return hash_hmac('sha1', $string, $this->secret);
$effectiveAlgorithm = strtolower((string) ($algorithm ?? $this->signatureAlgorithm ?? 'sha384'));
if ($effectiveAlgorithm === '') {
$effectiveAlgorithm = 'sha384';
}

try {
$signature = hash_hmac($effectiveAlgorithm, $string, $this->secret);
} catch (\ValueError $e) {
throw new \InvalidArgumentException('Unsupported signature algorithm: ' . $effectiveAlgorithm, 0, $e);
}

if ($signature === false) {
throw new \InvalidArgumentException('Unsupported signature algorithm: ' . $effectiveAlgorithm);
}

return $effectiveAlgorithm . ':' . $signature;
}

public function prepare() {
Expand Down
27 changes: 22 additions & 5 deletions test/simple/TransloaditRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function testAttributes() {
$this->assertEquals($this->request->secret, null);
$this->assertEquals($this->request->params, []);
$this->assertEquals($this->request->expires, '+2 hours');
$this->assertEquals($this->request->signatureAlgorithm, 'sha384');
$this->assertEquals('Expect:', $this->request->headers[0]);
$this->assertContains('Transloadit-Client: php-sdk:%s', $this->request->headers);
}
Expand Down Expand Up @@ -99,13 +100,28 @@ public function testSignString() {
// No secret, no signature
$this->assertEquals(null, $this->request->signString('foo'));

// Verify the test vector given in the documentation, see: http://transloadit.com/docs/authentication
// Verify the test vector (default sha384 + algorithm prefix)
$this->request->secret = 'd805593620e689465d7da6b8caf2ac7384fdb7e9';
$expectedSignature = 'fec703ccbe36b942c90d17f64b71268ed4f5f512';
$expectedSignature = 'sha384:69b74f954488cbb571cace210ae9039d18d84ec57edc784d19fd364f4295c99c93c14f0fed7f245b480d5856f12effc2';

$params = '{"auth":{"expires":"2010\/10\/19 09:01:20+00:00","key":"2b0c45611f6440dfb64611e872ec3211"},"steps":{"encode":{"robot":"\/video\/encode"}}}';
$signature = $this->request->signString($params);
$this->assertEquals($expectedSignature, $signature);

// Explicit algorithm override for legacy keys
$legacySignature = $this->request->signString($params, 'sha1');
$this->assertEquals('sha1:fec703ccbe36b942c90d17f64b71268ed4f5f512', $legacySignature);

// Request-level override should affect default signing behavior
$this->request->signatureAlgorithm = 'sha1';
$this->assertEquals('sha1:fec703ccbe36b942c90d17f64b71268ed4f5f512', $this->request->signString($params));
}

public function testSignStringWithInvalidAlgorithmThrowsInvalidArgumentException() {
$this->request->secret = 'secret';
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Unsupported signature algorithm: definitely-not-a-real-algorithm');
$this->request->signString('payload', 'definitely-not-a-real-algorithm');
}

public function testGetParamsString() {
Expand Down Expand Up @@ -146,7 +162,7 @@ public function testSignatureParityWithNodeCli(): void {
'width' => 320,
],
],
], 'cli-key', 'cli-secret', 'sha1');
], 'cli-key', 'cli-secret', 'sha384');

$this->assertNotNull($cliResult);
$this->assertArrayHasKey('signature', $cliResult);
Expand All @@ -166,8 +182,9 @@ public function testSignatureParityWithNodeCli(): void {
$cliParams['steps']['resize']['width']
);

$expectedSignature = hash_hmac('sha1', $cliResult['params'], 'cli-secret');
$this->assertEquals('sha1:' . $expectedSignature, $cliResult['signature']);
$expectedSignature = hash_hmac('sha384', $cliResult['params'], 'cli-secret');
$this->assertEquals('sha384:' . $expectedSignature, $cliResult['signature']);
$this->assertEquals($cliResult['signature'], $request->signString($cliResult['params']));
}

public function testExecute() {
Expand Down
3 changes: 3 additions & 0 deletions test/simple/TransloaditTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function testConstructor() {
public function testAttributes() {
$this->assertEquals($this->transloadit->key, null);
$this->assertEquals($this->transloadit->secret, null);
$this->assertEquals($this->transloadit->signatureAlgorithm, 'sha384');
}

public function testCreateAssembly() {
Expand Down Expand Up @@ -78,10 +79,12 @@ public function testCancelAssembly() {
public function testRequest() {
$this->transloadit->key = 'my-key';
$this->transloadit->secret = 'my-secret';
$this->transloadit->signatureAlgorithm = 'sha1';
$request = $this->transloadit->request(['url' => 'foobar'], false);

$this->assertEquals($this->transloadit->key, $request->key);
$this->assertEquals($this->transloadit->secret, $request->secret);
$this->assertEquals($this->transloadit->signatureAlgorithm, $request->signatureAlgorithm);
$this->assertEquals('foobar', $request->url);

// Unfortunately we can't test the $execute parameter because PHP
Expand Down
Loading