Skip to content

Commit 3d58891

Browse files
authored
Merge pull request vyuldashev#588 from therecluse26/therecluse26-encrypted-job-bugfix
Allow for encrypted command data
2 parents 30cc317 + 9bd427a commit 3d58891

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<env name="PORT" value="5672"/>
1111
<env name="PORT_SSL" value="5671"/>
1212
<env name="RABBITMQ_SSL_CAFILE" value="./tests/files/rootCA.pem"/>
13+
<env name="APP_KEY" value="12345678901234567890123456789012"/>
1314
</php>
1415
<logging/>
1516
</phpunit>

src/Queue/RabbitMQQueue.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
use ErrorException;
88
use Exception;
99
use Illuminate\Contracts\Queue\Queue as QueueContract;
10+
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
1011
use Illuminate\Queue\Queue;
1112
use Illuminate\Support\Arr;
13+
use Illuminate\Support\Facades\Crypt;
1214
use Illuminate\Support\Str;
1315
use PhpAmqpLib\Channel\AMQPChannel;
1416
use PhpAmqpLib\Connection\AbstractConnection;
@@ -525,6 +527,11 @@ protected function createMessage($payload, int $attempts = 0): array
525527
}
526528

527529
if (isset($currentPayload['data']['command'])) {
530+
// If the command data is encrypted, decrypt it first before attempting to unserialize
531+
if (is_subclass_of($currentPayload['data']['commandName'], ShouldBeEncrypted::class)) {
532+
$currentPayload['data']['command'] = Crypt::decrypt($currentPayload['data']['command']);
533+
}
534+
528535
$commandData = unserialize($currentPayload['data']['command']);
529536
if (property_exists($commandData, 'priority')) {
530537
$properties['priority'] = $commandData->priority;

tests/Feature/TestCase.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PhpAmqpLib\Exception\AMQPProtocolChannelException;
99
use RuntimeException;
1010
use VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob;
11+
use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestEncryptedJob;
1112
use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks\TestJob;
1213
use VladimirYuldashev\LaravelQueueRabbitMQ\Tests\TestCase as BaseTestCase;
1314

@@ -194,6 +195,103 @@ public function testBulk(): void
194195
$this->assertSame($count, Queue::size());
195196
}
196197

198+
public function testPushEncrypted(): void
199+
{
200+
Queue::push(new TestEncryptedJob());
201+
202+
sleep(1);
203+
204+
$this->assertSame(1, Queue::size());
205+
$this->assertNotNull($job = Queue::pop());
206+
$this->assertSame(1, $job->attempts());
207+
$this->assertInstanceOf(RabbitMQJob::class, $job);
208+
$this->assertSame(TestEncryptedJob::class, $job->resolveName());
209+
$this->assertNotNull($job->getJobId());
210+
211+
$payload = $job->payload();
212+
213+
$this->assertSame(TestEncryptedJob::class, $payload['displayName']);
214+
$this->assertSame('Illuminate\Queue\CallQueuedHandler@call', $payload['job']);
215+
$this->assertNull($payload['maxTries']);
216+
$this->assertNull($payload['backoff']);
217+
$this->assertNull($payload['timeout']);
218+
$this->assertNull($payload['retryUntil']);
219+
$this->assertSame($job->getJobId(), $payload['id']);
220+
221+
$job->delete();
222+
$this->assertSame(0, Queue::size());
223+
}
224+
225+
public function testPushEncryptedAfterCommit(): void
226+
{
227+
$transaction = new DatabaseTransactionsManager;
228+
229+
$this->app->singleton('db.transactions', function ($app) use ($transaction) {
230+
$transaction->begin('FakeDBConnection', 1);
231+
232+
return $transaction;
233+
});
234+
235+
TestEncryptedJob::dispatch()->afterCommit();
236+
237+
sleep(1);
238+
$this->assertSame(0, Queue::size());
239+
$this->assertNull(Queue::pop());
240+
241+
$transaction->commit('FakeDBConnection', 1, 0);
242+
243+
sleep(1);
244+
245+
$this->assertSame(1, Queue::size());
246+
$this->assertNotNull($job = Queue::pop());
247+
248+
$job->delete();
249+
$this->assertSame(0, Queue::size());
250+
}
251+
252+
public function testEncryptedLater(): void
253+
{
254+
Queue::later(3, new TestEncryptedJob());
255+
256+
sleep(1);
257+
258+
$this->assertSame(0, Queue::size());
259+
$this->assertNull(Queue::pop());
260+
261+
sleep(3);
262+
263+
$this->assertSame(1, Queue::size());
264+
$this->assertNotNull($job = Queue::pop());
265+
266+
$this->assertInstanceOf(RabbitMQJob::class, $job);
267+
268+
$body = json_decode($job->getRawBody(), true);
269+
270+
$this->assertSame(TestEncryptedJob::class, $body['displayName']);
271+
$this->assertSame('Illuminate\Queue\CallQueuedHandler@call', $body['job']);
272+
$this->assertSame(TestEncryptedJob::class, $body['data']['commandName']);
273+
$this->assertNotNull($job->getJobId());
274+
275+
$job->delete();
276+
$this->assertSame(0, Queue::size());
277+
}
278+
279+
public function testEncryptedBulk(): void
280+
{
281+
$count = 100;
282+
$jobs = [];
283+
284+
for ($i = 0; $i < $count; $i++) {
285+
$jobs[$i] = new TestEncryptedJob($i);
286+
}
287+
288+
Queue::bulk($jobs);
289+
290+
sleep(1);
291+
292+
$this->assertSame($count, Queue::size());
293+
}
294+
197295
public function testReleaseRaw(): void
198296
{
199297
Queue::pushRaw($payload = Str::random());

tests/Mocks/TestEncryptedJob.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace VladimirYuldashev\LaravelQueueRabbitMQ\Tests\Mocks;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
7+
use Illuminate\Contracts\Queue\ShouldQueue;
8+
use Illuminate\Foundation\Bus\Dispatchable;
9+
10+
class TestEncryptedJob implements ShouldBeEncrypted, ShouldQueue
11+
{
12+
use Dispatchable, Queueable;
13+
14+
public $i;
15+
16+
public function __construct($i = 0)
17+
{
18+
$this->i = $i;
19+
}
20+
21+
public function handle(): void
22+
{
23+
//
24+
}
25+
}

0 commit comments

Comments
 (0)