%PDF- %PDF-
Direktori : /home/silvzytp/calling_code/vendor/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/ |
Current File : //home/silvzytp/calling_code/vendor/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/AblyBroadcaster.php |
<?php namespace Illuminate\Broadcasting\Broadcasters; use Ably\AblyRest; use Ably\Exceptions\AblyException; use Ably\Models\Message as AblyMessage; use Illuminate\Broadcasting\BroadcastException; use Illuminate\Support\Str; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; /** * @author Matthew Hall (matthall28@gmail.com) * @author Taylor Otwell (taylor@laravel.com) */ class AblyBroadcaster extends Broadcaster { /** * The AblyRest SDK instance. * * @var \Ably\AblyRest */ protected $ably; /** * Create a new broadcaster instance. * * @param \Ably\AblyRest $ably * @return void */ public function __construct(AblyRest $ably) { $this->ably = $ably; } /** * Authenticate the incoming request for a given channel. * * @param \Illuminate\Http\Request $request * @return mixed * * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException */ public function auth($request) { $channelName = $this->normalizeChannelName($request->channel_name); if (empty($request->channel_name) || ($this->isGuardedChannel($request->channel_name) && ! $this->retrieveUser($request, $channelName))) { throw new AccessDeniedHttpException; } return parent::verifyUserCanAccessChannel( $request, $channelName ); } /** * Return the valid authentication response. * * @param \Illuminate\Http\Request $request * @param mixed $result * @return mixed */ public function validAuthenticationResponse($request, $result) { if (str_starts_with($request->channel_name, 'private')) { $signature = $this->generateAblySignature( $request->channel_name, $request->socket_id ); return ['auth' => $this->getPublicToken().':'.$signature]; } $channelName = $this->normalizeChannelName($request->channel_name); $user = $this->retrieveUser($request, $channelName); $broadcastIdentifier = method_exists($user, 'getAuthIdentifierForBroadcasting') ? $user->getAuthIdentifierForBroadcasting() : $user->getAuthIdentifier(); $signature = $this->generateAblySignature( $request->channel_name, $request->socket_id, $userData = array_filter([ 'user_id' => (string) $broadcastIdentifier, 'user_info' => $result, ]) ); return [ 'auth' => $this->getPublicToken().':'.$signature, 'channel_data' => json_encode($userData), ]; } /** * Generate the signature needed for Ably authentication headers. * * @param string $channelName * @param string $socketId * @param array|null $userData * @return string */ public function generateAblySignature($channelName, $socketId, $userData = null) { return hash_hmac( 'sha256', sprintf('%s:%s%s', $socketId, $channelName, $userData ? ':'.json_encode($userData) : ''), $this->getPrivateToken(), ); } /** * Broadcast the given event. * * @param array $channels * @param string $event * @param array $payload * @return void * * @throws \Illuminate\Broadcasting\BroadcastException */ public function broadcast(array $channels, $event, array $payload = []) { try { foreach ($this->formatChannels($channels) as $channel) { $this->ably->channels->get($channel)->publish( $this->buildAblyMessage($event, $payload) ); } } catch (AblyException $e) { throw new BroadcastException( sprintf('Ably error: %s', $e->getMessage()) ); } } /** * Build an Ably message object for broadcasting. * * @param string $event * @param array $payload * @return \Ably\Models\Message */ protected function buildAblyMessage($event, array $payload = []) { return tap(new AblyMessage, function ($message) use ($event, $payload) { $message->name = $event; $message->data = $payload; $message->connectionKey = data_get($payload, 'socket'); }); } /** * Return true if the channel is protected by authentication. * * @param string $channel * @return bool */ public function isGuardedChannel($channel) { return Str::startsWith($channel, ['private-', 'presence-']); } /** * Remove prefix from channel name. * * @param string $channel * @return string */ public function normalizeChannelName($channel) { if ($this->isGuardedChannel($channel)) { return str_starts_with($channel, 'private-') ? Str::replaceFirst('private-', '', $channel) : Str::replaceFirst('presence-', '', $channel); } return $channel; } /** * Format the channel array into an array of strings. * * @param array $channels * @return array */ protected function formatChannels(array $channels) { return array_map(function ($channel) { $channel = (string) $channel; if (Str::startsWith($channel, ['private-', 'presence-'])) { return str_starts_with($channel, 'private-') ? Str::replaceFirst('private-', 'private:', $channel) : Str::replaceFirst('presence-', 'presence:', $channel); } return 'public:'.$channel; }, $channels); } /** * Get the public token value from the Ably key. * * @return mixed */ protected function getPublicToken() { return Str::before($this->ably->options->key, ':'); } /** * Get the private token value from the Ably key. * * @return mixed */ protected function getPrivateToken() { return Str::after($this->ably->options->key, ':'); } /** * Get the underlying Ably SDK instance. * * @return \Ably\AblyRest */ public function getAbly() { return $this->ably; } }