/**
  * 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 the authmethods and try to send a response message
     foreach ($this->authMethods as $authMethod => $authMethodInfo) {
         if (in_array($authMethod, $requestedMethods) && (in_array($realm->getRealmName(), $authMethodInfo['auth_realms']) || in_array("*", $authMethodInfo['auth_realms']))) {
             $this->onHelloAuthHandler($authMethod, $authMethodInfo, $realm, $session, $msg);
             $sentMessage = true;
         }
     }
     //If we already replied with a message, we don't have to do anything else
     if ($sentMessage) {
         return;
     }
     // If no authentication providers are registered for this realm send an abort message
     if ($this->realmHasAuthProvider($realm->getRealmName())) {
         $session->abort(new \stdClass(), "wamp.error.not_authorized");
         return;
     }
     //If we've gotten this far, it means that the user needs to be Logged in as anonymous
     $session->setAuthenticationDetails(AuthenticationDetails::createAnonymous());
     $details = new \stdClass();
     $session->sendMessage(new WelcomeMessage($session->getSessionId(), $details));
     $session->setAuthenticated(true);
 }
 /**
  * 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);
         }
     }
 }