Ping::execute($request, $rpcRequest), self::GET_SESSION_STATE => GetSessionState::execute($request, $rpcRequest), self::GET_ALLOWED_METHODS => GetAllowedMethods::execute($request, $rpcRequest), self::GET_PRIVACY_POLICY => GetPrivacyPolicy::execute($request, $rpcRequest), self::ACCEPT_PRIVACY_POLICY => AcceptPrivacyPolicy::execute($request, $rpcRequest), self::GET_TERMS_OF_SERVICE => GetTermsOfService::execute($request, $rpcRequest), self::ACCEPT_TERMS_OF_SERVICE => AcceptTermsOfService::execute($request, $rpcRequest), self::GET_COMMUNITY_GUIDELINES => GetCommunityGuidelines::execute($request, $rpcRequest), self::ACCEPT_COMMUNITY_GUIDELINES => AcceptCommunityGuidelines::execute($request, $rpcRequest), self::VERIFICATION_GET_IMAGE_CAPTCHA => VerificationGetImageCaptcha::execute($request, $rpcRequest), self::VERIFICATION_ANSWER_IMAGE_CAPTCHA => VerificationAnswerImageCaptcha::execute($request, $rpcRequest), self::VERIFICATION_PASSWORD_AUTHENTICATION => VerificationPasswordAuthentication::execute($request, $rpcRequest), self::VERIFICATION_OTP_AUTHENTICATION => VerificationOtpAuthentication::execute($request, $rpcRequest), self::SETTINGS_SET_PASSWORD => SettingsSetPassword::execute($request, $rpcRequest), self::SETTINGS_UPDATE_PASSWORD => SettingsUpdatePassword::execute($request, $rpcRequest), self::SETTINGS_DELETE_PASSWORD => SettingsDeletePassword::execute($request, $rpcRequest), self::SETTINGS_SET_DISPLAY_NAME => SettingsSetDisplayName::execute($request, $rpcRequest), self::SETTINGS_DELETE_DISPLAY_NAME => SettingsDeleteDisplayName::execute($request, $rpcRequest), self::SETTINGS_SET_DISPLAY_PICTURE => SettingsSetDisplayPicture::execute($request, $rpcRequest), self::SETTINGS_DELETE_DISPLAY_PICTURE => SettingsDeleteDisplayPicture::execute($request, $rpcRequest), self::SETTINGS_SET_EMAIL => SettingsSetEmailAddress::execute($request, $rpcRequest), self::SETTINGS_DELETE_EMAIL => SettingsDeleteEmailAddress::execute($request, $rpcRequest), self::SETTINGS_SET_PHONE => SettingsSetPhoneNumber::execute($request, $rpcRequest), self::SETTINGS_DELETE_PHONE => SettingsDeletePhoneNumber::execute($request, $rpcRequest), self::SETTINGS_SET_BIRTHDAY => SettingsSetBirthday::execute($request, $rpcRequest), self::SETTINGS_DELETE_BIRTHDAY => SettingsDeleteBirthday::execute($request, $rpcRequest), self::SETTINGS_ADD_SIGNING_KEY => SettingsAddSigningKey::execute($request, $rpcRequest), self::SETTINGS_GET_SIGNING_KEYS => SettingsGetSigningKeys::execute($request, $rpcRequest), self::ADDRESS_BOOK_ADD_CONTACT => AddressBookAddContact::execute($request, $rpcRequest), self::ADDRESS_BOOK_DELETE_CONTACT => AddressBookDeleteContact::execute($request, $rpcRequest), self::ADDRESS_BOOK_GET_CONTACTS => AddressBookGetContacts::execute($request, $rpcRequest), self::AUTHENTICATE => Authenticate::execute($request, $rpcRequest), self::RESOLVE_PEER => ResolvePeer::execute($request, $rpcRequest), default => $rpcRequest->produceError(StandardError::METHOD_NOT_ALLOWED, sprintf("The method %s is not supported by the server", $rpcRequest->getMethod())) }; } /** * Checks if the access method is allowed for the given client request. * * @param ClientRequest $clientRequest The client request instance to check access against. * @return void * @throws DatabaseOperationException If an error occurs while checking the database for session information. * @throws StandardException If the method is not allowed for the given client request. */ public function checkAccess(ClientRequest $clientRequest): void { if(in_array($this, self::getAllowedMethods($clientRequest))) { return; } throw new StandardException(StandardError::METHOD_NOT_ALLOWED->getMessage(), StandardError::METHOD_NOT_ALLOWED); } /** * Determines the list of allowed methods for a given client request. * * @param ClientRequest $clientRequest The client request for which allowed methods are determined. * @return array Returns an array of allowed methods for the provided client request. * @throws DatabaseOperationException If an error occurs while checking the database for session information. */ public static function getAllowedMethods(ClientRequest $clientRequest): array { // These methods should always accessible $methods = [ // Important methods self::PING, // Always allow the ping method self::GET_SESSION_STATE, // The session state should always be accessible self::GET_ALLOWED_METHODS, // Client should always be able to get the allowed methods self::GET_PRIVACY_POLICY, // The user should always be able to get the privacy policy self::GET_TERMS_OF_SERVICE, // The user should always be able to get the terms of service self::GET_COMMUNITY_GUIDELINES, // The user should always be able to get the community guidelines ]; $session = $clientRequest->getSession(); if($session === null) { return $methods; } try { $external = $session->isExternal(); } catch(DatabaseOperationException) { $external = false; } // If the session is external (eg; coming from a different server) // Servers will have their own access control mechanisms if($external) { $methods = array_merge($methods, self::getExternalMethods($clientRequest)); } // If the session is authenticated, then allow additional method calls elseif($session->isAuthenticated()) { $methods = array_merge($methods, self::getAuthenticatedMethods()); } // If the session isn't authenticated, check if it's a registering user elseif($session->flagExists(SessionFlags::REGISTRATION_REQUIRED)) { $methods = array_merge($methods, self::getRegistrationMethods($session)); } // If the user is a registering peer, check if it's an authenticating one elseif($session->flagExists(SessionFlags::AUTHENTICATION_REQUIRED)) { $methods = array_merge($methods, self::getAuthenticationMethods($clientRequest)); } return $methods; } /** * Retrieves a list of external methods based on the client's session state. * * @param ClientRequest $clientRequest The client request object containing all the request parameters * @return array Returns an array methods that are available for external sessions */ private static function getExternalMethods(ClientRequest $clientRequest): array { $methods = []; $session = $clientRequest->getSession(); if(!$session->isAuthenticated() || $session->flagExists(SessionFlags::AUTHENTICATION_REQUIRED)) { $methods[] = self::AUTHENTICATE; } else { $methods[] = self::RESOLVE_PEER; } return $methods; } /** * Retrieves a list of authenticated user methods based on configuration settings. * * @return array An array of methods that are available to */ private static function getAuthenticatedMethods(): array { // These methods are always allowed for authenticated users $methods = [ self::SETTINGS_ADD_SIGNING_KEY, self::SETTINGS_GET_SIGNING_KEYS, self::SETTINGS_SET_DISPLAY_NAME, self::SETTINGS_SET_DISPLAY_PICTURE, self::SETTINGS_SET_PASSWORD, self::SETTINGS_UPDATE_PASSWORD, self::SETTINGS_SET_OTP, self::SETTINGS_SET_EMAIL, self::SETTINGS_SET_PHONE, self::SETTINGS_SET_BIRTHDAY, self::RESOLVE_PEER, self::ADDRESS_BOOK_ADD_CONTACT, self::ADDRESS_BOOK_DELETE_CONTACT, self::ADDRESS_BOOK_GET_CONTACTS, ]; // Prevent the user from deleting their display name if it is required if(!Configuration::getRegistrationConfiguration()->isDisplayNameRequired()) { $methods[] = self::SETTINGS_DELETE_DISPLAY_NAME; } // Prevent the user from deleting their password if it is required if(!Configuration::getRegistrationConfiguration()->isPasswordRequired()) { $methods[] = self::SETTINGS_DELETE_PASSWORD; } // Prevent the user from deleting their display picture if it is required if(!Configuration::getRegistrationConfiguration()->isDisplayPictureRequired()) { $methods[] = self::SETTINGS_DELETE_DISPLAY_PICTURE; } // Prevent the user from deleting their OTP if it is required if(!Configuration::getRegistrationConfiguration()->isOtpRequired()) { $methods[] = self::SETTINGS_DELETE_OTP; } // Prevent the user from deleting their Phone Number if it is required if(!Configuration::getRegistrationConfiguration()->isPhoneNumberRequired()) { $methods[] = self::SETTINGS_DELETE_PHONE; } // Prevent the user from deleting their email address if it is required if(!Configuration::getRegistrationConfiguration()->isEmailAddressRequired()) { $methods[] = self::SETTINGS_DELETE_EMAIL; } // Prevent the user from deleting their birthday if it is required if(!Configuration::getRegistrationConfiguration()->isBirthdayRequired()) { $methods[] = self::SETTINGS_DELETE_BIRTHDAY; } return $methods; } /** * Retrieves a list of registration methods based on the session flags. * * @param SessionRecord $session The session record containing flags that determine available registration methods. * @return array An array of registration methods available for the session. */ private static function getRegistrationMethods(SessionRecord $session): array { // Don't allow registration methods if registration is disabled if(!Configuration::getRegistrationConfiguration()->isRegistrationEnabled()) { return []; } $methods = []; // If the flag `VER_PRIVACY_POLICY` is set, then the user can accept the privacy policy if($session->flagExists(SessionFlags::VER_PRIVACY_POLICY)) { $methods[] = self::ACCEPT_PRIVACY_POLICY; } // If the flag `VER_TERMS_OF_SERVICE` is set, then the user can accept the terms of service if($session->flagExists(SessionFlags::VER_TERMS_OF_SERVICE)) { $methods[] = self::ACCEPT_TERMS_OF_SERVICE; } // If the flag `VER_COMMUNITY_GUIDELINES` is set, then the user can accept the community guidelines if($session->flagExists(SessionFlags::VER_COMMUNITY_GUIDELINES)) { $methods[] = self::ACCEPT_COMMUNITY_GUIDELINES; } // If the flag `VER_IMAGE_CAPTCHA` is set, then the user has to get and answer an image captcha if($session->flagExists(SessionFlags::VER_IMAGE_CAPTCHA)) { $methods[] = self::VERIFICATION_GET_IMAGE_CAPTCHA; $methods[] = self::VERIFICATION_ANSWER_IMAGE_CAPTCHA; } // If the flag `SET_PASSWORD` is set, then the user has to set a password if($session->flagExists(SessionFlags::SET_PASSWORD)) { $methods[] = self::SETTINGS_SET_PASSWORD; } // If the flag `SET_OTP` is set, then the user has to set an OTP if($session->flagExists(SessionFLags::SET_OTP)) { $methods[] = self::SETTINGS_SET_OTP; } // If the flag `SET_DISPLAY_NAME` is set, then the user has to set a display name if($session->flagExists(SessionFlags::SET_DISPLAY_NAME)) { $methods[] = self::SETTINGS_SET_DISPLAY_NAME; } // If the flag `SET_DISPLAY_PICTURE` is set, then the user has to set a display picture if($session->flagExists(SessionFlags::SET_DISPLAY_PICTURE)) { $methods[] = self::SETTINGS_SET_DISPLAY_PICTURE; } // If the flag `SET_EMAIL` is set, then the user has to set an email address if($session->flagExists(SessionFlags::SET_EMAIL)) { $methods[] = self::SETTINGS_SET_EMAIL; } // If the flag `SET_PHONE` is set, then the user has to set a phone number if($session->flagExists(SessionFlags::SET_PHONE)) { $methods[] = self::SETTINGS_SET_PHONE; } // If the flag `SET_BIRTHDAY` is set, then the user has to set a birthday if($session->flagExists(SessionFlags::SET_BIRTHDAY)) { $methods[] = self::SETTINGS_SET_BIRTHDAY; } return $methods; } /** * Retrieves the list of authentication methods available for the given client request. * * @param ClientRequest $clientRequest The client request for which the authentication methods are determined. * @return array The list of available authentication methods as an array of constants. * @throws DatabaseOperationException If an error occurs while checking the database for authentication methods. */ private static function getAuthenticationMethods(ClientRequest $clientRequest): array { if(!Configuration::getAuthenticationConfiguration()->isEnabled()) { return []; } $methods = []; if(Configuration::getAuthenticationConfiguration()->isImageCaptchaVerificationRequired()) { $methods[] = self::VERIFICATION_GET_IMAGE_CAPTCHA; $methods[] = self::VERIFICATION_ANSWER_IMAGE_CAPTCHA; } $peer = $clientRequest->getPeer(); if(PasswordManager::usesPassword($peer)) { $methods[] = self::VERIFICATION_PASSWORD_AUTHENTICATION; } if(OneTimePasswordManager::usesOtp($peer->getUuid())) { $methods[] = self::VERIFICATION_OTP_AUTHENTICATION; } return $methods; } }