Merge branch 'main' into feature/avatar-display

This commit is contained in:
Austin 2023-03-29 16:00:51 +00:00
commit cbc6c87d48
16 changed files with 367 additions and 73 deletions

View File

@ -2,6 +2,7 @@
.git/* .git/*
.github/* .github/*
.gitignore .gitignore
.gitattributes
# Don't track cargo generated files # Don't track cargo generated files
target/* target/*
@ -17,6 +18,7 @@ Dockerfile
*.md *.md
LICENSE LICENSE
CHANGELOG.md CHANGELOG.md
README.md
docs/* docs/*
example_configs/* example_configs/*

10
.gitattributes vendored Normal file
View File

@ -0,0 +1,10 @@
example-configs/** linguist-documentation
docs/** linguist-documentation
*.md linguist-documentation
lldap_config.docker_template.toml linguist-documentation
schema.graphql linguist-generated
.github/** -linguist-detectable
.devcontainer/** -linguist-detectable
.config/** -linguist-detectable

View File

@ -4,12 +4,18 @@ on:
push: push:
branches: branches:
- 'main' - 'main'
paths-ignore:
- 'docs/**'
- 'example_configs/**'
release: release:
types: types:
- 'published' - 'published'
pull_request: pull_request:
branches: branches:
- 'main' - 'main'
paths-ignore:
- 'docs/**'
- 'example_configs/**'
workflow_dispatch: workflow_dispatch:
inputs: inputs:
msg: msg:
@ -60,13 +66,30 @@ env:
# cache based on Cargo.lock per cargo target # cache based on Cargo.lock per cargo target
jobs: jobs:
pre_job:
continue-on-error: true
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@master
with:
concurrent_skipping: 'outdated_runs'
skip_after_successful_duplicate: ${{ github.ref != 'refs/heads/main' }}
paths_ignore: '["**/*.md", "**/docs/**", "example_configs/**", "*.sh", ".gitignore", "lldap_config.docker_template.toml"]'
do_not_skip: '["workflow_dispatch", "schedule"]'
cancel_others: true
build-ui: build-ui:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre_job
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
container: container:
image: nitnelave/rust-dev:latest image: nitnelave/rust-dev:latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |
@ -99,6 +122,8 @@ jobs:
build-bin: build-bin:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre_job
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
strategy: strategy:
matrix: matrix:
target: [armv7-unknown-linux-gnueabihf, aarch64-unknown-linux-musl, x86_64-unknown-linux-musl] target: [armv7-unknown-linux-gnueabihf, aarch64-unknown-linux-musl, x86_64-unknown-linux-musl]
@ -113,7 +138,7 @@ jobs:
CARGO_HOME: ${GITHUB_WORKSPACE}/.cargo CARGO_HOME: ${GITHUB_WORKSPACE}/.cargo
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- uses: actions/cache@v3 - uses: actions/cache@v3
with: with:
path: | path: |
@ -145,9 +170,9 @@ jobs:
name: ${{ matrix.target }}-lldap_set_password-bin name: ${{ matrix.target }}-lldap_set_password-bin
path: target/${{ matrix.target }}/release/lldap_set_password path: target/${{ matrix.target }}/release/lldap_set_password
lldap-database-integration-test: lldap-database-init-test:
needs: [build-ui,build-bin] needs: [build-ui,build-bin]
name: LLDAP test name: LLDAP database init test
runs-on: ubuntu-latest runs-on: ubuntu-latest
services: services:
mariadb: mariadb:
@ -159,6 +184,7 @@ jobs:
MYSQL_PASSWORD: lldappass MYSQL_PASSWORD: lldappass
MYSQL_DATABASE: lldap MYSQL_DATABASE: lldap
MYSQL_ROOT_PASSWORD: rootpass MYSQL_ROOT_PASSWORD: rootpass
options: --name mariadb
postgresql: postgresql:
image: postgres:latest image: postgres:latest
@ -168,6 +194,7 @@ jobs:
POSTGRES_USER: lldapuser POSTGRES_USER: lldapuser
POSTGRES_PASSWORD: lldappass POSTGRES_PASSWORD: lldappass
POSTGRES_DB: lldap POSTGRES_DB: lldap
options: --name postgresql
steps: steps:
- name: Download artifacts - name: Download artifacts
@ -175,8 +202,7 @@ jobs:
with: with:
name: x86_64-unknown-linux-musl-lldap-bin name: x86_64-unknown-linux-musl-lldap-bin
path: bin/ path: bin/
- name: Where is the bin?
run: ls -alR bin
- name: Set executables to LLDAP - name: Set executables to LLDAP
run: chmod +x bin/lldap run: chmod +x bin/lldap
@ -212,6 +238,188 @@ jobs:
LLDAP_ldap_port: 3892 LLDAP_ldap_port: 3892
LLDAP_http_port: 17172 LLDAP_http_port: 17172
- name: Check DB container logs
run: |
docker logs -n 20 mariadb
docker logs -n 20 postgresql
lldap-database-migration-test:
needs: [build-ui,build-bin]
name: LLDAP database migration test
runs-on: ubuntu-latest
services:
postgresql:
image: postgres:latest
ports:
- 5432:5432
env:
POSTGRES_USER: lldapuser
POSTGRES_PASSWORD: lldappass
POSTGRES_DB: lldap
options: --name postgresql
mariadb:
image: mariadb:latest
ports:
- 3306:3306
env:
MYSQL_USER: lldapuser
MYSQL_PASSWORD: lldappass
MYSQL_DATABASE: lldap
MYSQL_ROOT_PASSWORD: rootpass
options: --name mariadb
mysql:
image: mysql:latest
ports:
- 3307:3306
env:
MYSQL_USER: lldapuser
MYSQL_PASSWORD: lldappass
MYSQL_DATABASE: lldap
MYSQL_ROOT_PASSWORD: rootpass
options: --name mysql
steps:
- name: Download LLDAP artifacts
uses: actions/download-artifact@v3
with:
name: x86_64-unknown-linux-musl-lldap-bin
path: bin/
- name: Download LLDAP set password
uses: actions/download-artifact@v3
with:
name: x86_64-unknown-linux-musl-lldap_set_password-bin
path: bin/
- name: Set executables to LLDAP and LLDAP set password
run: |
chmod +x bin/lldap
chmod +x bin/lldap_set_password
- name: Install sqlite3 and ldap-utils for exporting and searching dummy user
run: sudo apt update && sudo apt install -y sqlite3 ldap-utils
- name: Run lldap with sqlite DB and healthcheck
run: |
bin/lldap run &
sleep 10s
bin/lldap healthcheck
env:
LLDAP_database_url: sqlite://users.db?mode=rwc
LLDAP_ldap_port: 3890
LLDAP_http_port: 17170
LLDAP_LDAP_USER_PASS: ldappass
LLDAP_JWT_SECRET: somejwtsecret
- name: Create dummy user
run: |
TOKEN=$(curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "ldappass"}' http://localhost:17170/auth/simple/login | cut -c 11-277)
echo "$TOKEN"
curl 'http://localhost:17170/api/graphql' -H 'Content-Type: application/json' -H "Authorization: Bearer ${TOKEN//[$'\t\r\n ']}" --data-binary '{"query":"mutation{\n createUser(user:\n {\n id: \"dummyuser\",\n email: \"dummyuser@example.com\"\n }\n )\n {\n id\n email\n }\n}\n\n\n"}' --compressed
bin/lldap_set_password --base-url http://localhost:17170 --admin-username admin --admin-password ldappass --token $TOKEN --username dummyuser --password dummypassword
- name: Test Dummy User, This will be checked again after importing
run: |
ldapsearch -H ldap://localhost:3890 -LLL -D "uid=dummyuser,ou=people,dc=example,dc=com" -w 'dummypassword' -s "One" -b "ou=people,dc=example,dc=com"
- name: Stop LLDAP sqlite
run: pkill lldap
- name: Export and Converting to Postgress
run: |
curl -L https://raw.githubusercontent.com/nitnelave/lldap/main/scripts/sqlite_dump_commands.sh -o helper.sh
chmod +x ./helper.sh
./helper.sh | sqlite3 ./users.db > ./dump.sql
sed -i -r -e "s/X'([[:xdigit:]]+'[^'])/'\\\x\\1/g" -e '1s/^/BEGIN;\n/' -e '$aCOMMIT;' ./dump.sql
- name: Create schema on postgres
run: |
bin/lldap create_schema -d postgres://lldapuser:lldappass@localhost:5432/lldap
- name: Copy converted db to postgress and import
run: |
docker ps -a
docker cp ./dump.sql postgresql:/tmp/dump.sql
docker exec postgresql bash -c "psql -U lldapuser -d lldap < /tmp/dump.sql"
rm ./dump.sql
- name: Export and Converting to mariadb
run: |
curl -L https://raw.githubusercontent.com/nitnelave/lldap/main/scripts/sqlite_dump_commands.sh -o helper.sh
chmod +x ./helper.sh
./helper.sh | sqlite3 ./users.db > ./dump.sql
cp ./dump.sql ./dump-no-sed.sql
sed -i -r -e "s/([^']'[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{9})\+00:00'([^'])/\1'\2/g" \-e 's/^INSERT INTO "?([a-zA-Z0-9_]+)"?/INSERT INTO `\1`/' -e '1s/^/START TRANSACTION;\n/' -e '$aCOMMIT;' ./dump.sql
sed -i '1 i\SET FOREIGN_KEY_CHECKS = 0;' ./dump.sql
- name: Create schema on mariadb
run: bin/lldap create_schema -d mysql://lldapuser:lldappass@localhost:3306/lldap
- name: Copy converted db to mariadb and import
run: |
docker ps -a
docker cp ./dump.sql mariadb:/tmp/dump.sql
docker exec mariadb bash -c "mariadb -ulldapuser -plldappass -f lldap < /tmp/dump.sql"
rm ./dump.sql
- name: Export and Converting to mysql
run: |
curl -L https://raw.githubusercontent.com/nitnelave/lldap/main/scripts/sqlite_dump_commands.sh -o helper.sh
chmod +x ./helper.sh
./helper.sh | sqlite3 ./users.db > ./dump.sql
sed -i -r -e 's/^INSERT INTO "?([a-zA-Z0-9_]+)"?/INSERT INTO `\1`/' -e '1s/^/START TRANSACTION;\n/' -e '$aCOMMIT;' ./dump.sql
sed -i '1 i\SET FOREIGN_KEY_CHECKS = 0;' ./dump.sql
- name: Create schema on mysql
run: bin/lldap create_schema -d mysql://lldapuser:lldappass@localhost:3307/lldap
- name: Copy converted db to mysql and import
run: |
docker ps -a
docker cp ./dump.sql mysql:/tmp/dump.sql
docker exec mysql bash -c "mysql -ulldapuser -plldappass -f lldap < /tmp/dump.sql"
rm ./dump.sql
- name: Run lldap with postgres DB and healthcheck again
run: |
bin/lldap run &
sleep 10s
bin/lldap healthcheck
env:
LLDAP_database_url: postgres://lldapuser:lldappass@localhost:5432/lldap
LLDAP_ldap_port: 3891
LLDAP_http_port: 17171
LLDAP_LDAP_USER_PASS: ldappass
LLDAP_JWT_SECRET: somejwtsecret
- name: Run lldap with mariaDB and healthcheck again
run: |
bin/lldap run &
sleep 10s
bin/lldap healthcheck
env:
LLDAP_database_url: mysql://lldapuser:lldappass@localhost:3306/lldap
LLDAP_ldap_port: 3892
LLDAP_http_port: 17172
LLDAP_JWT_SECRET: somejwtsecret
- name: Run lldap with mysql and healthcheck again
run: |
bin/lldap run &
sleep 10s
bin/lldap healthcheck
env:
LLDAP_database_url: mysql://lldapuser:lldappass@localhost:3307/lldap
LLDAP_ldap_port: 3893
LLDAP_http_port: 17173
LLDAP_JWT_SECRET: somejwtsecret
- name: Test Dummy User
run: |
ldapsearch -H ldap://localhost:3891 -LLL -D "uid=dummyuser,ou=people,dc=example,dc=com" -w 'dummypassword' -s "One" -b "ou=people,dc=example,dc=com"
ldapsearch -H ldap://localhost:3892 -LLL -D "uid=dummyuser,ou=people,dc=example,dc=com" -w 'dummypassword' -s "One" -b "ou=people,dc=example,dc=com"
ldapsearch -H ldap://localhost:3893 -LLL -D "uid=dummyuser,ou=people,dc=example,dc=com" -w 'dummypassword' -s "One" -b "ou=people,dc=example,dc=com"
build-docker-image: build-docker-image:
needs: [build-ui, build-bin] needs: [build-ui, build-bin]
@ -222,7 +430,7 @@ jobs:
packages: write packages: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3
with: with:
@ -337,6 +545,8 @@ jobs:
name: Create release artifacts name: Create release artifacts
if: github.event_name == 'release' if: github.event_name == 'release'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: write
steps: steps:
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v3

View File

@ -13,7 +13,6 @@ jobs:
pre_job: pre_job:
continue-on-error: true continue-on-error: true
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Map a step output to a job output
outputs: outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }} should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps: steps:
@ -22,7 +21,7 @@ jobs:
with: with:
concurrent_skipping: 'outdated_runs' concurrent_skipping: 'outdated_runs'
skip_after_successful_duplicate: 'true' skip_after_successful_duplicate: 'true'
paths_ignore: '["**/*.md", "**/docs/**", "example_configs/**", "*.sh"]' paths_ignore: '["**/*.md", "**/docs/**", "example_configs/**", "*.sh", ".dockerignore", ".gitignore", "lldap_config.docker_template.toml", "Dockerfile"]'
do_not_skip: '["workflow_dispatch", "schedule"]' do_not_skip: '["workflow_dispatch", "schedule"]'
cancel_others: true cancel_others: true
@ -34,7 +33,7 @@ jobs:
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Build - name: Build
run: cargo build --verbose --workspace run: cargo build --verbose --workspace
@ -53,7 +52,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
@ -70,7 +69,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
@ -87,7 +86,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v3.4.0 uses: actions/checkout@v3.5.0
- name: Install Rust - name: Install Rust
run: rustup toolchain install nightly --component llvm-tools-preview && rustup component add llvm-tools-preview --toolchain stable-x86_64-unknown-linux-gnu run: rustup toolchain install nightly --component llvm-tools-preview && rustup component add llvm-tools-preview --toolchain stable-x86_64-unknown-linux-gnu
@ -105,3 +104,4 @@ jobs:
with: with:
files: lcov.info files: lcov.info
fail_ci_if_error: true fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}

View File

@ -5,7 +5,66 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [0.4.2] - 2023-03-27
### Added
- Add support for MySQL/MariaDB/PostgreSQL, in addition to SQLite.
- Healthcheck command for docker setups.
- User creation through LDAP.
- IPv6 support.
- Dev container for VsCode.
- Add support for DN LDAP filters.
- Add support for SubString LDAP filters.
- Add support for LdapCompare operation.
- Add support for unencrypted/unauthenticated SMTP connection.
- Add a command to setup the database schema.
- Add a tool to set a user's password from the command line.
- Added consistent release artifacts.
### Changed
- Payload is now compressed, reducing the size to 700kb.
- entryUUID is returned in the default LDAP fields.
- Slightly improved support for LDAP browsing tools.
- Password reset can be identified by email (instead of just username).
- Various front-end improvements, and support for dark mode.
- Add content-type header to the password reset email, fixing rendering issues in some clients.
- Identify groups with "cn" instead of "uid" in memberOf field.
### Removed
- Removed dependency on nodejs/rollup.
### Fixed
- Email is now using the async API.
- Fix handling of empty/null names (display, first, last).
- Obscured old password field when changing password.
- Respect user setting to disable password resets.
- Fix handling of "present" filters with unknown attributes.
- Fix handling of filters that could lead to an ambiguous SQL query.
### New services
- Authentik
- Dell iDRAC
- Dex
- Kanboard
- NextCloud + OIDC or Authelia
- Nexus
- SUSE Rancher
- VaultWarden
- WeKan
- WikiJS
- ZendTo
### Dependencies (highlights)
- Upgraded Yew to 0.19
- Upgraded actix to 0.13
- Upgraded clap to 4
- Switched from sea-query to sea-orm 0.11
## [0.4.1] - 2022-10-10 ## [0.4.1] - 2022-10-10

54
Cargo.lock generated
View File

@ -2351,7 +2351,7 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]] [[package]]
name = "lldap" name = "lldap"
version = "0.4.2-alpha" version = "0.4.2"
dependencies = [ dependencies = [
"actix", "actix",
"actix-files", "actix-files",
@ -2410,13 +2410,13 @@ dependencies = [
"tracing-forest", "tracing-forest",
"tracing-log", "tracing-log",
"tracing-subscriber", "tracing-subscriber",
"uuid 1.3.0", "uuid 0.8.2",
"webpki-roots", "webpki-roots",
] ]
[[package]] [[package]]
name = "lldap_app" name = "lldap_app"
version = "0.4.2-alpha" version = "0.4.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64 0.13.1", "base64 0.13.1",
@ -2435,7 +2435,7 @@ dependencies = [
"serde_json", "serde_json",
"url-escape", "url-escape",
"validator", "validator",
"validator_derive 0.16.0", "validator_derive",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
@ -2448,7 +2448,7 @@ dependencies = [
[[package]] [[package]]
name = "lldap_auth" name = "lldap_auth"
version = "0.3.0-alpha.1" version = "0.3.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"curve25519-dalek", "curve25519-dalek",
@ -2537,6 +2537,12 @@ dependencies = [
"digest 0.10.6", "digest 0.10.6",
] ]
[[package]]
name = "md5"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.5.0" version = "2.5.0"
@ -2545,7 +2551,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "migration-tool" name = "migration-tool"
version = "0.4.2-alpha" version = "0.4.2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64 0.13.1", "base64 0.13.1",
@ -4405,6 +4411,9 @@ name = "uuid"
version = "0.8.2" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"md5",
]
[[package]] [[package]]
name = "uuid" name = "uuid"
@ -4413,7 +4422,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79"
dependencies = [ dependencies = [
"getrandom 0.2.8", "getrandom 0.2.8",
"md-5",
] ]
[[package]] [[package]]
@ -4429,7 +4437,7 @@ dependencies = [
"serde_derive", "serde_derive",
"serde_json", "serde_json",
"url", "url",
"validator_types 0.14.0", "validator_types",
] ]
[[package]] [[package]]
@ -4445,23 +4453,7 @@ dependencies = [
"quote", "quote",
"regex", "regex",
"syn", "syn",
"validator_types 0.14.0", "validator_types",
]
[[package]]
name = "validator_derive"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af"
dependencies = [
"if_chain",
"lazy_static",
"proc-macro-error",
"proc-macro2",
"quote",
"regex",
"syn",
"validator_types 0.16.0",
] ]
[[package]] [[package]]
@ -4474,16 +4466,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "validator_types"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3"
dependencies = [
"proc-macro2",
"syn",
]
[[package]] [[package]]
name = "valuable" name = "valuable"
version = "0.1.0" version = "0.1.0"
@ -4876,7 +4858,7 @@ source = "git+https://github.com/jfbilodeau/yew_form?rev=4b9fabffb63393ec7626a44
dependencies = [ dependencies = [
"gloo-console", "gloo-console",
"validator", "validator",
"validator_derive 0.14.0", "validator_derive",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"yew", "yew",

View File

@ -77,6 +77,9 @@ For more features (OAuth/OpenID support, reverse proxy, ...) you can install
other components (KeyCloak, Authelia, ...) using this server as the source of other components (KeyCloak, Authelia, ...) using this server as the source of
truth for users, via LDAP. truth for users, via LDAP.
By default, the data is stored in SQLite, but you can swap the backend with
MySQL/MariaDB or PostgreSQL.
## Installation ## Installation
### With Docker ### With Docker
@ -131,6 +134,9 @@ services:
- LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM
- LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD
- LLDAP_LDAP_BASE_DN=dc=example,dc=com - LLDAP_LDAP_BASE_DN=dc=example,dc=com
# You can also set a different database:
# - LLDAP_DATABASE_URL=mysql://mysql-user:password@mysql-server/my-database
# - LLDAP_DATABASE_URL=postgres://postgres-user:password@postgres-server/my-database
``` ```
Then the service will listen on two ports, one for LDAP and one for the web Then the service will listen on two ports, one for LDAP and one for the web
@ -142,6 +148,8 @@ See https://github.com/Evantage-WS/lldap-kubernetes for a LLDAP deployment for K
### From source ### From source
#### Backend
To compile the project, you'll need: To compile the project, you'll need:
- curl and gzip: `sudo apt install curl gzip` - curl and gzip: `sudo apt install curl gzip`
@ -156,13 +164,21 @@ cargo build --release -p lldap -p migration-tool
The resulting binaries will be in `./target/release/`. Alternatively, you can The resulting binaries will be in `./target/release/`. Alternatively, you can
just run `cargo run -- run` to run the server. just run `cargo run -- run` to run the server.
#### Frontend
To bring up the server, you'll need to compile the frontend. In addition to To bring up the server, you'll need to compile the frontend. In addition to
cargo, you'll need: `cargo`, you'll need:
- WASM-pack: `cargo install wasm-pack` - WASM-pack: `cargo install wasm-pack`
Then you can build the frontend files with `./app/build.sh` (you'll need to run Then you can build the frontend files with
this after every front-end change to update the WASM package served).
```shell
./app/build.sh
````
(you'll need to run this after every front-end change to update the WASM
package served).
The default config is in `src/infra/configuration.rs`, but you can override it The default config is in `src/infra/configuration.rs`, but you can override it
by creating an `lldap_config.toml`, setting environment variables or passing by creating an `lldap_config.toml`, setting environment variables or passing
@ -263,6 +279,12 @@ folder for help with:
- [XBackBone](example_configs/xbackbone_config.php) - [XBackBone](example_configs/xbackbone_config.php)
- [Zendto](example_configs/zendto.md) - [Zendto](example_configs/zendto.md)
## Migrating from SQLite
If you started with an SQLite database and would like to migrate to
MySQL/MariaDB or PostgreSQL, check out the [DB
migration docs](/docs/database_migration.md).
## Comparisons with other services ## Comparisons with other services
### vs OpenLDAP ### vs OpenLDAP

View File

@ -1,6 +1,6 @@
[package] [package]
name = "lldap_app" name = "lldap_app"
version = "0.4.2-alpha" version = "0.4.2"
authors = ["Valentin Tolmer <valentin@tolmer.fr>"] authors = ["Valentin Tolmer <valentin@tolmer.fr>"]
edition = "2021" edition = "2021"
include = ["src/**/*", "queries/**/*", "Cargo.toml", "../schema.graphql"] include = ["src/**/*", "queries/**/*", "Cargo.toml", "../schema.graphql"]

