예제 #1
0
 /**
  * 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));
     });
 }
예제 #2
0
 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!");
         }
     });
 }
예제 #3
0
 /**
  * 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()));
     }
 }
예제 #4
0
 /**
  * Logs a message using the logger.
  *
  * @param string $message
  */
 public function warn($message)
 {
     if (isset($this->logger)) {
         $this->logger->warn($message);
     }
 }