Beispiel #1
0
 /**
  * @depends testRealmCreate
  *
  * @param \Thruway\Realm $realm
  * @return \Thruway\Session
  */
 public function testJoin(\Thruway\Realm $realm)
 {
     $session = new \Thruway\Session(new \Thruway\Transport\DummyTransport());
     $realm->addSession($session);
     $this->assertSame($session->getRealm(), $realm);
     return $session;
 }
Beispiel #2
0
 /**
  * Gets called when the module is initialized in the router
  *
  * @inheritdoc
  */
 public function initModule(RouterInterface $router, LoopInterface $loop)
 {
     parent::initModule($router, $loop);
     $this->routerRealm = $router->getRealmManager()->getRealm($this->getRealm());
     $this->broker = $this->routerRealm->getBroker();
     $this->broker->setStateHandlerRegistry($this);
 }
Beispiel #3
0
 /**
  * @depends testRealmCreate
  *
  * @param \Thruway\Realm $realm
  * @return \Thruway\Session
  */
 public function testJoin(\Thruway\Realm $realm)
 {
     $session = new \Thruway\Session(new \Thruway\Transport\DummyTransport());
     $realm->onMessage($session, new \Thruway\Message\HelloMessage('test_realm', []));
     $this->assertInstanceOf('\\Thruway\\Message\\WelcomeMessage', $session->getTransport()->getLastMessageSent());
     $this->assertSame($session->getRealm(), $realm);
     return $session;
 }
Beispiel #4
0
 /**
  * Add new realm
  * 
  * @param \Thruway\Realm $realm
  * @throws \Thruway\Exception\InvalidRealmNameException
  * @throws \Exception
  */
 public function addRealm(Realm $realm)
 {
     $realmName = $realm->getRealmName();
     if (!static::validRealmName($realm->getRealmName())) {
         throw new InvalidRealmNameException();
     }
     if (array_key_exists($realm->getRealmName(), $this->realms)) {
         throw new \Exception("There is already a realm \"" . $realm->getRealmName() . "\"");
     }
     Logger::debug($this, "Adding realm \"" . $realmName . "\"");
     if ($realm->getManager() instanceof ManagerDummy) {
         /** remind people that we don't setup the manager for them if they
          * are creating their own realms */
         Logger::info($this, "Realm \"" . $realmName . "\" is using ManagerDummy");
     }
     $this->realms[$realm->getRealmName()] = $realm;
 }