View File

@ -14,4 +14,4 @@ fi
wasm-pack build --target web --release wasm-pack build --target web --release
gzip -9 -f pkg/lldap_app_bg.wasm gzip -9 -k -f pkg/lldap_app_bg.wasm

View File

@ -1,6 +1,10 @@
import init, { run_app } from '/pkg/lldap_app.js'; import init, { run_app } from '/pkg/lldap_app.js';
async function main() { async function main() {
if(navigator.userAgent.indexOf('AppleWebKit') != -1) {
await init('/pkg/lldap_app_bg.wasm'); await init('/pkg/lldap_app_bg.wasm');
} else {
await init('/pkg/lldap_app_bg.wasm.gz');
}
run_app(); run_app();
} }
main() main()

View File

@ -1,6 +1,6 @@
[package] [package]
name = "lldap_auth" name = "lldap_auth"
version = "0.3.0-alpha.1" version = "0.3.0"
authors = ["Valentin Tolmer <valentin@tolmer.fr>"] authors = ["Valentin Tolmer <valentin@tolmer.fr>"]
edition = "2021" edition = "2021"

View File

@ -26,9 +26,9 @@ Frontend:
Data storage: Data storage:
* The data (users, groups, memberships, active JWTs, ...) is stored in SQL. * The data (users, groups, memberships, active JWTs, ...) is stored in SQL.
* Currently only SQLite is supported (see * The main SQL DBs are supported: SQLite by default, MySQL, MariaDB, PostgreSQL
https://github.com/launchbadge/sqlx/issues/1225 for what blocks us from (see [DB Migration](/database_migration.md) for how to migrate off of
supporting more SQL backends). SQLite).
### Code organization ### Code organization

