# Test Infrastructure: LDAP Server

> **SUPERSEDED 2026-06-04** — ScadaBridge no longer runs its own glauth. Dev/test LDAP is now the
> shared GLAuth on **10.100.0.35:3893** (dc=zb,dc=local); source of truth and runbook:
> **`scadaproj/infra/glauth/`** (`~/Desktop/scadaproj/infra/glauth/config.toml`). The
> `scadabridge-ldap` container has been retired (commented out in `infra/docker-compose.yml`).
> The content below describes the retired local setup, kept for reference/rollback.

## Overview

The test LDAP server uses [GLAuth](https://glauth.github.io/), a lightweight LDAP server backed by a TOML config file. It provides test users and groups that map to ScadaBridge's role-based authorization model.

## Image & Ports

- **Image**: `glauth/glauth:latest`
- **LDAP port**: 3893 (plain LDAP, no TLS — dev only)
- **Host (shared)**: `10.100.0.35` — the shared `zb-shared-glauth` container on the Linux docker host (replaces `localhost` below)

## Base DN

```
dc=zb,dc=local
```

## Test Users

All users have the password `password`.

| Username | Email | Primary Group | Additional Groups | ScadaBridge Role |
|----------|-------|---------------|-------------------|----------------|
| `admin` | admin@scadabridge.local | SCADA-Admins | — | Full administrator |
| `designer` | designer@scadabridge.local | SCADA-Designers | — | Template designer |
| `deployer` | deployer@scadabridge.local | SCADA-Deploy-All | — | Deploy to all sites |
| `site-deployer` | site-deployer@scadabridge.local | SCADA-Deploy-SiteA | — | Deploy to SiteA only |
| `multi-role` | multi-role@scadabridge.local | SCADA-Admins | SCADA-Designers, SCADA-Deploy-All | Multiple roles |

## Groups

| Group | GID | Purpose |
|-------|-----|---------|
| SCADA-Admins | 5501 | Full administrative access |
| SCADA-Designers | 5502 | Template creation and editing |
| SCADA-Deploy-All | 5503 | Deploy to any site |
| SCADA-Deploy-SiteA | 5504 | Deploy to SiteA only (site-scoped) |

## User DNs

Users bind with their full DN, which includes the primary group as an OU:

```
cn=<username>,ou=<PrimaryGroupName>,ou=users,dc=zb,dc=local
```

For example: `cn=admin,ou=SCADA-Admins,ou=users,dc=zb,dc=local`

The full DNs for all test users:

| Username | Full DN |
|----------|---------|
| `admin` | `cn=admin,ou=SCADA-Admins,ou=users,dc=zb,dc=local` |
| `designer` | `cn=designer,ou=SCADA-Designers,ou=users,dc=zb,dc=local` |
| `deployer` | `cn=deployer,ou=SCADA-Deploy-All,ou=users,dc=zb,dc=local` |
| `site-deployer` | `cn=site-deployer,ou=SCADA-Deploy-SiteA,ou=users,dc=zb,dc=local` |
| `multi-role` | `cn=multi-role,ou=SCADA-Admins,ou=users,dc=zb,dc=local` |

## Verification

1. Check the shared container is running (on the docker host):

```bash
# The container now runs on 10.100.0.35 as zb-shared-glauth, not locally.
# To verify from the docker host:
#   docker ps --filter name=zb-shared-glauth
# Formerly: docker ps --filter name=scadabridge-ldap  (retired)
```

2. Test a user bind with `ldapsearch` against the shared host:

```bash
ldapsearch -H ldap://10.100.0.35:3893 \
  -D "cn=admin,ou=SCADA-Admins,ou=users,dc=zb,dc=local" \
  -w password \
  -b "dc=zb,dc=local" \
  "(objectClass=*)"
```

3. Search for group membership:

```bash
ldapsearch -H ldap://10.100.0.35:3893 \
  -D "cn=admin,ou=SCADA-Admins,ou=users,dc=zb,dc=local" \
  -w password \
  -b "dc=zb,dc=local" \
  "(cn=multi-role)"
```

## CLI Tool

The `infra/tools/ldap_tool.py` script provides a convenient CLI for interacting with the LDAP server.

**Install dependencies** (one-time):
```bash
pip install -r infra/tools/requirements.txt
```

**Commands**:

```bash
# Check LDAP connectivity and list entries
python infra/tools/ldap_tool.py check

# Test user authentication
python infra/tools/ldap_tool.py bind --user designer --password password

# List all users with group memberships
python infra/tools/ldap_tool.py users

# List all groups with members
python infra/tools/ldap_tool.py groups

# Search with an arbitrary LDAP filter
python infra/tools/ldap_tool.py search --filter "(cn=multi-role)"
```

Use `--host 10.100.0.35 --port 3893` to point at the shared server. Run with `--help` for full usage.

## Relevance to ScadaBridge Components

- **Security & Auth** — test LDAP bind authentication, group-to-role mapping, and multi-group resolution.
- **Central UI** — test login flows with different role combinations.

## Notes

- GLAuth uses plain LDAP on port 3893. ScadaBridge's Security & Auth component requires LDAPS/StartTLS in production. For dev testing, configure the LDAP client to allow plaintext connections.
- To add users or groups, edit **`scadaproj/infra/glauth/config.toml`** (the shared source of truth at `~/Desktop/scadaproj/infra/glauth/config.toml`) and restart the `zb-shared-glauth` container on the docker host. **Do not edit the retired `ScadaBridge/infra/glauth/config.toml`** — that file is historical only. The config is mounted into the container as `/app/config/config.cfg` (the path GLAuth expects).
- The `admin` user is configured with `[[users.capabilities]]` (`action = "search"`, `object = "*"`) in the GLAuth config. This grants the admin account permission to perform LDAP search operations, which is required for user/group lookups.
- Anonymous bind is not allowed. All LDAP operations (including searches) require an authenticated bind. Use the `admin` account for search operations.
