Joomla: Add LDAP autocreate plugin support

- Introduced autocreate_users feature flag in config/main.yml
- Added ldapautocreate.php and ldapautocreate.xml plugin files
- Implemented tasks/01_ldap_files.yml for plugin deployment
- Added tasks/05_ldap.yml to configure LDAP plugin and register ldapautocreate
- Renamed tasks for better structure (01→02, 02→03, etc.)
- Updated cli-ldap.php.j2 for clean parameter handling
- Mounted ldapautocreate plugin via docker-compose.yml.j2
- Extended vars/main.yml with LDAP autocreate configuration

Ref: https://chatgpt.com/share/68b0802f-bfd4-800f-b10a-57cf0c091f7e
This commit is contained in:
2025-08-28 18:13:53 +02:00
parent 18f3b1042f
commit ef801aa498
15 changed files with 326 additions and 119 deletions

View File

@@ -1,54 +1,68 @@
<?php
// Tiny Joomla CLI to enable + configure Authentication - LDAP plugin.
// Safe to run multiple times.
// Joomla CLI script to enable and configure the Authentication - LDAP plugin.
// Safe to run multiple times. Uses only Factory::getDbo() (no web/administrator app context required).
define('_JEXEC', 1);
if (PHP_SAPI !== 'cli') { fwrite(STDERR, "CLI only\n"); exit(1); }
define('JPATH_BASE', __DIR__ . '/..');
$root = __DIR__ . '/..';
require $root . '/includes/defines.php';
require $root . '/includes/framework.php';
// Load Joomla framework
require JPATH_BASE . '/includes/defines.php';
require JPATH_BASE . '/includes/framework.php';
$app = \Joomla\CMS\Factory::getApplication('administrator');
$dbo = \Joomla\CMS\Factory::getDbo();
use Joomla\CMS\Factory;
// Database driver from Factory
$dbo = Factory::getDbo();
// Locate the LDAP plugin row in #__extensions
$query = $dbo->getQuery(true)
->select('*')
->from($dbo->quoteName('#__extensions'))
->where($dbo->quoteName('type') . ' = ' . $dbo->quote('plugin'))
->where($dbo->quoteName('folder') . ' = ' . $dbo->quote('authentication'))
->where($dbo->quoteName('element') . ' = ' . $dbo->quote('ldap'));
->select('*')
->from($dbo->quoteName('#__extensions'))
->where($dbo->quoteName('type') . ' = ' . $dbo->quote('plugin'))
->where($dbo->quoteName('folder') . ' = ' . $dbo->quote('authentication'))
->where($dbo->quoteName('element') . ' = ' . $dbo->quote('ldap'));
$dbo->setQuery($query);
$ext = $dbo->loadObject();
if (!$ext) { fwrite(STDERR, "LDAP plugin not found.\n"); exit(2); }
if (!$ext) {
fwrite(STDERR, "LDAP plugin not found.\n");
exit(2);
}
// Merge desired params
// Helper to strip quotes if present in env-file values
$get = static fn($k) => preg_replace('/^(["\'])(.*)\1$/', '$2', getenv($k) ?: '');
// Desired plugin parameters (must match Joomla LDAP plugin schema)
$desired = [
"host" => getenv('JOOMLA_LDAP_HOST'),
"port" => (int) getenv('JOOMLA_LDAP_PORT'),
"basedn" => getenv('JOOMLA_LDAP_BASE_DN'),
"userbasedn" => getenv('JOOMLA_LDAP_USER_TREE_DN'),
"groupbasedn" => getenv('JOOMLA_LDAP_GROUP_TREE_DN'),
"authmethod" => getenv('JOOMLA_LDAP_AUTH_METHOD'), // "bind" or "search"
"searchstring" => getenv('JOOMLA_LDAP_USER_SEARCH_STRING'),
"username" => getenv('JOOMLA_LDAP_BIND_DN'),
"password" => getenv('JOOMLA_LDAP_BIND_PASSWORD'),
"uid" => getenv('JOOMLA_LDAP_UID_ATTR'),
"email" => getenv('JOOMLA_LDAP_EMAIL_ATTR'),
"fullname" => getenv('JOOMLA_LDAP_NAME_ATTR'),
"starttls" => (bool) getenv('JOOMLA_LDAP_USE_STARTTLS'),
"ignore_reqcert" => (bool) getenv('JOOMLA_LDAP_IGNORE_CERT'),
"mapfullname" => (bool) getenv('JOOMLA_LDAP_MAP_FULLNAME'),
"mapemail" => (bool) getenv('JOOMLA_LDAP_MAP_EMAIL'),
// Connection settings
"host" => $get('JOOMLA_LDAP_HOST'),
"port" => (int) $get('JOOMLA_LDAP_PORT'),
"use_ldapV3" => true,
"negotiate_tls" => (bool) $get('JOOMLA_LDAP_USE_STARTTLS'),
"no_referrals" => false,
// Authentication settings
"auth_method" => $get('JOOMLA_LDAP_AUTH_METHOD') ?: "search", // "search" or "bind"
"base_dn" => $get('JOOMLA_LDAP_BASE_DN'),
"search_string" => $get('JOOMLA_LDAP_USER_SEARCH_STRING'), // e.g. uid=[username]
"users_dn" => $get('JOOMLA_LDAP_USER_TREE_DN'), // required for "bind" mode
"username" => $get('JOOMLA_LDAP_BIND_DN'),
"password" => $get('JOOMLA_LDAP_BIND_PASSWORD'),
// Attribute mapping
"ldap_uid" => $get('JOOMLA_LDAP_UID_ATTR') ?: "uid",
"ldap_email" => $get('JOOMLA_LDAP_EMAIL_ATTR') ?: "mail",
"ldap_fullname" => $get('JOOMLA_LDAP_NAME_ATTR') ?: "cn",
];
// Merge current parameters with desired values
$current = json_decode($ext->params ?: "{}", true) ?: [];
$merged = array_replace($current, array_filter($desired, fn($v) => $v !== null && $v !== ''));
$clean = array_filter($desired, static fn($v) => $v !== null && $v !== '');
$merged = array_replace($current, $clean);
// Save back to database and enable the plugin
$ext->params = json_encode($merged, JSON_UNESCAPED_SLASHES);
$ext->enabled = {{ JOOMLA_LDAP_ENABLED | ternary(1, 0) }};
$ext->enabled = 1;
$dbo->updateObject('#__extensions', $ext, 'extension_id');
echo "LDAP plugin enabled=". $ext->enabled . " and configured.\n";
echo "LDAP plugin enabled={$ext->enabled} and configured.\n";