View File

@ -65,7 +65,8 @@ a transaction:
``` ```
sed -i -r -e 's/^INSERT INTO "?([a-zA-Z0-9_]+)"?/INSERT INTO `\1`/' \ sed -i -r -e 's/^INSERT INTO "?([a-zA-Z0-9_]+)"?/INSERT INTO `\1`/' \
-e '1s/^/START TRANSACTION;\n/' \ -e '1s/^/START TRANSACTION;\n/' \
-e '$aCOMMIT;' /path/to/dump.sql -e '$aCOMMIT;' \
-e '1 i\SET FOREIGN_KEY_CHECKS = 0;' /path/to/dump.sql
``` ```
### To MariaDB ### To MariaDB
@ -77,7 +78,8 @@ strings. Use the following command to remove those and perform the additional My
sed -i -r -e "s/([^']'[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{9})\+00:00'([^'])/\1'\2/g" \ sed -i -r -e "s/([^']'[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{9})\+00:00'([^'])/\1'\2/g" \
-e 's/^INSERT INTO "?([a-zA-Z0-9_]+)"?/INSERT INTO `\1`/' \ -e 's/^INSERT INTO "?([a-zA-Z0-9_]+)"?/INSERT INTO `\1`/' \
-e '1s/^/START TRANSACTION;\n/' \ -e '1s/^/START TRANSACTION;\n/' \
-e '$aCOMMIT;' /path/to/dump.sql -e '$aCOMMIT;' \
-e '1 i\SET FOREIGN_KEY_CHECKS = 0;' /path/to/dump.sql
``` ```
## Insert data ## Insert data
@ -103,3 +105,5 @@ or
Modify your `database_url` in `lldap_config.toml` (or `LLDAP_DATABASE_URL` in the env) Modify your `database_url` in `lldap_config.toml` (or `LLDAP_DATABASE_URL` in the env)
to point to your new database (the same value used when generating schema). Restart to point to your new database (the same value used when generating schema). Restart
LLDAP and check the logs to ensure there were no errors. LLDAP and check the logs to ensure there were no errors.
#### More details/examples can be seen in the CI process [here](https://raw.githubusercontent.com/nitnelave/lldap/main/.github/workflows/docker-build-static.yml), look for the job `lldap-database-migration-test`

