/** * Connect to ARI. * * @param string $address Example ws://localhost:8088/ari/events?api_key=username:password&app=stasis_app_name */ public function connect($address) { $components = parse_url($address); $host = $components['host']; $port = $components['port']; $path = $components['path']; $query = $components['query']; $queryParts = []; parse_str($query, $queryParts); $this->stasisApplicationName = $queryParts['app']; $apiKey = $queryParts['api_key']; list($username, $password) = explode(':', $apiKey); $this->endpoint = new PestJSON('http://' . $host . ':' . $port . dirname($path)); $this->endpoint->setupAuth($username, $password, 'basic'); $this->wsClient = new WebSocket($address, $this->eventLoop, $this->logger); $this->wsClient->on("message", function (WebSocketMessage $rawMessage) { $message = new Message($rawMessage->getData()); $eventType = '\\phparia\\Events\\' . $message->getType(); if (class_exists($eventType)) { $event = new $eventType($this, $rawMessage->getData()); } else { $this->logger->warn("Event: '{$eventType}' not implemented"); // @todo Create a generic event for any that are not implemented return; } // Emit the specific event (just to get it back to where it came from) if ($event instanceof IdentifiableEventInterface) { $this->logger->notice("Emitting ID event: {$event->getEventId()}"); $this->wsClient->emit($event->getEventId(), array('event' => $event)); } // Emit the general event $this->logger->notice("Emitting event: {$message->getType()}"); $this->wsClient->emit($message->getType(), array('event' => $event)); }); }
public function __construct($server, LoggerInterface $logger) { $this->server = $server; $this->logger = $logger; $this->handlers = new \SplObjectStorage(); $this->membership = new \SplObjectStorage(); /** * @var $membership \SplObjectStorage|WebSocketUriHandlerInterface[] */ $membership = $this->membership; $that = $this; $server->on("connect", function (WebSocketTransportInterface $client) use($that, $logger, $membership) { $handler = $that->matchConnection($client); if ($handler) { $logger->notice("Added client {$client->getId()} to " . get_class($handler)); $membership->attach($client, $handler); $handler->emit("connect", array("client" => $client)); $handler->addConnection($client); } else { $logger->err("Cannot route {$client->getId()} with request uri {$client->getHandshakeRequest()->getUriString()}"); } }); $server->on('disconnect', function (WebSocketTransportInterface $client) use($that, $logger, $membership) { if ($membership->contains($client)) { $handler = $membership[$client]; $membership->detach($client); $logger->notice("Removed client {$client->getId()} from" . get_class($handler)); $handler->removeConnection($client); $handler->emit("disconnect", array("client" => $client)); } else { $logger->warn("Client {$client->getId()} not attached to any handler, so cannot remove it!"); } }); $server->on("message", function (WebSocketTransportInterface $client, WebSocketMessageInterface $message) use($that, $logger, $membership) { if ($membership->contains($client)) { $handler = $membership[$client]; $handler->emit("message", compact('client', 'message')); } else { $logger->warn("Client {$client->getId()} not attached to any handler, so cannot forward the message!"); } }); }
/** * Login via an external Application. This will get obsolet as soon we'll have a full featured Rest API. * * Passed in params: * - appKey: Application identifier key * - user: Name of the user to log in * - pass: Password of the user to log in * * Returns an json response with the session-id. * Non existent users will be created! * */ public function loginExternAction() { $services = $this->serviceLocator; $adapter = $services->get('ExternalApplicationAdapter'); $appKey = $this->params()->fromPost('appKey'); $adapter->setIdentity($this->params()->fromPost('user'))->setCredential($this->params()->fromPost('pass'))->setApplicationKey($appKey); $auth = $this->auth; $result = $auth->authenticate($adapter); if ($result->isValid()) { $this->logger->info('User ' . $this->params()->fromPost('user') . ' logged via ' . $appKey); // the external login may include some parameters for an update $updateParams = $this->params()->fromPost(); unset($updateParams['user'], $updateParams['pass'], $updateParams['appKey']); $resultMessage = $result->getMessages(); $password = null; if (array_key_exists('firstLogin', $resultMessage) && $resultMessage['firstLogin'] === true) { $password = substr(md5(uniqid()), 0, 6); $updateParams['password'] = $password; } if (!empty($updateParams)) { $user = $auth->getUser(); try { foreach ($updateParams as $updateKey => $updateValue) { if ('email' == $updateKey) { $user->info->email = $updateValue; } $user->{$updateKey} = $updateValue; } } catch (\Exception $e) { } $services->get('repositories')->store($user); } $resultMessage = $result->getMessages(); // TODO: send a mail also when required (maybe first mail failed or email has changed) if (array_key_exists('firstLogin', $resultMessage) && $resultMessage['firstLogin'] === true) { // first external Login $userName = $this->params()->fromPost('user'); $this->logger->debug('first login for User: '******'/^(.*)@\\w+$/', $userName, $realUserName)) { $userName = $realUserName[1]; } $mail = $this->mailer('htmltemplate'); /* @var $mail \Core\Mail\HTMLTemplateMessage */ $apps = $this->config('external_applications'); $apps = array_flip($apps); $application = isset($apps[$appKey]) ? $apps[$appKey] : null; $mail->setVariables(array('application' => $application, 'login' => $userName, 'password' => $password)); $mail->setSubject($this->options->getMailSubjectRegistration()); $mail->setTemplate('mail/first-external-login'); $mail->addTo($user->getInfo()->getEmail()); try { $this->mailer($mail); $this->logger->info('Mail first-login sent to ' . $userName); } catch (\Zend\Mail\Transport\Exception\ExceptionInterface $e) { $this->logger->warn('No Mail was sent'); $this->logger->debug($e); } } return new JsonModel(array('status' => 'success', 'token' => session_id())); } else { $this->logger->info('Failed to authenticate User ' . $this->params()->fromPost('user') . ' via ' . $this->params()->fromPost('appKey')); $this->getResponse()->setStatusCode(Response::STATUS_CODE_401); return new JsonModel(array('status' => 'failure', 'user' => $this->params()->fromPost('user'), 'appKey' => $this->params()->fromPost('appKey'), 'code' => $result->getCode(), 'messages' => $result->getMessages())); } }
/** * Logs a message using the logger. * * @param string $message */ public function warn($message) { if (isset($this->logger)) { $this->logger->warn($message); } }