View File

@@ -11,6 +11,9 @@
- data:/var/www/html
{% if JOOMLA_LDAP_ENABLED %}
- {{ JOOMLA_LDAP_CONF_FILE }}:/var/www/html/cli/cli-ldap.php:ro
{% if JOOMLA_LDAP_AUTO_CREATE_ENABLED | bool %}
- {{ JOOMLA_LDAP_AUT_CRT_HOST_DIR }}:{{ JOOMLA_LDAP_AUT_CRT_DOCK_DIR }}:ro
{% endif %}
{% endif %}
ports:
- "127.0.0.1:{{ ports.localhost.http[application_id] }}:{{ container_port }}"

View File

@@ -6,29 +6,29 @@ JOOMLA_ADMIN_EMAIL={{ JOOMLA_USER_EMAIL }}
{% if database_type == 'mariadb' %}
# Database
JOOMLA_DB_HOST="{{ database_host }}:{{ database_port }}"
JOOMLA_DB_USER="{{ database_username }}"
JOOMLA_DB_PASSWORD="{{ database_password }}"
JOOMLA_DB_NAME="{{ database_name }}"
JOOMLA_DB_TYPE="{{ JOOMLA_DB_CONNECTOR }}"
JOOMLA_DB_HOST={{ database_host }}:{{ database_port }}
JOOMLA_DB_USER={{ database_username }}
JOOMLA_DB_PASSWORD={{ database_password }}
JOOMLA_DB_NAME={{ database_name }}
JOOMLA_DB_TYPE={{ JOOMLA_DB_CONNECTOR }}
{% endif %}
{% if JOOMLA_LDAP_ENABLED %}
# LDAP
JOOMLA_LDAP_HOST="{{ JOOMLA_LDAP_HOST }}"
JOOMLA_LDAP_PORT="{{ JOOMLA_LDAP_PORT }}"
JOOMLA_LDAP_BASE_DN="{{ JOOMLA_LDAP_BASE_DN }}"
JOOMLA_LDAP_USER_TREE_DN="{{ JOOMLA_LDAP_USER_TREE_DN }}"
JOOMLA_LDAP_GROUP_TREE_DN="{{ JOOMLA_LDAP_GROUP_TREE_DN }}"
JOOMLA_LDAP_UID_ATTR="{{ JOOMLA_LDAP_UID_ATTR }}"
JOOMLA_LDAP_EMAIL_ATTR="{{ JOOMLA_LDAP_EMAIL_ATTR }}"
JOOMLA_LDAP_NAME_ATTR="{{ JOOMLA_LDAP_NAME_ATTR }}"
JOOMLA_LDAP_BIND_DN="{{ JOOMLA_LDAP_BIND_DN }}"
JOOMLA_LDAP_BIND_PASSWORD="{{ JOOMLA_LDAP_BIND_PASSWORD }}"
JOOMLA_LDAP_USE_STARTTLS="{{ JOOMLA_LDAP_USE_STARTTLS | ternary('1','') }}"
JOOMLA_LDAP_IGNORE_CERT="{{ JOOMLA_LDAP_IGNORE_CERT | ternary('1','') }}"
JOOMLA_LDAP_MAP_FULLNAME="{{ JOOMLA_LDAP_MAP_FULLNAME | ternary('1','') }}"
JOOMLA_LDAP_MAP_EMAIL="{{ JOOMLA_LDAP_MAP_EMAIL | ternary('1','') }}"
JOOMLA_LDAP_AUTH_METHOD="{{ JOOMLA_LDAP_AUTH_METHOD }}"
JOOMLA_LDAP_USER_SEARCH_STRING="{{ JOOMLA_LDAP_USER_SEARCH_STRING }}"
JOOMLA_LDAP_HOST={{ JOOMLA_LDAP_HOST }}
JOOMLA_LDAP_PORT={{ JOOMLA_LDAP_PORT }}
JOOMLA_LDAP_BASE_DN={{ JOOMLA_LDAP_BASE_DN }}
JOOMLA_LDAP_USER_TREE_DN={{ JOOMLA_LDAP_USER_TREE_DN }}
JOOMLA_LDAP_GROUP_TREE_DN={{ JOOMLA_LDAP_GROUP_TREE_DN }}
JOOMLA_LDAP_UID_ATTR={{ JOOMLA_LDAP_UID_ATTR }}
JOOMLA_LDAP_EMAIL_ATTR={{ JOOMLA_LDAP_EMAIL_ATTR }}
JOOMLA_LDAP_NAME_ATTR={{ JOOMLA_LDAP_NAME_ATTR }}
JOOMLA_LDAP_BIND_DN={{ JOOMLA_LDAP_BIND_DN }}
JOOMLA_LDAP_BIND_PASSWORD={{ JOOMLA_LDAP_BIND_PASSWORD }}
JOOMLA_LDAP_USE_STARTTLS={{ JOOMLA_LDAP_USE_STARTTLS | ternary('1','') }}
JOOMLA_LDAP_IGNORE_CERT={{ JOOMLA_LDAP_IGNORE_CERT | ternary('1','') }}
JOOMLA_LDAP_MAP_FULLNAME={{ JOOMLA_LDAP_MAP_FULLNAME | ternary('1','') }}
JOOMLA_LDAP_MAP_EMAIL={{ JOOMLA_LDAP_MAP_EMAIL | ternary('1','') }}
JOOMLA_LDAP_AUTH_METHOD={{ JOOMLA_LDAP_AUTH_METHOD }}
JOOMLA_LDAP_USER_SEARCH_STRING={{ JOOMLA_LDAP_USER_SEARCH_STRING }}
{% endif %}