Skip to content

Commit 09df2f3

Browse files
fpotierminottic
andauthored
LDAP integration (#143)
* Add LDAP container * BE v4 LDAP config * FE LDAP config * Add `LDAP_ENABLED` feature flag in CI/README * BE v3 LDAP config * Update README for BE v3 and v4 * Implement comments * Fix CI * Include ldap from shared BE compose * Implement commens --------- Co-authored-by: minottic <carlo.minotti1@gmail.com>
1 parent 4142053 commit 09df2f3

File tree

22 files changed

+146
-10
lines changed

22 files changed

+146
-10
lines changed

.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ BE_VERSION=v4
66

77
## Enable v4 ELASTIC feature (disable if required or set in command line). To later disable, either unset or set to an empty value
88
# ELASTIC_ENABLED=true
9+
10+
## Enable LDAP authentication backend (disable if required or set in command line). To later disable, either unset or set to an empty value
11+
# LDAP_ENABLED=true

.github/workflows/compose_test.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ jobs:
5454
strategy:
5555
matrix:
5656
BE_VERSION: [v3, v4]
57-
JOBS_AND_ELASTIC_ENABLED: ['', true]
57+
ELASTIC_OR_JOBS_ENABLED: ['', true]
58+
LDAP_ENABLED: ['', true]
5859
steps:
5960
- uses: actions/checkout@v4
6061
- name: Test compose.yaml
6162
run: |-
62-
export JOBS_ENABLED=${{ matrix.JOBS_AND_ELASTIC_ENABLED }}
63-
export ELASTIC_ENABLED=${{ matrix.JOBS_AND_ELASTIC_ENABLED }}
63+
export JOBS_ENABLED=${{ matrix.ELASTIC_OR_JOBS_ENABLED }}
64+
export ELASTIC_ENABLED=${{ matrix.ELASTIC_OR_JOBS_ENABLED }}
65+
export LDAP_ENABLED=${{ matrix.LDAP_ENABLED }}
6466
export BE_VERSION=${{ matrix.BE_VERSION }}
6567
docker compose --profile '*' up --wait --wait-timeout 300

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ They are used when adding new services or grouping services together (and do not
4141
| env | `BE_VERSION` | <li>`v3`: backend/v3<li>`v4`: backend/v4 | `v4` | as set | Sets the be version to use in (2) of [default setup](#default-setup) to v3 | mongodb,frontend |
4242
| env | `JOBS_ENABLED` | `true`: rabbitmq,archivemock,jobs feature | `''` | v3 | Creates a rabbitmq message broker which the be posts to and the archivemock listens to. It emulates the data long-term archive/retrieve workflow | |
4343
| env | `ELASTIC_ENABLED` | `true`: elastic,elastic feature | `''` | v4 | Creates an elastic search service and sets the be to use it for full-text searches | |
44+
| env | `LDAP_ENABLED` | `true`: ldap auth | `''` | as set | Creates an LDAP service and sets the be to use it as authentication backend | |
4445

4546

4647
After optionally setting any configuration option, one can still select the services to run as described [here](README.md#select-the-services).

services/backend/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,12 @@ The SciCat backend HTTP service.
55
## Dependency on `BE_VERSION`
66

77
The `BE_VERSION` value controls which version of the backend should be started, either [v3](./services/v3) or [v4](./services/v4) (default).
8+
9+
## Dependencies
10+
11+
Here below we show the internal dependencies of the service, which are not already covered [here](../../../../README.md) (if `B` depends on `A`, then we visualize as `A --> B`). The same subdomain to service convention applies.
12+
13+
```mermaid
14+
graph TD
15+
ldap --> backend
16+
```

services/backend/compose.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
include:
2-
- ./services/${BE_VERSION:-v4}/compose.yaml
2+
- path:
3+
- ./services/${BE_VERSION:-v4}/compose.yaml
4+
- ./services/ldap/.${LDAP_ENABLED:+./${BE_VERSION:-v4}/}compose${LDAP_ENABLED:+.ldap}.yaml
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## empty file used when override configs are not enabled
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# LDAP (OpenLDAP)
2+
3+
LDAP (Lightweight Directory Access Protocol) is a protocol used to access and manage directory information such as user credentials.
4+
SciCat can use LDAP as third-party authentication provider.
5+
6+
## Configuration options
7+
8+
The OpenLDAP configuration is set by the [.env file](./config/.env).
9+
10+
For an extensive list of available options see [here](https://hub.docker.com/r/bitnami/openldap).
11+
12+
You can add other users by editing the [ldif file](./config/ldifs/02-users.ldif).
13+
:warning: User creation is only done once, when the container is created.
14+
15+
## Default configuration
16+
The default configuration [.env file](./config/.env) creates the `dc=facility` domain with the following user:
17+
18+
| Username | Password |
19+
| --------- | -------- |
20+
| ldap-user | password |
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
services:
2+
ldap:
3+
image: bitnami/openldap:2.6
4+
volumes:
5+
- ./config/ldifs:/ldifs:ro
6+
env_file:
7+
- ./config/.env
8+
healthcheck:
9+
test: ldapwhoami -H ldap://ldap:389 -D 'cn=admin,dc=facility' -w 'admin'
10+
start_period: 5s
11+
interval: 10s
12+
timeout: 10s
13+
retries: 5
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
LDAP_ADMIN_USERNAME=admin
2+
LDAP_ADMIN_PASSWORD=admin
3+
LDAP_PORT_NUMBER=389
4+
LDAP_ROOT=dc=facility
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
dn: dc=facility
2+
objectClass: top
3+
objectClass: dcObject
4+
objectClass: organization
5+
o: My Organization
6+
dc: facility
7+
8+
dn: ou=users,dc=facility
9+
objectClass: top
10+
objectClass: organizationalUnit
11+
ou: users
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
dn: uid=ldap-user,ou=users,dc=facility
2+
objectClass: top
3+
objectClass: person
4+
objectClass: organizationalPerson
5+
objectClass: inetOrgPerson
6+
uid: ldap-user
7+
cn: LDAP user
8+
displayName: ldap-user
9+
sn: LDAP
10+
givenName: User
11+
mail: ldap-user@facility.com
12+
userPassword: password

services/backend/services/v3/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,14 @@ In the default configuration folder [config](./config), the backend is set to us
6969

7070
Additionally, by setting the env variable [ENABLE_JOBS](../../.env#L5), the [archive mock](./services/archivemock/) and [rabbitmq](./services/rabbitmq/) services are started and the backend is configured to connect to them.
7171

72+
If `LDAP_ENABLED` is toggled, you can use LDAP to log in with a [LDAP user](../ldap/README.md#default-configuration).
73+
7274
## Dependencies
7375

74-
Here below we show the internal dependencies of the service, which are not already covered [here](../../../../README.md) (if `B` depends on `A`, then we visualize it as `A --> B`). The same subdomain to service convention applies.
76+
Here below we show the internal dependencies of the service, which are not already covered [here](../../../../README.md) and [here](../../README.md) (if `B` depends on `A`, then we visualize as `A --> B`). The same subdomain to service convention applies.
7577

7678
```mermaid
77-
graph TD
79+
graph TD
7880
rabbitmq --> archivemock
7981
rabbitmq --> backend
8082
backend --> archivemock
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include:
2+
- ../ldap/compose.yaml
3+
4+
services:
5+
backend:
6+
depends_on:
7+
ldap:
8+
condition: service_healthy
9+
volumes:
10+
- ./config/providers.ldap.json:/config/providers.ldap.json
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"ldap": {
3+
"provider": "ldap",
4+
"authScheme": "ldap",
5+
"module": "passport-ldapauth",
6+
"authPath": "/auth/msad",
7+
"successRedirect": "/auth/account",
8+
"failureRedirect": "/msad",
9+
"session": true,
10+
"json": true,
11+
"failureFlash": true,
12+
"profileAttributesFromLDAP": {
13+
"displayName": "displayName",
14+
"email": "mail"
15+
},
16+
"server": {
17+
"url": "ldap://ldap:389",
18+
"bindDn": "cn=admin,dc=facility",
19+
"bindCredentials": "admin",
20+
"searchBase": "ou=users,dc=facility",
21+
"searchFilter": "(uid={{username}})"
22+
}
23+
}
24+
}

services/backend/services/v4/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ In the default configuration folder [config](./config), the backend is set to us
2323

2424
## Enable additional features
2525

26-
Additionally, by setting the env variable `ELASTIC_ENABLED`, the [elastic search](./services/elastic/) service is started and the backend is configured to connect to them.
26+
Additionally, by setting the env variable `ELASTIC_ENABLED`, the [elastic search](./services/elastic/) service is started and the backend is configured to connect to them.
27+
28+
If `LDAP_ENABLED` is toggled, you can use LDAP to log in with a [LDAP user](../ldap/README.md#default-configuration).
2729

2830
## Dependencies
2931

30-
Here below we show the internal dependencies of the service, which are not already covered [here](../../../../README.md) (if `B` depends on `A`, then we visualize as `A --> B`). The same subdomain to service convention applies.
32+
Here below we show the internal dependencies of the service, which are not already covered [here](../../../../README.md) and [here](../../README.md) (if `B` depends on `A`, then we visualize as `A --> B`). The same subdomain to service convention applies.
3133

3234
```mermaid
3335
graph TD
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include:
2+
- ../ldap/compose.yaml
3+
4+
services:
5+
backend:
6+
depends_on:
7+
ldap:
8+
condition: service_healthy
9+
env_file:
10+
- ./config/.ldap.env
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
LDAP_URL=ldap://ldap:389
2+
LDAP_SEARCH_BASE=ou=users,dc=facility
3+
LDAP_SEARCH_FILTER=(uid={{username}})

services/frontend/compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ services:
1313
- /config/init.sh && nginx -g "daemon off;"
1414
environment:
1515
BE_VERSION: ${BE_VERSION:-v4}
16+
LDAP_ENABLED: ${LDAP_ENABLED:-}
1617
labels:
1718
- traefik.http.routers.frontend.rule=Host(`localhost`)

services/frontend/config/config.base.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"editMetadataEnabled":true,
88
"editPublishedData":true,
99
"editSampleEnabled":true,
10-
"externalAuthEndpoint":"/auth/msad",
10+
"externalAuthEndpoint":"/api/v3/auth/ldap",
1111
"facility":"SAMPLE-SITE",
1212
"fileColorEnabled":true,
1313
"fileDownloadEnabled":true,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"loginLdapEnabled": true,
3+
"loginLdapLabel": "Connect with LDAP"
4+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"accessTokenPrefix": ""
2+
"accessTokenPrefix": "",
3+
"externalAuthEndpoint":"/auth/msad"
34
}

services/frontend/config/init.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ exclude_config () {
1010
}
1111

1212
[ "$BE_VERSION" = "v4" ] && exclude_config "v3.json"
13+
[ -z "$LDAP_ENABLED" ] && exclude_config "ldap.json"
1314

1415
# shellcheck disable=SC2086
1516
jq -s 'reduce .[] as $item ({}; . * $item)' $FILES > /usr/share/nginx/html/assets/config.json

0 commit comments

Comments
 (0)