containsParameter('channel_uuid')) { throw new MissingRpcArgumentException('channel_uuid'); } try { if ($request->isExternal()) { return self::handleExternal($request, $rpcRequest); } } catch (DatabaseOperationException $e) { throw new StandardRpcException('There was an error while handling the external request', StandardError::INTERNAL_SERVER_ERROR, $e); } return self::handleInternal($request, $rpcRequest); } /** * @param ClientRequest $request * @param RpcRequest $rpcRequest * @return SerializableInterface|null * @throws StandardRpcException */ private static function handleInternal(ClientRequest $request, RpcRequest $rpcRequest): ?SerializableInterface { try { $requestingPeer = $request->getPeer(); $encryptionChannel = EncryptionChannelManager::getChannel($rpcRequest->getParameter('channel_uuid')); } catch(DatabaseOperationException $e) { throw new StandardRpcException('There was an error while trying to obtain the encryption channel', StandardError::INTERNAL_SERVER_ERROR, $e); } if($encryptionChannel === null) { return $rpcRequest->produceError(StandardError::NOT_FOUND, 'The requested encryption channel was not found'); } elseif(!$encryptionChannel->isParticipant($requestingPeer->getAddress())) { return $rpcRequest->produceError(StandardError::UNAUTHORIZED, 'The requested encryption channel is not accessible'); } elseif($encryptionChannel->getStatus() === EncryptionChannelStatus::CLOSED) { return $rpcRequest->produceResponse(false); } try { EncryptionChannelManager::closeChannel($encryptionChannel->getUuid()); } catch(DatabaseOperationException $e) { throw new StandardRpcException('An error occurred while trying to close the encryption channel', StandardError::INTERNAL_SERVER_ERROR, $e); } $externalPeer = $encryptionChannel->getExternalPeer(); if($externalPeer !== null) { try { $rpcClient = Socialbox::getExternalSession($encryptionChannel->getCallingPeerAddress()->getDomain()); $rpcClient->encryptionCloseChannel( channelUuid: $rpcRequest->getParameter('channel_uuid'), identifiedAs: $requestingPeer->getAddress() ); } catch(Exception $e) { if($e instanceof RpcException) { throw StandardRpcException::fromRpcException($e); } throw new StandardRpcException('There was an error while trying to notify the external server of the encryption channel', StandardError::INTERNAL_SERVER_ERROR, $e); } } return $rpcRequest->produceResponse(true); } /** * @param ClientRequest $request * @param RpcRequest $rpcRequest * @return SerializableInterface|null * @throws StandardRpcException */ private static function handleExternal(ClientRequest $request, RpcRequest $rpcRequest): ?SerializableInterface { if($request->getIdentifyAs() === null) { throw new StandardRpcException('The IdentifyAs field is required for external requests', StandardError::UNAUTHORIZED); } try { $encryptionChannel = EncryptionChannelManager::getChannel($rpcRequest->getParameter('channel_uuid')); } catch(DatabaseOperationException $e) { throw new StandardRpcException('An error occurred while trying to obtain the encryption channel', StandardError::INTERNAL_SERVER_ERROR, $e); } if($encryptionChannel === null) { return $rpcRequest->produceError(StandardError::NOT_FOUND, 'The requested encryption channel was not found'); } elseif(!$encryptionChannel->isParticipant($request->getIdentifyAs())) { return $rpcRequest->produceError(StandardError::UNAUTHORIZED, 'The requested encryption channel is not accessible'); } elseif($encryptionChannel->getStatus() === EncryptionChannelStatus::CLOSED) { return $rpcRequest->produceResponse(false); } try { EncryptionChannelManager::closeChannel($encryptionChannel->getUuid()); } catch(DatabaseOperationException $e) { throw new StandardRpcException('An error occurred while trying to close the encryption channel', StandardError::INTERNAL_SERVER_ERROR, $e); } return $rpcRequest->produceResponse(true); } }