Skip to content

Commit

Permalink
#54: Add e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sevensolutions committed Jan 25, 2025
1 parent 47ce99b commit c2c58f9
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:

- name: Install dependencies
run: npm ci
- name: Prepare tests
run: npm run prepare
- name: Install Playwright Browsers
run: npx playwright install --with-deps

Expand Down
3 changes: 2 additions & 1 deletion e2e/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules/
/playwright-report/
/blob-report/
/playwright/.cache/
.http.yml
.http.yml
**/certificates
1 change: 1 addition & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "1.0.0",
"main": "index.js",
"scripts": {
"prepare": "cd tests/dex && ./gencerts.sh",
"test": "playwright test"
},
"keywords": [],
Expand Down
File renamed without changes.
73 changes: 73 additions & 0 deletions e2e/tests/dex/dex-https.config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
issuer: https://localhost:5554/dex

storage:
type: sqlite3
config:
file: /tmp/dex.db

# Configuration for the HTTP endpoints.
web:
https: 0.0.0.0:5554
tlsCert: /certificates/website_cert/website.pem
tlsKey: /certificates/website_cert/website.key
tlsMinVersion: 1.2
tlsMaxVersion: 1.3

# Configuration for dex appearance
# frontend:
# issuer: dex
# logoURL: theme/logo.png
# dir: web/
# theme: light

# Options for controlling the logger.
# logger:
# level: "debug"
# format: "text" # can also be "json"

staticClients:
- id: traefik
redirectURIs:
- "http://localhost:9080/oidc/callback"
- "https://localhost:9443/oidc/callback"
name: 'Traefik App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
# - id: example-device-client
# redirectURIs:
# - /device/callback
# name: 'Static Client for Device Flow'
# public: true
connectors:
- type: mockCallback
id: mock
name: Example

# Let dex keep a list of passwords which can be used to login to dex.
enablePasswordDB: true

# A static list of passwords to login the end user. By identifying here, dex
# won't look in its underlying storage for passwords.
#
# If this option isn't chosen users may be added through the gRPC API.
staticPasswords:
- email: "[email protected]"
# bcrypt hash of the string "password": $(echo password | htpasswd -BinC 10 admin | cut -d: -f2)
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
- email: "[email protected]"
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: "alice"
userID: "7134d97d-58b0-417d-936f-762661122b00"
- email: "[email protected]"
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: "bob"
userID: "4cbac28e-39f8-4d88-8408-079a97d60c9c"

# Allow password grants with local users
oauth2:
skipApprovalScreen: true
# passwordConnector: local
16 changes: 13 additions & 3 deletions e2e/tests/dex/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
services:
dex:
dex-http:
image: "ghcr.io/dexidp/dex:latest-alpine"
restart: unless-stopped
ports:
- "5556:5556"
volumes:
- "./dex.config.yml:/etc/dex/config.docker.yaml:ro"
- "./dex-http.config.yml:/etc/dex/config.docker.yaml:ro"
dex-https:
image: "ghcr.io/dexidp/dex:latest-alpine"
restart: unless-stopped
ports:
- "5554:5554"
volumes:
- "./dex-https.config.yml:/etc/dex/config.docker.yaml:ro"
- "./certificates:/certificates:ro"

traefik:
image: "traefik:v3.1.4"
Expand All @@ -20,8 +28,10 @@ services:
- "../../../traefik-config.yml:/etc/traefik/traefik.yml:ro"
- "../../..:/plugins-local/src/github.com/sevensolutions/traefik-oidc-auth:ro"
- "../../.http.yml:/etc/traefik/configs/http.yml:ro" # Will be generated by tests
- "./certificates:/certificates:ro"
environment:
PROVIDER_URL: http://dex:5556/dex
PROVIDER_URL_HTTP: http://dex-http:5556/dex
PROVIDER_URL_HTTPS: https://dex-https:5554/dex
CLIENT_ID: traefik
CLIENT_SECRET: ZXhhbXBsZS1hcHAtc2VjcmV0

Expand Down
63 changes: 63 additions & 0 deletions e2e/tests/dex/gencerts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/bin/bash

set -e

# Output directories
ROOT_CA_DIR="certificates/root_ca"
INTERMEDIATE_CA_DIR="certificates/intermediate_ca"
WEBSITE_CERT_DIR="certificates/website_cert"
BUNDLE_DIR="certificates/bundle"

# Remove existing directories
rm -rf $ROOT_CA_DIR $INTERMEDIATE_CA_DIR $WEBSITE_CERT_DIR $BUNDLE_DIR

mkdir -p $ROOT_CA_DIR $INTERMEDIATE_CA_DIR $WEBSITE_CERT_DIR $BUNDLE_DIR

# Root CA
ROOT_KEY="$ROOT_CA_DIR/rootCA.key"
ROOT_CERT="$ROOT_CA_DIR/rootCA.pem"

openssl genrsa -out $ROOT_KEY 4096
openssl req -x509 -new -nodes -key $ROOT_KEY -sha256 -days 3650 -out $ROOT_CERT -subj "/C=US/ST=California/L=San Francisco/O=Root CA/OU=Certificate Authority/CN=Root CA"

echo "Root CA created: $ROOT_CERT"

# Intermediate CA
INTERMEDIATE_KEY="$INTERMEDIATE_CA_DIR/intermediateCA.key"
INTERMEDIATE_CSR="$INTERMEDIATE_CA_DIR/intermediateCA.csr"
INTERMEDIATE_CERT="$INTERMEDIATE_CA_DIR/intermediateCA.pem"