View File

@ -1,6 +1,6 @@
[package] [package]
name = "migration-tool" name = "migration-tool"
version = "0.4.2-alpha" version = "0.4.2"
edition = "2021" edition = "2021"
authors = ["Valentin Tolmer <valentin@tolmer.fr>"] authors = ["Valentin Tolmer <valentin@tolmer.fr>"]

View File

@ -2,7 +2,7 @@
authors = ["Valentin Tolmer <valentin@tolmer.fr>"] authors = ["Valentin Tolmer <valentin@tolmer.fr>"]
edition = "2021" edition = "2021"
name = "lldap" name = "lldap"
version = "0.4.2-alpha" version = "0.4.2"
[dependencies] [dependencies]
actix = "0.13" actix = "0.13"
@ -15,7 +15,7 @@ actix-web = "4.3"
actix-web-httpauth = "0.8" actix-web-httpauth = "0.8"
anyhow = "*" anyhow = "*"
async-trait = "0.1" async-trait = "0.1"
base64 = "*" base64 = "0.21"
bincode = "1.3" bincode = "1.3"
cron = "*" cron = "*"
derive_builder = "0.12" derive_builder = "0.12"

View File

@ -16,7 +16,7 @@ use actix_files::{Files, NamedFile};
use actix_http::{header, HttpServiceBuilder}; use actix_http::{header, HttpServiceBuilder};
use actix_server::ServerBuilder; use actix_server::ServerBuilder;
use actix_service::map_config; use actix_service::map_config;
use actix_web::{dev::AppConfig, guard, middleware, web, App, HttpResponse, Responder}; use actix_web::{dev::AppConfig, guard, web, App, HttpResponse, Responder};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use hmac::Hmac; use hmac::Hmac;
use sha2::Sha512; use sha2::Sha512;
@ -68,6 +68,10 @@ pub(crate) fn error_to_http_response(error: TcpError) -> HttpResponse {
} }
async fn wasm_handler() -> actix_web::Result<impl Responder> { async fn wasm_handler() -> actix_web::Result<impl Responder> {
Ok(actix_files::NamedFile::open_async("./app/pkg/lldap_app_bg.wasm").await?)
}
async fn wasm_handler_compressed() -> actix_web::Result<impl Responder> {
Ok( Ok(
actix_files::NamedFile::open_async("./app/pkg/lldap_app_bg.wasm.gz") actix_files::NamedFile::open_async("./app/pkg/lldap_app_bg.wasm.gz")
.await? .await?
@ -110,12 +114,9 @@ fn http_config<Backend>(
.configure(super::graphql::api::configure_endpoint::<Backend>), .configure(super::graphql::api::configure_endpoint::<Backend>),
) )
.service( .service(
web::resource("/pkg/lldap_app_bg.wasm").route( web::resource("/pkg/lldap_app_bg.wasm.gz").route(web::route().to(wasm_handler_compressed)),
web::route()
.wrap(middleware::Compress::default())
.to(wasm_handler),
),
) )
.service(web::resource("/pkg/lldap_app_bg.wasm").route(web::route().to(wasm_handler)))
// Serve the /pkg path with the compiled WASM app. // Serve the /pkg path with the compiled WASM app.
.service(Files::new("/pkg", "./app/pkg")) .service(Files::new("/pkg", "./app/pkg"))
// Serve static files // Serve static files