Skip to content

Commit

Permalink
Merge pull request #23 from mongodb-js/oidc-mock-provider-docker
Browse files Browse the repository at this point in the history
chore(oidc): add docker compose configuration that uses mock oidc provider
  • Loading branch information
gribnoysup authored Dec 4, 2023
2 parents ca4bacd + fe78c0d commit 0799920
Show file tree
Hide file tree
Showing 12 changed files with 182 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docker/oidc/mock-oidc-provider/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
!proxy.js
!oidc-mock-provider.js
16 changes: 16 additions & 0 deletions docker/oidc/mock-oidc-provider/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM mongodb/mongodb-enterprise-server:latest
USER root
RUN apt-get update && apt-get install -y \
ca-certificates \
curl
ARG NODE_VERSION=20.10.0
ARG NODE_PACKAGE=node-v$NODE_VERSION-linux-arm64
ARG NODE_HOME=/opt/$NODE_PACKAGE
ENV NODE_PATH $NODE_HOME/lib/node_modules
ENV PATH $NODE_HOME/bin:$PATH
RUN curl https://nodejs.org/dist/v$NODE_VERSION/$NODE_PACKAGE.tar.gz | tar -xzC /opt/
RUN mkdir -p /tmp/mock-provider && cd /tmp/mock-provider && npm init -y && npm install @mongodb-js/oidc-mock-provider
COPY start-server.sh /start-server.sh
COPY oidc-mock-provider.js /tmp/mock-provider/oidc-mock-provider.js
COPY proxy.js /tmp/mock-provider/proxy.js
ENTRYPOINT ["/start-server.sh"]
20 changes: 20 additions & 0 deletions docker/oidc/mock-oidc-provider/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
### MongoDB enterprise with mock OIDC provider auth enabled

```sh
docker-compose -f oidc/mock-oidc-provider/docker-compose.yaml up
```

#### How to connect

```sh
mongosh \
--host localhost \
--port 27096 \
--authenticationMechanism MONGODB-OIDC
```

Connection string:

```
mongodb://localhost:27096/?authMechanism=MONGODB-OIDC
```
21 changes: 21 additions & 0 deletions docker/oidc/mock-oidc-provider/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import path from 'path';

import ConnectionString from 'mongodb-connection-string-url';

const port = '27017';

const connectionString = new ConnectionString(`mongodb://localhost:${port}`);
connectionString.searchParams.set('authMechanism', 'MONGODB-OIDC');

export default {
dockerCompose: {
projectName: path.basename(__dirname),
yamlPath: path.resolve(__dirname, 'docker-compose.yaml'),
},
waitOn: [`tcp:${port}`],
connections: {
oidc: {
connectionString: connectionString.href,
},
},
};
13 changes: 13 additions & 0 deletions docker/oidc/mock-oidc-provider/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3'
services:
mongodb-server-with-mock-oidc-provider:
build: .
ports:
- '27096:27017'
- '29091:29091'
environment:
- OIDC_TOKEN_PAYLOAD_EXPIRES_IN
# comma-separated list
- OIDC_TOKEN_PAYLOAD_GROUPS
- OIDC_TOKEN_PAYLOAD_SUB
- OIDC_TOKEN_PAYLOAD_AUD
60 changes: 60 additions & 0 deletions docker/oidc/mock-oidc-provider/oidc-mock-provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const { OIDCMockProvider } = require('@mongodb-js/oidc-mock-provider');

const DEFAULT_TOKEN_PAYLOAD = {
expires_in: process.env.OIDC_TOKEN_PAYLOAD_EXPIRES_IN
? Number(process.env.OIDC_TOKEN_PAYLOAD_EXPIRES_IN)
: 3600,
payload: {
// Define the user information stored inside the access tokens.
groups: process.env.OIDC_TOKEN_PAYLOAD_GROUPS
? process.env.OIDC_TOKEN_PAYLOAD_GROUPS.split(',')
: ['testgroup'],
sub: process.env.OIDC_TOKEN_PAYLOAD_SUB || 'testuser',
aud: process.env.OIDC_TOKEN_PAYLOAD_AUD || 'resource-server-audience-value',
},
};

