/** * Partial test reused by actual exposed tests. * Publishes messages to a provided channel, checks for encryption, retrieves history, * compares decoded payloads with original messages */ private function executePublishTestOnChannel(Channel $channel) { // first publish some messages $data = ['utf' => 'This is a UTF-8 string message payload. äôč ビール', 'binary' => hex2bin('00102030405060708090a0b0c0d0e0f0ff'), 'object' => (object) ['test' => 'This is a JSONObject message payload'], 'array' => ['This is a JSONarray message payload', 'Test']]; $messages = []; foreach ($data as $type => $payload) { $msg = new Message(); $msg->name = $type; $msg->data = $payload; $messages[] = $msg; } $channel->publish($messages); // publish all messages at once foreach ($messages as $msg) { if ($channel->getCipherParams()) { // check if the messages are encrypted $msgJSON = json_decode($msg->toJSON()); $this->assertTrue(strpos($msgJSON->encoding, $channel->getCipherParams()->getAlgorithmString()) !== false, 'Expected message encoding to contain a cipher algorithm'); $this->assertFalse($msgJSON->data === $payload, 'Expected encrypted message payload not to match original data'); } else { // check if the messages are unencrypted $msgJSON = json_decode($msg->toJSON()); $this->assertTrue(strpos($msgJSON->encoding, 'cipher') === false, 'Expected message encoding not to contain a cipher algorithm'); } } // get the history for this channel $messages = $channel->history(); $this->assertNotNull($messages, 'Expected non-null messages'); $this->assertEquals(4, count($messages->items), 'Expected 4 messages'); $actual_message_order = []; // verify message contents foreach ($messages->items as $message) { $actual_message_order[] = $message->name; // payload must exactly match the one that was sent and must be decrypted automatically $originalPayload = $data[$message->name]; $this->assertEquals($originalPayload, $message->data, 'Expected retrieved message\'s data to match the original data (' . $message->name . ')'); } // verify message order $this->assertEquals(array_reverse(array_keys($data)), $actual_message_order, 'Expected messages in reverse order'); }
/** * Posts a message to this channel * @param mixed ... Either a Message, array of Message-s, or (string eventName, string data, [string clientId]) * @throws \Ably\Exceptions\AblyException */ public function publish() { $args = func_get_args(); $json = ''; if (count($args) == 1 && is_a($args[0], 'Ably\\Models\\Message')) { // single Message $msg = $args[0]; if ($this->options->cipher) { $msg->setCipherParams($this->options->cipher); } $json = $msg->toJSON(); } else { if (count($args) == 1 && is_array($args[0])) { // array of Messages $jsonArray = []; foreach ($args[0] as $msg) { if ($this->options->cipher) { $msg->setCipherParams($this->options->cipher); } $jsonArray[] = $msg->toJSON(); } $json = '[' . implode(',', $jsonArray) . ']'; } else { if (count($args) >= 2 && count($args) <= 3) { // eventName, data[, clientId] $msg = new Message(); $msg->name = $args[0]; $msg->data = $args[1]; if (count($args) == 3) { $msg->clientId = $args[2]; } if ($this->options->cipher) { $msg->setCipherParams($this->options->cipher); } $json = $msg->toJSON(); } else { throw new AblyException('Wrong parameters provided, use either Message, array of Messages, or name and data', 40003, 400); } } } $authClientId = $this->ably->auth->clientId; // if the message has a clientId set and we're using token based auth, the clientIds must match unless we're a wildcard client if (!empty($msg->clientId) && !$this->ably->auth->isUsingBasicAuth() && $authClientId != '*' && $msg->clientId != $authClientId) { throw new AblyException('Message\'s clientId does not match the clientId of the authorisation token.', 40102, 401); } $this->ably->post($this->channelPath . '/messages', $headers = [], $json); return true; }
/** * Tests if example messages match actual messages after encryption/decryption and vice versa: * decrypt(encrypted_example) == unencrypted_example * encrypt(unencrypted_example) == encrypted_example * * @dataProvider filenameProvider */ public function testMessageEncryptionAgainstFixture($filename) { $fixture = json_decode(file_get_contents($filename)); foreach ($fixture->items as $example) { $cipherParams = Crypto::getDefaultParams(['key' => $fixture->key, 'algorithm' => $fixture->algorithm, 'keyLength' => $fixture->keylength, 'mode' => $fixture->mode, 'iv' => $fixture->iv, 'base64Key' => true, 'base64Iv' => true]); $decodedExample = new Message(); $decodedExample->fromJSON($example->encoded); $decryptedExample = new Message(); $decryptedExample->setCipherParams($cipherParams); $decryptedExample->fromJSON($example->encrypted); $this->assertEquals($decodedExample->data, $decryptedExample->data, 'Expected unencrypted and decrypted message\'s contents to match'); $decodedExample->setCipherParams($cipherParams); $encryptedJSON = json_decode($decodedExample->toJSON()); $this->assertEquals($example->encrypted->data, $encryptedJSON->data, 'Expected encrypted and example encrypted message\'s contents to match'); } }