Как добавить автоматическую подстановку доменов при входе в Roundcube

Тип статьи:
Авторская

Для реализации подобного алгоритма нужно создать отдельный каталог для плагина. В данном примере roundcube лежит по пути /var/www/html/webmail, если у вас другой — отредактируйте под себя.

  1. sudo mkdir /var/www/html/webmail/plugins/login_autocomplete/

Создаем файл конфигурации

  1. sudo nano /var/www/html/webmail/plugins/login_autocomplete/login_autocomplete.php

Со следующим содержимым

  1. <?php
  2.  
  3. class login_autocomplete extends rcube_plugin
  4. {
  5. public $task = 'login';
  6.  
  7. // =========================================================================
  8. // НАСТРОЙКИ ПЛАГИНА
  9. // =========================================================================
  10.  
  11. //Запрещать домены, которых нет в списке
  12. private $restrict_domains = true;
  13.  
  14. //Включить логи. Используется путь записи логов из переменной $config['log_dir']
  15. private $enable_logging = true;
  16.  
  17. //Название лога
  18. private $log_filename = 'autocomplete_auth.log';
  19.  
  20. //Список доменов
  21. private $allowed_domains = ['domain1.tld', 'domain2.tld'];
  22. // =========================================================================
  23.  
  24. public function init()
  25. {
  26. $this->add_hook('authenticate', [$this, 'validate_login_domain']);
  27.  
  28. $this->add_hook('template_object_loginform', [$this, 'login_form_modify']);
  29. }
  30.  
  31. public function validate_login_domain($args)
  32. {
  33. $user_email = trim($args['user']);
  34.  
  35. if (!$this->restrict_domains) {
  36. $this->log_action($user_email, 'ALLOWED (Control disabled)');
  37. return $args;
  38. }
  39.  
  40. if (strpos($user_email, '@') !== false) {
  41. $parts = explode('@', $user_email);
  42. $user_domain = strtolower(end($parts));
  43.  
  44. if (!in_array($user_domain, $this->allowed_domains)) {
  45.  
  46. $this->log_action($user_email, 'BLOCKED (Unauthorized domain)');
  47.  
  48. $rcmail = rcube::get_instance();
  49. unset($_SESSION['login_error']);
  50.  
  51. $rcmail->output->show_message('Вход с этого почтового домена запрещен администратором', 'error');
  52.  
  53. $args['abort'] = false;
  54. $args['pass'] = '';
  55.  
  56. if ($rcmail->output->ajax_request) {
  57. $rcmail->output->send();
  58. exit;
  59. }
  60.  
  61. $rcmail->output->send('login');
  62. exit;
  63. }
  64. }
  65.  
  66. $this->log_action($user_email, 'ALLOWED (Domain check passed)');
  67.  
  68. return $args;
  69. }
  70.  
  71. private function log_action($user, $status)
  72. {
  73. if (!$this->enable_logging) return;
  74.  
  75. $rcmail = rcube::get_instance();
  76. $log_dir = rtrim($rcmail->config->get('log_dir', RCUBE_INSTALL_PATH . 'logs'), '/\\');
  77. $log_file = $log_dir . DIRECTORY_SEPARATOR . $this->log_filename;
  78.  
  79. $ip = rcube_utils::remote_addr();
  80. $date = date('Y-m-d H:i:s');
  81. $log_line = sprintf("[%s]: %s -> %s (IP: %s)\n", $date, $user, $status, $ip);
  82.  
  83. if ($fp = @fopen($log_file, 'a')) {
  84. @fwrite($fp, $log_line);
  85. @fflush($fp);
  86. @fclose($fp);
  87. }
  88. }
  89.  
  90. public function login_form_modify($args)
  91. {
  92. $domains_json = json_encode($this->allowed_domains);
  93.  
  94. $styles = "
  95. <style>
  96. .rc-autocomplete-container { position: relative; width: 100%; }
  97. .rc-autocomplete-list {
  98. position: absolute; top: 100%; left: 0; z-index: 9999; width: 100%;
  99. background: #ffffff; border: 1px solid #cbd5e1; border-radius: 4px;
  100. box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1); max-height: 200px;
  101. overflow-y: auto; margin-top: 2px; padding: 0; list-style: none; display: none;
  102. }
  103. .rc-autocomplete-item { padding: 10px 14px; cursor: pointer; color: #334155; font-size: 14px; text-align: left; }
  104. .rc-autocomplete-item:hover { background: #f1f5f9; color: #0284c7; }
  105. </style>";
  106.  
  107. $script = "
  108. <script>
  109. (function() {
  110. var baseDomains = {$domains_json};
  111. var checkInput = setInterval(function() {
  112. var userInput = document.getElementById('rcmloginuser');
  113. if (userInput) {
  114. clearInterval(checkInput);
  115. userInput.setAttribute('autocomplete', 'new-password');
  116.  
  117. var wrapper = document.createElement('div');
  118. wrapper.className = 'rc-autocomplete-container';
  119. userInput.parentNode.insertBefore(wrapper, userInput);
  120. wrapper.appendChild(userInput);
  121.  
  122. var listContainer = document.createElement('ul');
  123. listContainer.className = 'rc-autocomplete-list';
  124. wrapper.appendChild(listContainer);
  125.  
  126. function renderSuggestions() {
  127. var val = userInput.value.trim();
  128. if (val.length === 0 || val.includes('@')) {
  129. listContainer.style.display = 'none';
  130. return;
  131. }
  132. listContainer.innerHTML = '';
  133. baseDomains.forEach(function(domain) {
  134. var li = document.createElement('li');
  135. li.className = 'rc-autocomplete-item';
  136. li.textContent = val + '@' + domain;
  137. li.addEventListener('click', function() {
  138. userInput.value = val + '@' + domain;
  139. listContainer.style.display = 'none';
  140. userInput.focus();
  141. });
  142. listContainer.appendChild(li);
  143. });
  144. listContainer.style.display = 'block';
  145. }
  146.  
  147. userInput.addEventListener('input', renderSuggestions);
  148. document.addEventListener('click', function(e) {
  149. if (e.target !== userInput) listContainer.style.display = 'none';
  150. });
  151. }
  152. }, 50);
  153. })();
  154. </script>";
  155.  
  156. $args['content'] .= $styles . $script;
  157. return $args;
  158. }
  159. }

Для корректной работы скрипта необходимо убедиться, что у web-сервера (Nginx, Apache и т.п.) есть права на папку с плагином и файл конфигурации. Для Debian/Ubuntu права можно задать следующим образом:

  1. sudo chown -R www-data:www-data /var/www/html/webmail/plugins/login_autocomplete/

где

  •  /var/www/html/webmail/plugins/login_autocomplete/ — путь к папке плагина.
  • www-data — имя пользователя веб-сервера.

Редактируем

  1. sudo nano /var/www/html/webmail/config/config.inc.php

Дописывая в список плагинов login_autocomplete

  1. $config['plugins'] = [
  2. //Прочие плагины
  3. //...
  4. 'login_autocomplete',
  5. ];

Работа данного плагина тестировалась в версиях roundcube 1.7.x.

72
Посещая этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.