Beispiel #5
0
 /**
  * Add new realm
  *
  * @param \Thruway\Realm $realm
  * @throws \Thruway\Exception\InvalidRealmNameException
  * @throws \Exception
  */
 public function addRealm(Realm $realm)
 {
     $realmName = $realm->getRealmName();
     if (!static::validRealmName($realm->getRealmName())) {
         throw new InvalidRealmNameException();
     }
     if (array_key_exists($realm->getRealmName(), $this->realms)) {
         throw new \Exception("There is already a realm \"" . $realm->getRealmName() . "\"");
     }
     Logger::debug($this, "Adding realm \"" . $realmName . "\"");
     $this->realms[$realm->getRealmName()] = $realm;
     $this->router->getEventDispatcher()->dispatch('new_realm', new NewRealmEvent($realm));
 }
 /**
  * Call the RPC URI that has been registered to handle Authentication Hello Messages
  *
  * @param $authMethod
  * @param $authMethodInfo
  * @param Realm $realm
  * @param Session $session
  * @param HelloMessage $msg
  */
 private function onHelloAuthHandler($authMethod, $authMethodInfo, Realm $realm, Session $session, HelloMessage $msg)
 {
     $authDetails = new AuthenticationDetails();
     $authDetails->setAuthMethod($authMethod);
     $helloDetails = $msg->getDetails();
     if (isset($helloDetails->authid)) {
         $authDetails->setAuthId($helloDetails->authid);
     }
     $session->setAuthenticationDetails($authDetails);
     $sessionInfo = ["sessionId" => $session->getSessionId(), "realm" => $realm->getRealmName()];
     $onHelloSuccess = function ($res) use($realm, $session, $msg) {
         // this is handling the return of the onhello RPC call
         if (isset($res[0]) && $res[0] == "FAILURE") {
             $session->abort(new \stdClass(), "thruway.error.authentication_failure");
             return;
         }
         if (count($res) < 2) {
             $session->abort(new \stdClass(), "thruway.auth.invalid_response_to_hello");
             return;
         }
         switch ($res[0]) {
             case "CHALLENGE":
                 // TODO: validate challenge message
                 $authMethod = $res[1]->challenge_method;
                 $challenge = $res[1]->challenge;
                 $session->getAuthenticationDetails()->setChallenge($challenge);
                 $session->getAuthenticationDetails()->setChallengeDetails($res[1]);
                 $challengeDetails = $session->getAuthenticationDetails()->getChallengeDetails();
                 $session->sendMessage(new ChallengeMessage($authMethod, $challengeDetails));
                 break;
             case "NOCHALLENGE":
                 $details = new \stdClass();
                 $details->authid = $res[1]->authid;
                 $details->authmethod = $session->getAuthenticationDetails()->getAuthMethod();
                 if (isset($res[1]->_thruway_authextra)) {
                     $session->getAuthenticationDetails()->setAuthExtra($res[1]->_thruway_authextra);
                 }
                 $session->sendMessage(new WelcomeMessage($session->getSessionId(), $details));
                 break;
             default:
                 $session->abort(new \stdClass(), "thruway.error.authentication_failure");
         }
     };
     $onHelloError = function () use($session) {
         Logger::error($this, "onhello rejected the promise");
         $session->abort("thruway.error.unknown");
     };
     $onHelloAuthHandler = $authMethodInfo['handlers']->onhello;
     //Make the OnHello Call
     $this->session->call($onHelloAuthHandler, [$msg, $sessionInfo])->then($onHelloSuccess, $onHelloError);
 }
 /**
  * Handle HelloMessage
  *
  * @param \Thruway\Realm $realm
  * @param \Thruway\Session $session
  * @param \Thruway\Message\HelloMessage $msg
  */
 public function handleHelloMessage(Realm $realm, Session $session, HelloMessage $msg)
 {
     $requestedMethods = $msg->getAuthMethods();
     $sentMessage = false;
     // go through our authMethods and see which one matches first
     foreach ($this->authMethods as $authMethod => $authMethodInfo) {
         if (in_array($authMethod, $requestedMethods) && (in_array($realm->getRealmName(), $authMethodInfo['auth_realms']) || in_array("*", $authMethodInfo['auth_realms']))) {
             // we can agree on something
             $authDetails = new AuthenticationDetails();
             $authDetails->setAuthMethod($authMethod);
             $helloDetails = $msg->getDetails();
             if (isset($helloDetails['authid'])) {
                 $authDetails->setAuthId($helloDetails['authid']);
             }
             $session->setAuthenticationDetails($authDetails);
             $sessionInfo = ["sessionId" => $session->getSessionId(), "realm" => $realm->getRealmName()];
             $this->session->call($authMethodInfo['handlers']['onhello'], [$msg, $sessionInfo])->then(function ($res) use($session, $msg) {
                 // this is handling the return of the onhello RPC call
                 if (count($res) < 2) {
                     $session->abort(new \stdClass(), "thruway.auth.invalid_response_to_hello");
                     return;
                 }
                 if ($res[0] == "CHALLENGE") {
                     // TODO: validate challenge message
                     $authMethod = $res[1]['challenge_method'];
                     $challenge = $res[1]['challenge'];
                     $session->getAuthenticationDetails()->setChallenge($challenge);
                     $session->getAuthenticationDetails()->setChallengeDetails($res[1]);
                     $session->sendMessage(new ChallengeMessage($authMethod, $session->getAuthenticationDetails()->getChallengeDetails()));
                 } else {
                     if ($res[0] == "NOCHALLENGE") {
                         $session->sendMessage(new WelcomeMessage($session->getSessionId(), ["authid" => $res[1]["authid"], "authmethod" => $session->getAuthenticationDetails()->getAuthMethod()]));
                     } else {
                         if ($res[0] == "ERROR") {
                             $session->abort(new \stdClass(), "authentication_failure");
                         } else {
                             $session->abort(new \stdClass(), "authentication_failure");
                         }
                     }
                 }
             }, function () use($session) {
                 Logger::error($this, "onhello rejected the promise");
                 $session->abort("thruway.error.unknown");
             });
             $sentMessage = true;
         }
     }
     /*
      * If we've gotten this far without sending a message, it means that no auth methods were sent by the client or the auth method sent
      * by the client hasn't been registered for this realm, so we need to check if there are any auth providers registered for the realm.
      * If there are auth provides registered then Abort. Otherwise we can send a welcome message.
      */
     if (!$sentMessage) {
         if ($this->realmHasAuthProvider($realm->getRealmName())) {
             $session->abort(new \stdClass(), "wamp.error.not_authorized");
         } else {
             //Logged in as anonymous
             $session->setAuthenticationDetails(AuthenticationDetails::createAnonymous());
             $roles = ["broker" => new \stdClass(), "dealer" => new \stdClass()];
             $session->sendMessage(new WelcomeMessage($session->getSessionId(), ["roles" => $roles]));
             $session->setAuthenticated(true);
         }
     }
 }