Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LDAP integration #143

Merged
merged 10 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ BE_VERSION=v4

## Enable v4 ELASTIC feature (disable if required or set in command line). To later disable, either unset or set to an empty value
# ELASTIC_ENABLED=true

## Enable LDAP authentication backend (disable if required or set in command line). To later disable, either unset or set to an empty value
# LDAP_ENABLED=true
9 changes: 6 additions & 3 deletions .github/workflows/compose_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,15 @@ jobs:
strategy:
matrix:
BE_VERSION: [v3, v4]
JOBS_AND_ELASTIC_ENABLED: ['', true]
ELASTIC_OR_JOBS_ENABLED: ['', true]
ELASTIC_ENABLED: ['', true]
minottic marked this conversation as resolved.
Show resolved Hide resolved
LDAP_ENABLED: ['', true]
steps:
- uses: actions/checkout@v4
- name: Test compose.yaml
run: |-
export JOBS_ENABLED=${{ matrix.JOBS_AND_ELASTIC_ENABLED }}
export ELASTIC_ENABLED=${{ matrix.JOBS_AND_ELASTIC_ENABLED }}
export JOBS_ENABLED=${{ matrix.matrix.ELASTIC_OR_JOBS_ENABLED }}
export ELASTIC_ENABLED=${{ matrix.ELASTIC_OR_JOBS_ENABLED }}
export LDAP_ENABLED=${{ matrix.LDAP_ENABLED }}
export BE_VERSION=${{ matrix.BE_VERSION }}
docker compose --profile '*' up --wait --wait-timeout 300
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ They are used when adding new services or grouping services together (and do not
| 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 |
| 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 | |
| env | `ELASTIC_ENABLED` | `true`: elastic,elastic feature | `''` | v4 | Creates an elastic search service and sets the be to use it for full-text searches | |
| env | `LDAP_ENABLED` | `true`: ldap auth | `''` | as set | Creates an LDAP service and sets the be to use it as authentication backend | |


After optionally setting any configuration option, one can still select the services to run as described [here](README.md#select-the-services).
Expand Down
9 changes: 9 additions & 0 deletions services/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ The SciCat backend HTTP service.
## Dependency on `BE_VERSION`

The `BE_VERSION` value controls which version of the backend should be started, either [v3](./services/v3) or [v4](./services/v4) (default).

## Dependencies

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.

```mermaid
graph TD
ldap --> backend
```
4 changes: 3 additions & 1 deletion services/backend/compose.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
include:
- ./services/${BE_VERSION:-v4}/compose.yaml
- path:
- ./services/${BE_VERSION:-v4}/compose.yaml
- ./services/ldap/.${LDAP_ENABLED:+./${BE_VERSION:-v4}/}compose${LDAP_ENABLED:+.ldap}.yaml
1 change: 1 addition & 0 deletions services/backend/services/ldap/.compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## empty file used when override configs are not enabled
20 changes: 20 additions & 0 deletions services/backend/services/ldap/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# LDAP (OpenLDAP)

LDAP (Lightweight Directory Access Protocol) is a protocol used to access and manage directory information such as user credentials.
SciCat can use LDAP as third-party authentication provider.

## Configuration options

The OpenLDAP configuration is set by the [.env file](./config/.env).

For an extensive list of available options see [here](https://hub.docker.com/r/bitnami/openldap).

You can add other users by editing the [ldif file](./config/ldifs/02-users.ldif).
:warning: User creation is only done once, when the container is created.

## Default configuration
The default configuration [.env file](./config/.env) creates the `dc=facility` domain with the following user:

| Username | Password |
| --------- | -------- |
| ldap-user | password |
13 changes: 13 additions & 0 deletions services/backend/services/ldap/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
services:
ldap:
image: bitnami/openldap:2.6
volumes:
- ./config/ldifs:/ldifs:ro
env_file:
- ./config/.env
healthcheck:
test: ldapwhoami -H ldap://ldap:389 -D 'cn=admin,dc=facility' -w 'admin'
start_period: 5s
interval: 10s
timeout: 10s
retries: 5
4 changes: 4 additions & 0 deletions services/backend/services/ldap/config/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
LDAP_ADMIN_USERNAME=admin
LDAP_ADMIN_PASSWORD=admin
LDAP_PORT_NUMBER=389
LDAP_ROOT=dc=facility
11 changes: 11 additions & 0 deletions services/backend/services/ldap/config/ldifs/01-bootstrap.ldif
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
dn: dc=facility
objectClass: top
objectClass: dcObject
objectClass: organization
o: My Organization
dc: facility

dn: ou=users,dc=facility
objectClass: top
objectClass: organizationalUnit
ou: users
12 changes: 12 additions & 0 deletions services/backend/services/ldap/config/ldifs/02-users.ldif
fpotier marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
dn: uid=ldap-user,ou=users,dc=facility
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: ldap-user
cn: LDAP user
displayName: ldap-user
sn: LDAP
givenName: User
mail: ldap-user@facility.com
userPassword: password
6 changes: 4 additions & 2 deletions services/backend/services/v3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ In the default configuration folder [config](./config), the backend is set to us

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.

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

## Dependencies

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.
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.

```mermaid
graph TD
graph TD
rabbitmq --> archivemock
rabbitmq --> backend
backend --> archivemock
Expand Down
12 changes: 12 additions & 0 deletions services/backend/services/v3/compose.ldap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
include:
- ../ldap/compose.yaml

services:
backend:
depends_on:
ldap:
condition: service_healthy
volumes:
- ./config/providers.ldap.json:/config/providers.ldap.json
environment:
LDAP_ENABLED: true
30 changes: 30 additions & 0 deletions services/backend/services/v3/config/mergeJson.js
fpotier marked this conversation as resolved.
Show resolved Hide resolved
minottic marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const fs = require("fs");

const readJsonFile = (filePath) => {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
};

const writeJsonFile = (filePath, data) => {
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), "utf8");
};

const mergeJsonFiles = (inputPaths, outputPath) => {
let mergedJson = {};

inputPaths.forEach(filePath => {
const jsonData = readJsonFile(filePath);
mergedJson = { ...mergedJson, ...jsonData };
});

writeJsonFile(outputPath, mergedJson);
console.log(`Merged JSON has been written to ${outputPath}`);
};

const args = process.argv.slice(2);
if (args.length < 2) {
console.error("Please provide at least one input file and one output file.");
process.exit(1);
}
const outputPath = args.pop();

mergeJsonFiles(args, outputPath);
24 changes: 24 additions & 0 deletions services/backend/services/v3/config/providers.ldap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"ldap": {
"provider": "ldap",
"authScheme": "ldap",
"module": "passport-ldapauth",
"authPath": "/auth/msad",
"successRedirect": "/auth/account",
"failureRedirect": "/msad",
"session": true,
"json": true,
"failureFlash": true,
"profileAttributesFromLDAP": {
"displayName": "displayName",
"email": "mail"
},
"server": {
"url": "ldap://ldap:389",
"bindDn": "cn=admin,dc=facility",
"bindCredentials": "admin",
"searchBase": "ou=users,dc=facility",
"searchFilter": "(uid={{username}})"
}
}
}
6 changes: 4 additions & 2 deletions services/backend/services/v4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ In the default configuration folder [config](./config), the backend is set to us

## Enable additional features

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.
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.

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

## Dependencies

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.
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.

```mermaid
graph TD
Expand Down
10 changes: 10 additions & 0 deletions services/backend/services/v4/compose.ldap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include:
- ../ldap/compose.yaml

services:
backend:
depends_on:
ldap:
condition: service_healthy
env_file:
- ./config/.ldap.env
3 changes: 3 additions & 0 deletions services/backend/services/v4/config/.ldap.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
LDAP_URL=ldap://ldap:389
LDAP_SEARCH_BASE=ou=users,dc=facility
LDAP_SEARCH_FILTER=(uid={{username}})
1 change: 1 addition & 0 deletions services/frontend/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ services:
- /config/init.sh && nginx -g "daemon off;"
environment:
BE_VERSION: ${BE_VERSION:-v4}
LDAP_ENABLED: ${LDAP_ENABLED:-}
minottic marked this conversation as resolved.
Show resolved Hide resolved
labels:
- traefik.http.routers.frontend.rule=Host(`localhost`)
2 changes: 1 addition & 1 deletion services/frontend/config/config.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"editMetadataEnabled":true,
"editPublishedData":true,
"editSampleEnabled":true,
"externalAuthEndpoint":"/auth/msad",
"externalAuthEndpoint":"/api/v3/auth/ldap",
"facility":"SAMPLE-SITE",
"fileColorEnabled":true,
"fileDownloadEnabled":true,
Expand Down
4 changes: 4 additions & 0 deletions services/frontend/config/config.ldap.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"loginLdapEnabled": true,
"loginLdapLabel": "Connect with LDAP"
}
3 changes: 2 additions & 1 deletion services/frontend/config/config.v3.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"accessTokenPrefix": ""
"accessTokenPrefix": "",
"externalAuthEndpoint":"/auth/msad"
}
1 change: 1 addition & 0 deletions services/frontend/config/init.sh
fpotier marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exclude_config () {
}

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

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