/** * Check to see if an action is authorized on a specific uri given the * context of the session attempting the action * * actionMsg should be an instance of: register, call, subscribe, or publish messages * * @param Session $session * @param ActionMessageInterface $actionMsg * @throws \Exception * @return boolean */ public function isAuthorizedTo(Session $session, ActionMessageInterface $actionMsg) { // authorization $action = $actionMsg->getActionName(); $uri = $actionMsg->getUri(); $authenticationDetails = $session->getAuthenticationDetails(); // admin can do anything - pretty important // if this isn't here - then we can't setup any other rules if ($authenticationDetails->hasAuthRole('admin')) { return true; } if (!$this->isReady()) { return false; } $rolesToCheck = ["default"]; if (count($authenticationDetails->getAuthRoles()) > 0) { $rolesToCheck = array_merge($rolesToCheck, $authenticationDetails->getAuthRoles()); } return $this->isAuthorizedByRolesActionAndUri($rolesToCheck, $action, $uri); }
/** * @param Session $session * @param CallMessage $msg * @return bool */ private function processCall(Session $session, CallMessage $msg) { $registration = $this->getRegistrationByProcedureName($msg->getProcedureName()); if (!$registration) { $errorMsg = ErrorMessage::createErrorMessageFromMessage($msg); $this->manager->error('No registration for call message: ' . $msg->getProcedureName()); $errorMsg->setErrorURI('wamp.error.no_such_registration'); $session->sendMessage($errorMsg); return false; } $invocationMessage = InvocationMessage::createMessageFrom($msg, $registration); if ($registration->getDiscloseCaller() === true && $session->getAuthenticationDetails()) { $details = ["caller" => $session->getSessionId(), "authid" => $session->getAuthenticationDetails()->getAuthId(), "authmethod" => $session->getAuthenticationDetails()->getAuthMethod()]; $invocationMessage->setDetails($details); } $call = new Call($msg, $session, $invocationMessage, $registration->getSession()); $this->calls->attach($call); $registration->getSession()->sendMessage($invocationMessage); }
/** * @param Session $session * @param EventMessage $msg * @param Subscription $subscription */ private function disclosePublisherOption(Session $session, EventMessage $msg, Subscription $subscription) { if ($subscription->isDisclosePublisher() === true) { $details = ["caller" => $session->getSessionId(), "authid" => $session->getAuthenticationDetails()->getAuthId(), "authrole" => $session->getAuthenticationDetails()->getAuthRole(), "authroles" => $session->getAuthenticationDetails()->getAuthRoles(), "authmethod" => $session->getAuthenticationDetails()->getAuthMethod()]; $msg->setDetails(array_merge($msg->getDetails(), $details)); } }
/** * Call the handler that was registered to handle the Authenticate Message * * @param $authMethod * @param $authMethodInfo * @param Realm $realm * @param Session $session * @param AuthenticateMessage $msg */ private function onAuthenticateHandler($authMethod, $authMethodInfo, Realm $realm, Session $session, AuthenticateMessage $msg) { $onAuthenticateSuccess = function ($res) use($realm, $session) { if (count($res) < 1) { $session->abort(new \stdClass(), "thruway.error.authentication_failure"); return; } // we should figure out a way to have the router send the welcome // message so that the roles and extras that go along with it can be // filled in if ($res[0] == "SUCCESS") { $welcomeDetails = new \stdClass(); if (isset($res[1]->authid)) { $session->getAuthenticationDetails()->setAuthId($res[1]->authid); } else { $session->getAuthenticationDetails()->setAuthId('authenticated_user'); } $authRole = 'authenticated_user'; $session->getAuthenticationDetails()->addAuthRole($authRole); if (isset($res[1]->authroles)) { $session->getAuthenticationDetails()->addAuthRole($res[1]->authroles); } if (isset($res[1]->authrole)) { $session->getAuthenticationDetails()->addAuthRole($res[1]->authrole); } if (isset($res[1]->_thruway_authextra)) { $session->getAuthenticationDetails()->setAuthExtra($res[1]->_thruway_authextra); } if (isset($res[1]) && is_object($res[1])) { $res[1]->authrole = $session->getAuthenticationDetails()->getAuthRole(); $res[1]->authroles = $session->getAuthenticationDetails()->getAuthRoles(); $res[1]->authid = $session->getAuthenticationDetails()->getAuthId(); foreach ($res[1] as $k => $v) { $welcomeDetails->{$k} = $v; } } $session->setAuthenticated(true); $session->sendMessage(new WelcomeMessage($session->getSessionId(), $welcomeDetails)); } else { $session->abort(new \stdClass(), "thruway.error.authentication_failure"); } }; $onAuthenticateError = function () use($session) { Logger::error($this, "onauthenticate rejected the promise"); $session->abort("thruway.error.unknown"); }; $extra = new \stdClass(); $extra->challenge_details = $session->getAuthenticationDetails()->getChallengeDetails(); $arguments = new \stdClass(); $arguments->extra = $extra; $arguments->authid = $session->getAuthenticationDetails()->getAuthId(); $arguments->challenge = $session->getAuthenticationDetails()->getChallenge(); $arguments->signature = $msg->getSignature(); $arguments->authmethod = $authMethod; $arguments->hello_message = $session->getHelloMessage(); // now we send our authenticate information to the RPC $onAuthenticateHandler = $authMethodInfo['handlers']->onauthenticate; $this->session->call($onAuthenticateHandler, [$arguments])->then($onAuthenticateSuccess, $onAuthenticateError); }
/** * @param Session $session */ public function disclosePublisher(Session $session) { $details = $this->getDetails(); $details->publisher = $session->getSessionId(); $details->topic = $this->topic; $authenticationDetails = $session->getAuthenticationDetails(); $details->authid = $authenticationDetails->getAuthId(); $details->authrole = $authenticationDetails->getAuthRole(); $details->authroles = $authenticationDetails->getAuthRoles(); $details->authmethod = $authenticationDetails->getAuthMethod(); if ($authenticationDetails->getAuthExtra() !== null) { $details->_thruway_authextra = $authenticationDetails->getAuthExtra(); } }
/** * Handle Authenticate message * * @param \Thruway\Realm $realm * @param \Thruway\Session $session * @param \Thruway\Message\AuthenticateMessage $msg * @throws \Exception */ public function handleAuthenticateMessage(Realm $realm, Session $session, AuthenticateMessage $msg) { if ($session->getAuthenticationDetails() === null) { throw new \Exception('Authenticate with no previous auth details'); } $authMethod = $session->getAuthenticationDetails()->getAuthMethod(); // find the auth method foreach ($this->authMethods as $am => $authMethodInfo) { if ($authMethod == $am) { // found it // now we send our authenticate information to the RPC $this->getCaller()->call($this->session, $authMethodInfo['handlers']['onauthenticate'], ['authmethod' => $authMethod, 'challenge' => $session->getAuthenticationDetails()->getChallenge(), 'extra' => ['challenge_details' => $session->getAuthenticationDetails()->getChallengeDetails()], 'signature' => $msg->getSignature(), 'authid' => $session->getAuthenticationDetails()->getAuthId()])->then(function ($res) use($session) { // if (!is_array($res)) { // return; // } if (count($res) < 1) { return; } // we should figure out a way to have the router send the welcome // message so that the roles and extras that go along with it can be // filled in if ($res[0] == "SUCCESS") { $welcomeDetails = ["roles" => []]; if (isset($res[1]) && isset($res[1]['authid'])) { $session->getAuthenticationDetails()->setAuthId($res[1]['authid']); } else { $session->getAuthenticationDetails()->setAuthId('authenticated_user'); $res[1]['authid'] = $session->getAuthenticationDetails()->getAuthId(); } $authRole = 'authenticated_user'; $session->getAuthenticationDetails()->addAuthRole($authRole); if (isset($res[1]) && isset($res[1]['authroles'])) { $session->getAuthenticationDetails()->addAuthRole($res[1]['authroles']); $authRole = $session->getAuthenticationDetails()->getAuthRole(); } if (isset($res[1]) && isset($res[1]['authrole'])) { $session->getAuthenticationDetails()->addAuthRole($res[1]['authrole']); } if (isset($res[1])) { $res[1]['authrole'] = $session->getAuthenticationDetails()->getAuthRole(); $res[1]['authroles'] = $session->getAuthenticationDetails()->getAuthRoles(); $res[1]['authid'] = $session->getAuthenticationDetails()->getAuthId(); if (is_array($res[1])) { $welcomeDetails = array_merge($welcomeDetails, $res[1]); } } $session->setAuthenticated(true); $session->sendMessage(new WelcomeMessage($session->getSessionId(), $welcomeDetails)); } else { $session->abort(new \stdClass(), "bad.login"); } }, function () use($session) { Logger::error($this, "onauthenticate rejected the promise"); $session->abort("thruway.error.unknown"); }); } } }