From 50c440bd8ca81e3333ac1cddf64d3a5bfeea88b8 Mon Sep 17 00:00:00 2001 From: pooneyy <85266337+pooneyy@users.noreply.github.com> Date: Sun, 25 Jan 2026 21:47:29 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(phpLDAPadmin):=20add=20phpLDAP?= =?UTF-8?q?admin=20application?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - add version-specific data.yml with form fields for HTTP port, LDAP server, LDAP port, LDAP baseDN, admin credentials, and timezone configuration - add docker-compose.yml for container deployment with environment variable mapping and volume mounts - add init.sh script for directory creation and APP_KEY generation - add README.md and README_en.md with product introduction and feature descriptions - add root data.yml with application metadata, tags, and architecture support - add logo.png --- apps/phpldapadmin/2.3.8/data.yml | 157 +++++++++++++++++++++ apps/phpldapadmin/2.3.8/docker-compose.yml | 28 ++++ apps/phpldapadmin/2.3.8/scripts/init.sh | 12 ++ apps/phpldapadmin/README.md | 11 ++ apps/phpldapadmin/README_en.md | 11 ++ apps/phpldapadmin/data.yml | 30 ++++ apps/phpldapadmin/logo.png | Bin 0 -> 8308 bytes 7 files changed, 249 insertions(+) create mode 100644 apps/phpldapadmin/2.3.8/data.yml create mode 100644 apps/phpldapadmin/2.3.8/docker-compose.yml create mode 100644 apps/phpldapadmin/2.3.8/scripts/init.sh create mode 100644 apps/phpldapadmin/README.md create mode 100644 apps/phpldapadmin/README_en.md create mode 100644 apps/phpldapadmin/data.yml create mode 100644 apps/phpldapadmin/logo.png diff --git a/apps/phpldapadmin/2.3.8/data.yml b/apps/phpldapadmin/2.3.8/data.yml new file mode 100644 index 000000000..90981a950 --- /dev/null +++ b/apps/phpldapadmin/2.3.8/data.yml @@ -0,0 +1,157 @@ +additionalProperties: + formFields: + - default: 8080 + envKey: PANEL_APP_PORT_HTTP + labelZh: HTTP 端口 + labelEn: HTTP Port + label: + en: HTTP Port + ja: HTTP ポート + ko: HTTP 포트 + ms: Port HTTP + pt-br: Porta HTTP + ru: HTTP Порт + tr: HTTP Portu + zh: HTTP 端口 + zh-Hant: HTTP 連接埠 + description: + en: "Set the HTTP access port for the application, valid range: 1-65535" + ja: "アプリケーションのHTTPアクセスポートを設定します。有効範囲: 1-65535" + ko: "애플리케이션의 HTTP 접근 포트를 설정합니다. 유효 범위: 1-65535" + ms: "Tetapkan port akses HTTP untuk aplikasi, julat sah: 1-65535" + pt-br: "Defina a porta de acesso HTTP para o aplicativo, intervalo válido: 1-65535" + ru: "Установите порт доступа HTTP для приложения, допустимый диапазон: 1-65535" + tr: "Uygulama için HTTP erişim portunu ayarlayın, geçerli aralık: 1-65535" + zh: "设置应用的 HTTP 访问端口,有效范围: 1-65535" + zh-Hant: "設定應用程式的 HTTP 存取連接埠,有效範圍: 1-65535" + required: true + type: number + edit: true + rule: paramPort + - default: my.ldap.server.org + envKey: LDAP_HOST + labelZh: LDAP 服务器 + labelEn: LDAP Server + label: + zh: LDAP 服务器 + zh-Hant: LDAP 伺服器 + en: LDAP Server + ja: LDAP サーバー + ko: LDAP 서버 + ms: Pelayan LDAP + pt-br: Servidor LDAP + ru: LDAP-сервер + tr: LDAP Sunucusu + description: + zh: 一个可解析的主机名,指向您的 LDAP 服务器,或 LDAP 服务器的 IP 地址 + zh-Hant: 一個可解析的主機名稱,指向您的 LDAP 伺服器,或 LDAP 伺服器的 IP 位址 + en: A resolvable hostname that points to your LDAP server, or the IP address of the LDAP server + ja: LDAPサーバーを指す解決可能なホスト名、またはLDAPサーバーのIPアドレス + ko: LDAP 서버를 가리키는 확인 가능한 호스트명 또는 LDAP 서버의 IP 주소 + ms: Satu nama hos yang boleh diselesaikan yang menunjuk ke pelayan LDAP anda, atau alamat IP pelayan LDAP + pt-br: Um nome de host resolvível que aponta para seu servidor LDAP, ou o endereço IP do servidor LDAP + ru: Разрешаемое имя хоста, указывающее на ваш LDAP-сервер, или IP-адрес LDAP-сервера + tr: LDAP sunucunuzu işaret eden çözümlenebilir bir ana bilgisayar adı veya LDAP sunucusunun IP adresi + required: true + type: text + edit: true + - default: 389 + envKey: LDAP_PORT + labelZh: LDAP 服务端口 + labelEn: LDAP Service Port + label: + zh: LDAP 服务端口 + zh-Hant: LDAP 伺服器的通訊埠 + en: LDAP Service Port + ja: LDAP サービスポート + ko: LDAP 서비스 포트 + ms: Port Perkhidmatan LDAP + pt-br: Porta do Serviço LDAP + ru: Порт службы LDAP + tr: LDAP Servis Bağlantı Noktası + description: + zh: 如果您的 LDAP 服务器使用非标准端口,或启用了 SSL 的端口,则可能需要更改此设置。 + zh-Hant: 如果您的 LDAP 伺服器使用非標準埠,或啟用了 SSL 的埠,則可能需要更改此設定。 + en: You may need to change this if your LDAP server on a non-standard port, or a SSL enabled port + ja: LDAPサーバーが非標準ポートまたはSSLが有効なポートを使用している場合、これを変更する必要があるかもしれません。 + ko: LDAP 서버가 비표준 포트 또는 SSL 활성화 포트를 사용하는 경우 이를 변경해야 할 수 있습니다. + ms: Anda mungkin perlu menukar ini jika pelayan LDAP anda berada di port bukan standard, atau port yang didayakan SSL. + pt-br: Você pode precisar alterar isso se seu servidor LDAP estiver em uma porta não padrão ou em uma porta com SSL habilitado. + ru: Возможно, вам потребуется изменить это, если ваш LDAP-сервер использует нестандартный порт или порт с поддержкой SSL. + tr: LDAP sunucunuz standart olmayan bir bağlantı noktasında veya SSL etkin bir bağlantı noktasındaysa, bunu değiştirmeniz gerekebilir. + required: true + type: number + edit: true + rule: paramPort + - default: dc=example,dc=org + envKey: LDAP_BASE_DN + labelZh: LDAP baseDN + labelEn: LDAP baseDN + label: + zh: LDAP baseDN + en: LDAP baseDN + required: true + type: text + edit: true + - default: cn=admin,dc=example,dc=org + envKey: LDAP_ADMIN_USERNAME + labelZh: 用于连接 LDAP 服务器的身份验证 DN + labelEn: Authentication DN to connect to LDAP server + label: + zh: 用于连接 LDAP 服务器的身份验证 DN + zh-Hant: 用於連接 LDAP 伺服器的身份驗證 DN + en: Authentication DN to connect to LDAP server + ja: LDAPサーバー接続用の認証DN + ko: LDAP 서버 연결용 인증 DN + ms: DN Pengesahan untuk menyambung ke pelayan LDAP + pt-br: DN de Autenticação para conectar ao servidor LDAP + ru: DN аутентификации для подключения к LDAP-серверу + tr: LDAP sunucusuna bağlanmak için Kimlik Doğrulama DN'si + required: true + type: text + edit: true + - default: "" + envKey: LDAP_ADMIN_PASSWORD + labelZh: LDAP 服务器密码 + labelEn: Password for LDAP server + label: + zh: LDAP 服务器密码 + zh-Hant: LDAP 伺服器密碼 + en: Password for LDAP server + ja: LDAPサーバーのパスワード + ko: LDAP 서버 비밀번호 + ms: Kata laluan untuk pelayan LDAP + pt-br: Senha do servidor LDAP + ru: Пароль для LDAP-сервера + tr: LDAP sunucusu parolası + required: true + type: password + edit: true + rule: paramComplexity + - default: Etc/UTC + envKey: APP_TIMEZONE + labelZh: 时区 + labelEn: Time Zone + label: + zh: 时区 + zh-Hant: 時區 + en: Time Zone + ja: タイムゾーン + ko: 시간대 + ms: Zon Waktu + pt-br: Fuso Horário + ru: Часовой пояс + tr: Saat Dilimi + description: + zh: 此时区主要用于日志记录 + zh-Hant: 此時區主要用於日誌記錄 + en: This timezone used, mostly for, logging. + ja: このタイムゾーンは、主にログ記録に使用されます + ko: 이 시간대는 주로 로깅에 사용됩니다 + ms: Zon waktu ini digunakan, kebanyakannya untuk, pembuatan log. + pt-br: Este fuso horário é usado, principalmente, para registro de logs. + ru: Этот часовой пояс используется, в основном, для ведения журналов. + tr: Bu saat dilimi, çoğunlukla günlük kaydı için kullanılır. + required: false + type: text + edit: true diff --git a/apps/phpldapadmin/2.3.8/docker-compose.yml b/apps/phpldapadmin/2.3.8/docker-compose.yml new file mode 100644 index 000000000..c8b1fce54 --- /dev/null +++ b/apps/phpldapadmin/2.3.8/docker-compose.yml @@ -0,0 +1,28 @@ +services: + phpldapadmin: + image: phpldapadmin/phpldapadmin:2.3.8 + container_name: ${CONTAINER_NAME} + restart: unless-stopped + ports: + - ${PANEL_APP_PORT_HTTP}:8080 + environment: + - LDAP_BASE_DN=${LDAP_BASE_DN} + - LDAP_HOST=${LDAP_HOST} + - LDAP_PORT=${LDAP_PORT} + - LDAP_USERNAME=${LDAP_ADMIN_USERNAME} + - LDAP_PASSWORD=${LDAP_ADMIN_PASSWORD} + - APP_KEY=${APP_KEY} + - APP_TIMEZONE=${APP_TIMEZONE} + - LDAP_CACHE=true + - CACHE_DRIVER=file + - SERVER_NAME=:8080 + volumes: + - ./logs:/app/storage/logs + - ./sessions:/app/storage/framework/sessions + networks: + - 1panel-network + labels: + createdBy: Apps +networks: + 1panel-network: + external: true diff --git a/apps/phpldapadmin/2.3.8/scripts/init.sh b/apps/phpldapadmin/2.3.8/scripts/init.sh new file mode 100644 index 000000000..d4655f4ec --- /dev/null +++ b/apps/phpldapadmin/2.3.8/scripts/init.sh @@ -0,0 +1,12 @@ +mkdir -p logs sessions +chmod -R 777 logs sessions +APP_KEY=$(echo "base64:$(head -c 32 /dev/urandom | base64)") +if grep -q "APP_KEY=" .env; then + if [[ "$(uname)" == "Darwin" ]]; then + sed -i '' "s/APP_KEY=.*/APP_KEY=$APP_KEY/" .env + else + sed -i "s/APP_KEY=.*/APP_KEY=$APP_KEY/" .env + fi +else + echo "APP_KEY=$APP_KEY" >> .env +fi \ No newline at end of file diff --git a/apps/phpldapadmin/README.md b/apps/phpldapadmin/README.md new file mode 100644 index 000000000..62132f602 --- /dev/null +++ b/apps/phpldapadmin/README.md @@ -0,0 +1,11 @@ +## 产品介绍 + +phpLDAPadmin(简称PLA)是一个基于Web的LDAP数据管理工具,专为系统管理员设计。该项目遵循LDAP RFC标准,可与任何兼容的LDAP服务器配合使用,提供直观的图形界面来管理LDAP目录数据。 + +## 主要功能 + +- **LDAP数据管理**:通过Web界面执行LDAP目录的浏览、添加、删除、修改等操作,支持属性编辑、对象类管理,无需命令行即可完成日常目录维护任务。 +- **多LDAP服务器兼容**:原生支持OpenLDAP、OpenDJ、389 Directory Server、Apache DS等主流LDAP服务器,计划未来支持Microsoft Active Directory,具备良好的跨平台兼容性。 +- **JSON模板引擎**:从v2.2版本开始引入基于JSON格式的模板系统,允许管理员自定义对象类和属性模板,简化重复性配置工作,支持自定义模板目录避免升级覆盖。 +- **Docker容器化部署**:提供官方Docker镜像,简化安装和配置过程,支持快速部署和测试,确保环境一致性,降低部署复杂度。 +- **国际化与翻译支持**:内置多语言界面框架,允许社区贡献翻译文件,使工具能够适配不同语言环境的管理员使用需求。 \ No newline at end of file diff --git a/apps/phpldapadmin/README_en.md b/apps/phpldapadmin/README_en.md new file mode 100644 index 000000000..b3f3d89ee --- /dev/null +++ b/apps/phpldapadmin/README_en.md @@ -0,0 +1,11 @@ +## Product Introduction + +phpLDAPadmin (PLA) is a web-based LDAP data management tool designed specifically for system administrators. The project adheres to LDAP RFC standards and can work with any compatible LDAP server, providing an intuitive graphical interface for managing LDAP directory data. + +## Main Features + +- **LDAP Data Management**: Perform operations such as browsing, adding, deleting, and modifying LDAP directories through a web interface, supporting attribute editing and object class management, enabling daily directory maintenance tasks without the need for command-line interaction. +- **Multi-LDAP Server Compatibility**: Natively supports mainstream LDAP servers such as OpenLDAP, OpenDJ, 389 Directory Server, and Apache DS, with Microsoft Active Directory scheduled for future support, offering excellent cross-platform compatibility. +- **JSON Template Engine**: Introduced in v2.2, a JSON-based template system allows administrators to customize object classes and attribute templates, streamlining repetitive configuration tasks, while supporting custom template directories to avoid overwriting during upgrades. +- **Docker Containerized Deployment**: Provides official Docker images to simplify installation and configuration processes, enabling rapid deployment and testing, ensuring environment consistency, and reducing deployment complexity. +- **Internationalization and Translation Support**: Built-in multi-language interface framework allows community contributions to translation files, enabling the tool to adapt to the usage needs of administrators in different language environments. \ No newline at end of file diff --git a/apps/phpldapadmin/data.yml b/apps/phpldapadmin/data.yml new file mode 100644 index 000000000..53c642314 --- /dev/null +++ b/apps/phpldapadmin/data.yml @@ -0,0 +1,30 @@ +name: phpLDAPadmin +tags: + - 数据库 +title: 基于 Web 的 LDAP 数据管理工具 +description: 基于 Web 的 LDAP 数据管理工具 +additionalProperties: + key: phpldapadmin + name: phpLDAPadmin + tags: + - Database + shortDescZh: 基于 Web 的 LDAP 数据管理工具 + shortDescEn: Web based LDAP data management tool + description: + en: Web based LDAP data management tool + zh: 基于 Web 的 LDAP 数据管理工具 + zh-Hant: 基於 Web 的 LDAP 資料管理工具 + ja: WebベースのLDAPデータ管理ツール + ms: Alat pengurusan data LDAP berasaskan Web + pt-br: Ferramenta de gerenciamento de dados LDAP baseada na Web + ru: Веб-инструмент управления данными LDAP + ko: 웹 기반 LDAP 데이터 관리 도구 + type: website + crossVersionUpdate: true + limit: 0 + website: https://github.com/leenooks/phpLDAPadmin + github: https://github.com/leenooks/phpLDAPadmin + document: https://github.com/leenooks/phpLDAPadmin + architectures: + - amd64 + - arm64 diff --git a/apps/phpldapadmin/logo.png b/apps/phpldapadmin/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc81610017c13ac8f5a971d7799cfda340eb7ea GIT binary patch literal 8308 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 F{SWgc7ia(g literal 0 HcmV?d00001