Создайте пользователя ejabberd из PHP

Мне нужно создать пользователя ejabberd из PHP-скрипта. Я также должен иметь возможность добавить нового пользователя в предопределенный общий список.

Должен ли я просто вызвать ejabberdctl с помощью exec() или есть лучший способ?

Solutions Collecting From Web of "Создайте пользователя ejabberd из PHP"

ejabberdctl на сегодняшний день является самым простым в этом конкретном случае. Другие варианты:

  • Внедрить полный клиент XMPP в PHP (!)

  • Внедрите модуль в Erlang, который проксирует запросы: связь PHP <-> Erlang должна быть через сокет, и в нем будет задействовано много маршалингов (!)

Вот мое окончательное решение:

Благодаря совету jldupont, что ejabberdctl будет самым простым решением, я нажал на препятствия, с которыми столкнулся, и имею рабочее решение.

По умолчанию пользователь apache не имеет права на успешное выполнение ejabberdctl (и не без оснований). Поэтому для того, чтобы он работал, вы должны называть его sudo . Но … sudo требует пароль, который представляет две проблемы:

  1. У пользователя apache нет пароля.
  2. Даже если бы это было так, нет способа ввести его из PHP.

Решение (для Ubuntu) – добавьте эту строку в конец /etc/sudoers :

 www-data ALL= (ejabberd) NOPASSWD: /usr/sbin/ejabberdctl 

Путь к файлу sudoers и ejabberdctl может отличаться для других дистрибутивов Linux. Это позволяет пользователю apache ( www-data ) запускать только ejabberdctl с повышенными привилегиями и без необходимости ввода пароля.

Все, что осталось, это PHP-код:

 <?php $username = 'tester'; $password = 'testerspassword'; $node = 'myserver.com'; exec('sudo -u ejabberd /usr/sbin/ejabberdctl register '.$username.' '.$node.' '.$password.' 2>&1',$output,$status); if($output == 0) { // Success! } else { // Failure, $output has the details echo '<pre>'; foreach($output as $o) { echo $o."\n"; } echo '</pre>'; } ?> 

Безопасность

Важно отметить, что это представляет значительный риск для безопасности, даже если вы разрешаете только одну команду запускать www-data . Если вы используете этот подход, вам нужно убедиться, что вы защищаете PHP-код за какой-то аутентификацией, чтобы не кто-нибудь мог его выполнить. Помимо очевидных угроз безопасности, он может открыть ваш сервер до атаки на отказ в обслуживании.

Я пришел к этому вопросу в 2016 году, есть гораздо более простые способы реализации этого, чем принятый ответ и самый высокий голос.

  1. Используйте библиотеку XMPP PHP, наиболее распространенную из которых:

https://github.com/fabiang/xmpp

  1. Хотя эта библиотека не поддерживает добавление пользователя из коробки, вы можете очень легко ее расширить

вот класс, который я написал для добавления пользователя:

 use Fabiang\Xmpp\Util\XML; /** * Register new user * @param string $username * @param string $password * @param string $email * @package XMPP\Protocol * @category XMPP */ class Register implements ProtocolImplementationInterface { protected $username; protected $password; protected $email; /** * Constructor. * * @param string $username * @param string $password * @param string $email */ public function __construct($username, $password, $email) { $this->username = $username; $this->password = $password; $this->email = $email; } /** * Build XML message * @return type */ public function toString() { $query = "<iq type='set' id='%s'><query xmlns='jabber:iq:register'><username>%s</username><password>%s</password><email>%s</email></query></iq>"; return XML::quoteMessage($query, XML::generateId(), (string) $this->username, (string) $this->password, (string) $this->email); } } 
  1. Вы должны включить внутриполосную регистрацию в файле ejabberd.cfg, поскольку по умолчанию она запрещена:

{access, register, [{allow, all}]}.

Наконец, здесь приведен пример кода для использования этого класса:

 private function registerChatUser($name, $password, $email) { $address = 'tcp://yourserverip:5222'; $adminUsername = 'youradmin'; $adminPassword = 'youradminpassword'; $options = new Options($address); $options->setUsername($adminUsername)->setPassword($adminPassword); $client = new Client($options); $client->connect(); $register = new Register($name, $password, $email); $client->send($register); $client->disconnect(); } 

Вызов библиотеки завершится неудачно, если у сервера нет действительного сертификата SSL. Либо поставьте действительный сертификат, либо замените эту часть в SocketClient.php нижеприведенным фрагментом

 // call stream_socket_client with custom error handler enabled $handler = new ErrorHandler( function ($address, $timeout, $flags) { $options = [ 'ssl' => [ 'allow_self_signed' => true, 'verify_peer_name' => false, ], ]; $context = stream_context_create($options); return stream_socket_client($address, $errno, $errstr, $timeout, $flags, $context); }, $this->address, $timeout, $flags ); 

Если вам нужен чистый и безопасный способ сделать это с помощью PHP в протоколе XMPP, я рекомендую работать с этим примером script register_user.php . Это пример, который можно найти в Jaxl PHP Library.

Загрузите библиотеку Jaxl и используйте следующую команду:

 JAXL $ php examples/register_user.php localhost Choose a username and password to register with this server username:test_user password:test_pass registration successful shutting down... JAXL $ 

Самый простой способ сделать это – использовать mod_xmlrpc – который позволяет запускать команды ejabberdctl с помощью xmlrpc. Это легко использовать с библиотекой, такой как:

https://github.com/gamenet/php-jabber-rpc

 /* Add user to Jabber */ use \GameNet\Jabber\RpcClient; use \GameNet\Jabber\Mixins\UserTrait; $rpc = new RpcClient([ 'server' => 'jabber.org:4560', 'host' => 'myhost.org', 'debug' => false, ]); $result=$rpc->createUser( $username, $password ); 

Я решил проблему с mod_register_web [ 1 , 2 ]. Он не требует тонны кода и, я думаю, достаточно безопасен. mod_register_web предоставляет html-страницу с простой формой POST для регистрации нового пользователя.

Включить модуль под отдельным HTTP-прослушивателем (в моем случае, порт 5281). Сделайте этот порт доступным только для локальных запросов с параметром «ip».

 listen: port: 5280 module: ejabberd_http web_admin: true http_bind: true ## register: true ip: "127.0.0.1" # Only local requests allowed for user registration port: 5281 module: ejabberd_http register: true modules: mod_register_web: {} 

Пример запроса:

 curl -XPOST 127.0.0.1:5281/register/new -d 'username=lucky&host=vHost&password=test&password2=test' 

Запрос может быть выполнен из php-кода с соответствующей библиотекой (которая уже была в моих рамках).

curl -XPOST 127.0.0.1:5281/api/register -d '{"user": "lucky", "host": "data.com", "password": "test"}'