(async () => {
const port = process.argv[2];
const proxyPort = process.argv[3];
const serverOidcConfig = {
get issuer() {
return provider.issuer;
},
clientId: 'testServer',
requestScopes: ['mongodbGroups'],
authorizationClaim: 'groups',
audience: 'resource-server-audience-value',
authNamePrefix: 'dev',
};
const provider = await OIDCMockProvider.create({
port: Number(port),
getTokenPayload() {
return DEFAULT_TOKEN_PAYLOAD;
},
overrideRequestHandler(_url, req, res) {
console.log('[OIDC PROVIDER] %s %s', req.method, req.url);
if (req.url === '/server-oidc-config') {
res.setHeader('content-type', 'application/json');
res.write(JSON.stringify(serverOidcConfig));
res.end();
}
},
});
console.log('[OIDC PROVIDER] Listening on %s', provider.issuer);
// To make sure oidc-mock-provider can be used by the server, we need to make
// sure that it's listening on the localhost and the issuer returned by the
// various mock provider requests is matching for all parts of the OIDC flow.
//
// This is tricky in docker environment on macos where we can't run the
// container attached to the host network. We can't use docker hostnames
// either because then we will not be passing various http localhost checks in
// server or oidc-plugin.
//
// To work around that we set up a proxy (see `./proxy.js`) that actually
// listens on all interfaces (0.0.0.0), while mock provider is only listening
// to localhost. To make sure that all responses returned by mock provider are
// matching the proxy address that is exposed outside, we override instance
// issuer property after we start the mock provider.
provider.issuer = `http://localhost:${proxyPort}`;
})();
28 changes: 28 additions & 0 deletions docker/oidc/mock-oidc-provider/proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// see ./oidc-mock-provider.js for why we need this proxy
const http = require('http');

const from = process.argv[2];
const to = process.argv[3];

http
.createServer(function (clientReq, clientRes) {
console.log('[OIDC PROVIDER PROXY] %s %s', clientReq.method, clientReq.url);

const options = {
hostname: 'localhost',
port: to,
path: clientReq.url,
method: clientReq.method,
headers: clientReq.headers,
};

const proxy = http.request(options, function (res) {
clientRes.writeHead(res.statusCode, res.headers);
res.pipe(clientRes, { end: true });
});

clientReq.pipe(proxy, { end: true });
})
.listen(from, '0.0.0.0', () => {
console.log(`[OIDC PROVIDER PROXY] Listening on http://0.0.0.0:${from}`);
});
17 changes: 17 additions & 0 deletions docker/oidc/mock-oidc-provider/start-server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
set -e
OIDC_PROVIDER_PORT=29090
OIDC_PROVIDER_PROXY_PORT=29091
node /tmp/mock-provider/oidc-mock-provider.js $OIDC_PROVIDER_PORT $OIDC_PROVIDER_PROXY_PORT &
node /tmp/mock-provider/proxy.js $OIDC_PROVIDER_PROXY_PORT $OIDC_PROVIDER_PORT &
echo Waiting to make sure that oidc mock provider and proxy are running
until $(curl --output /dev/null --silent --head --fail http://localhost:$OIDC_PROVIDER_PROXY_PORT/.well-known/openid-configuration); do
sleep 0.3
done
echo Starting server
OIDC_IDENTITY_PROVIDERS="[$(curl --fail http://localhost:29091/server-oidc-config)]"
# This is original mongodb/mongodb-enterprise-server entrypoint
python3 /usr/local/bin/docker-entrypoint.py \
--setParameter authenticationMechanisms="SCRAM-SHA-256,MONGODB-OIDC" \
--setParameter enableTestCommands="true" \
--setParameter oidcIdentityProviders="$OIDC_IDENTITY_PROVIDERS"
1 change: 1 addition & 0 deletions scripts/ps-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ docker-compose -f docker/sharded/docker-compose.yaml ps
docker-compose -f docker/ssh/docker-compose.yaml ps
docker-compose -f docker/tls/docker-compose.yaml ps
docker-compose -f docker/kerberos/docker-compose.yaml ps
docker-compose -f docker/oidc/mock-oidc-provider/docker-compose.yaml ps
1 change: 1 addition & 0 deletions scripts/start-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ docker-compose -f docker/sharded/docker-compose.yaml up -d --force-recreate
docker-compose -f docker/ssh/docker-compose.yaml up -d --force-recreate
docker-compose -f docker/tls/docker-compose.yaml up -d --force-recreate
docker-compose -f docker/kerberos/docker-compose.yaml up -d --force-recreate
docker-compose -f docker/oidc/mock-oidc-provider/docker-compose.yaml up -d --force-recreate
1 change: 1 addition & 0 deletions scripts/stop-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ docker-compose -f docker/sharded/docker-compose.yaml down --remove-orphans --vol
docker-compose -f docker/ssh/docker-compose.yaml down --remove-orphans --volumes
docker-compose -f docker/tls/docker-compose.yaml down --remove-orphans --volumes
docker-compose -f docker/kerberos/docker-compose.yaml down --remove-orphans --volumes
docker-compose -f docker/oidc/mock-oidc-provider/docker-compose.yaml down --remove-orphans --volumes
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import scram from '../docker/scram/config';
import sharded from '../docker/sharded/config';
import ssh from '../docker/ssh/config';
import tls from '../docker/tls/config';
import oidc from '../docker/oidc/mock-oidc-provider/config';

const CONFIGS: Record<string, TestEnvironmentConfiguration> = {
community,
Expand All @@ -22,6 +23,7 @@ const CONFIGS: Record<string, TestEnvironmentConfiguration> = {
sharded,
ssh,
tls,
oidc,
};

export default function createTestEnvironments(
Expand Down

0 comments on commit 0799920

Please sign in to comment.