Создать пользователя ejabberd из PHP - PullRequest
10 голосов
/ 26 октября 2009

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

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

Ответы [ 7 ]

10 голосов
/ 27 октября 2009

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

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

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

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

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

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

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

Осталось только код PHP:

<code><?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 '
'; } ?>

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

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

6 голосов
/ 29 января 2016

Я столкнулся с этим вопросом в 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, поскольку по умолчанию это запрещено:

{доступ, регистрация, [{разрешить, все}]}.

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

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
);
4 голосов
/ 26 октября 2009

ejabberdctl, безусловно, самый простой в этом конкретном случае. Другие варианты:

  • Реализация полного клиентского XMPP в PHP (!)

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

1 голос
/ 02 октября 2012

Если вам нужен чистый и безопасный способ сделать это с использованием PHP в протоколе XMPP, я рекомендую работать с этим примером сценария 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 $
0 голосов
/ 06 февраля 2017

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

0 голосов
/ 27 февраля 2016

Я решил проблему с 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 с соответствующей библиотекой (которая уже была в моей структуре).

0 голосов
/ 06 апреля 2015

Самый простой способ сделать это - использовать 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 );
...