openssl genrsa -out $INTERMEDIATE_KEY 4096
openssl req -new -key $INTERMEDIATE_KEY -out $INTERMEDIATE_CSR -subj "/C=US/ST=California/L=San Francisco/O=Intermediate CA/OU=Certificate Authority/CN=Intermediate CA"

openssl x509 -req -in $INTERMEDIATE_CSR -CA $ROOT_CERT -CAkey $ROOT_KEY -CAcreateserial -out $INTERMEDIATE_CERT -days 3650 -sha256 \
-extfile <(printf "basicConstraints=CA:TRUE\nkeyUsage=keyCertSign,cRLSign")

echo "Intermediate CA created: $INTERMEDIATE_CERT"

# Bundle file (Root CA + Intermediate CA)
BUNDLE_FILE="$BUNDLE_DIR/ca_bundle.pem"
cat $INTERMEDIATE_CERT $ROOT_CERT > $BUNDLE_FILE
echo "CA bundle created: $BUNDLE_FILE"

# Website Certificate
WEBSITE_KEY="$WEBSITE_CERT_DIR/website.key"
WEBSITE_CSR="$WEBSITE_CERT_DIR/website.csr"
WEBSITE_CERT="$WEBSITE_CERT_DIR/website.pem"

openssl genrsa -out $WEBSITE_KEY 2048
openssl req -new -key $WEBSITE_KEY -out $WEBSITE_CSR -subj "/C=US/ST=California/L=San Francisco/O=Example Website/OU=IT Department/CN=dex-https"

openssl x509 -req -in $WEBSITE_CSR -CA $INTERMEDIATE_CERT -CAkey $INTERMEDIATE_KEY -CAcreateserial -out $WEBSITE_CERT -days 825 -sha256 \
-extfile <(printf "subjectAltName=DNS:dex-https,DNS:localhost,IP:127.0.0.1\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth")

echo "Website certificate created: $WEBSITE_CERT"

# Summary
cat <<EOF
Certificates created successfully:
- Root CA: $ROOT_CERT
- Intermediate CA: $INTERMEDIATE_CERT
- Website Cert: $WEBSITE_CERT
- CA Bundle: $BUNDLE_FILE
EOF
52 changes: 46 additions & 6 deletions e2e/tests/dex/simple-login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ http:
traefik-oidc-auth:
LogLevel: DEBUG
Provider:
UrlEnv: "PROVIDER_URL"
UrlEnv: "PROVIDER_URL_HTTP"
ClientIdEnv: "CLIENT_ID"
ClientSecretEnv: "CLIENT_SECRET"
UsePkce: false
Expand Down Expand Up @@ -105,7 +105,7 @@ http:
traefik-oidc-auth:
LogLevel: DEBUG
Provider:
UrlEnv: "PROVIDER_URL"
UrlEnv: "PROVIDER_URL_HTTP"
ClientIdEnv: "CLIENT_ID"
ClientSecretEnv: "CLIENT_SECRET"
UsePkce: false
Expand Down Expand Up @@ -155,7 +155,7 @@ http:
traefik-oidc-auth:
LogLevel: DEBUG
Provider:
UrlEnv: "PROVIDER_URL"
UrlEnv: "PROVIDER_URL_HTTP"
ClientIdEnv: "CLIENT_ID"
ClientSecretEnv: "CLIENT_SECRET"
UsePkce: false
Expand Down Expand Up @@ -194,7 +194,7 @@ http:
traefik-oidc-auth:
LogLevel: DEBUG
Provider:
UrlEnv: "PROVIDER_URL"
UrlEnv: "PROVIDER_URL_HTTP"
ClientIdEnv: "CLIENT_ID"
ClientSecretEnv: "CLIENT_SECRET"
UsePkce: false
Expand All @@ -218,13 +218,53 @@ http:
expect(response.status()).toBe(401);
});

test("login at provider via self signed certificate", async ({ page }) => {
await configureTraefik(`
http:
services:
whoami:
loadBalancer:
servers:
- url: http://whoami:80
middlewares:
oidc-auth:
plugin:
traefik-oidc-auth:
LogLevel: DEBUG
Provider:
UrlEnv: "PROVIDER_URL_HTTPS"
CACertificateFilePath: "/certificates/bundle/ca_bundle.pem"
ClientIdEnv: "CLIENT_ID"
ClientSecretEnv: "CLIENT_SECRET"
UsePkce: false
routers:
whoami:
entryPoints: ["web"]
rule: "HostRegexp(\`.+\`)"
service: whoami
middlewares: ["oidc-auth@file"]
whoami-secure:
entryPoints: ["websecure"]
tls: {}
rule: "HostRegexp(\`.+\`)"
service: whoami
middlewares: ["oidc-auth@file"]
`);

await page.goto("https://localhost:9443");

const response = await login(page, "[email protected]", "password", "https://localhost:9443");

expect(response.status()).toBe(200);
});

//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------

async function login(page: Page, username: string, password: string, waitForUrl: string): Promise<Response> {
await page.waitForURL("http://localhost:5556/dex/auth**");

await page.locator(':text("Log in with Email")').click();

await page.locator("#login").fill(username);
Expand Down

0 comments on commit c2c58f9

Please sign in to comment.