Skip to content

[Backport 2.x] Cypress13 testing frame work for OIDC and SAML #150

[Backport 2.x] Cypress13 testing frame work for OIDC and SAML

[Backport 2.x] Cypress13 testing frame work for OIDC and SAML #150

name: Snapshot based E2E OIDC tests workflow
on:
pull_request:
branches: [ '**' ]
env:
OPENSEARCH_VERSION: '2.12.0'
KEYCLOAK_VERSION: '21.0.1'
TEST_KEYCLOAK_CLIENT_SECRET: 'oacHfNaXyy81r2uHq1A9RY4ASryre4rZ'
CI: 1
# avoid warnings like "tput: No value for $TERM and no -T specified"
TERM: xterm
PLUGIN_NAME: opensearch-security
# This is the SHA256 checksum of the known good kc.sh script for Keycloak version 21.0.1.
KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT: 'f825ea1a9ffa5ad91673737c06857ababbb69b6b8f09e0c637b4c998517f9608'
jobs:
tests:
name: Run Cypress E2E OIDC tests
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
steps:
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 11
- name: Checkout Branch
uses: actions/checkout@v3
- name: Set env
run: |
opensearch_version=$(node -p "require('./package.json').opensearchDashboards.version")
plugin_version=$(node -p "require('./package.json').version")
echo "OPENSEARCH_VERSION=$opensearch_version" >> $GITHUB_ENV
echo "PLUGIN_VERSION=$plugin_version" >> $GITHUB_ENV
shell: bash
# Download and Check Keycloak Version
- name: Download and Check Keyloak Version on Linux
if: ${{ runner.os == 'Linux' }}
run: |
echo "Downloading Keycloak ${{ env.KEYCLOAK_VERSION }}"
wget https://github.com/keycloak/keycloak/releases/download/${{ env.KEYCLOAK_VERSION }}/keycloak-${{ env.KEYCLOAK_VERSION }}.tar.gz
echo "Unpacking Keycloak"
tar -xzf keycloak-${{ env.KEYCLOAK_VERSION }}.tar.gz
cd keycloak-${{ env.KEYCLOAK_VERSION }}/bin
chmod +x ./kc.sh
echo "Generating checksum for the downloaded kc.sh script..."
DOWNLOADED_CHECKSUM=$(sha256sum kc.sh | awk '{print $1}')
echo "Downloaded kc.sh checksum: $DOWNLOADED_CHECKSUM"
echo "Known good kc.sh checksum: ${{ env.KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT }}"
KNOWN_GOOD_CHECKSUM="${{ env.KNOWN_CHECKSUM_OF_KEYCLOAK_SCRIPT }}"
if [ "$DOWNLOADED_CHECKSUM" != "$KNOWN_GOOD_CHECKSUM" ]; then
echo "Checksum mismatch. The kc.sh script does not match the known good version. Please check https://github.com/keycloak/keycloak and verify the updates."
exit 1
else
echo "Checksum match confirmed. Proceeding with setup."
fi
chmod +x ./kc.sh
# Setup and Run Keycloak
- name: Get and run Keycloak on Linux
if: ${{ runner.os == 'Linux' }}
run: |
export KEYCLOAK_ADMIN=admin
export KEYCLOAK_ADMIN_PASSWORD=admin
cd keycloak-${{ env.KEYCLOAK_VERSION }}/bin
echo "Starting keycloak"
./kc.sh start-dev --http-enabled=true --hostname-strict-https=false --http-host=localhost --http-relative-path /auth --health-enabled=true &
timeout 300 bash -c 'while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8080/auth/health)" != "200" ]]; do sleep 5; done'
chmod +x kcadm.sh
echo "Creating client"
./kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password admin
CID=$(./kcadm.sh create clients -r master -s clientId=opensearch -s secret="${{ env.TEST_KEYCLOAK_CLIENT_SECRET }}" -s 'attributes."access.token.lifespan"=60' -s 'redirectUris=["http://localhost:5603/auth/openid/login", "http://localhost:5601", "http://localhost:5601/auth/openid/login"]' -i)
./kcadm.sh get clients/$CID/installation/providers/keycloak-oidc-keycloak-json > tmp
echo "Getting client secret for dashboards configuration purpose"
CLIENT_SECRET=$(grep -o '"secret" : "[^"]*' tmp | grep -o '[^"]*$')
echo "KEYCLOAK_CLIENT_SECRET=$CLIENT_SECRET" >> $GITHUB_ENV
echo "The client secret is: $CLIENT_SECRET"
echo "Creating client mapper"
./kcadm.sh create clients/$CID/protocol-mappers/models -r master -s 'config."id.token.claim"=true' -s 'config."multivalued"=true' -s 'config."claim.name"="roles"' -s 'config."userinfo.token.claim"=true' -s 'config."access.token.claim"=true' -s 'name=rolemapper' -s 'protocolMapper=oidc-usermodel-realm-role-mapper' -s "protocol=openid-connect"
- name: Download security plugin and create setup scripts
uses: ./.github/actions/download-plugin
with:
opensearch-version: ${{ env.OPENSEARCH_VERSION }}
plugin-name: ${{ env.PLUGIN_NAME }}
plugin-version: ${{ env.PLUGIN_VERSION }}
# Download OpenSearch
- name: Download OpenSearch for Linux
uses: peternied/download-file@v2
if: ${{ runner.os == 'Linux' }}
with:
url: https://artifacts.opensearch.org/snapshots/core/opensearch/${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/opensearch-min-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT-linux-x64-latest.tar.gz
# Extract downloaded tar/zip
- name: Extract downloaded tar
if: ${{ runner.os == 'Linux' }}
run: |
tar -xzf opensearch-*.tar.gz
rm -f opensearch-*.tar.gz
shell: bash
# Install the security plugin
- name: Install Plugin into OpenSearch for Linux
if: ${{ runner.os == 'Linux'}}
run: |
chmod +x ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin
/bin/bash -c "yes | ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch-plugin install file:$(pwd)/opensearch-security.zip"
shell: bash
# Add OIDC Configuration
- name: Injecting OIDC Configuration for Linux
if: ${{ runner.os == 'Linux'}}
run: |
echo "Creating new SAML configuration"
cd ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/opensearch-security/
rm -rf config.yml
cat << 'EOT' > config.yml
---
_meta:
type: "config"
config_version: 2
config:
dynamic:
http:
anonymous_auth_enabled: false
authc:
basic_internal_auth_domain:
description: "Authenticate via HTTP Basic against internal users database"
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: basic
challenge: false
authentication_backend:
type: intern
openid_auth_domain:
http_enabled: true
transport_enabled: true
order: 1
http_authenticator:
type: openid
challenge: false
config:
subject_key: preferred_username
roles_key: roles
openid_connect_url: http://localhost:8080/auth/realms/master/.well-known/openid-configuration
authentication_backend:
type: noop
EOT
echo "THIS IS THE SECURITY CONFIG FILE: "
cat config.yml
# TODO: REMOVE THIS ONCE ADMIN JAVA TOOL SUPPORT IT
- name: Write password to initialAdminPassword location
if: ${{ runner.os == 'Linux'}}
run:
echo admin >> ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/config/initialAdminPassword.txt
shell: bash
# Run any configuration scripts
- name: Run Setup Script for Linux
if: ${{ runner.os == 'Linux' }}
run: |
echo "running linux setup"
chmod +x ./setup.sh
./setup.sh
shell: bash
# Run OpenSearch
- name: Run OpenSearch with plugin on Linux
if: ${{ runner.os == 'Linux'}}
run: |
/bin/bash -c "./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/bin/opensearch &"
shell: bash
# Give the OpenSearch process some time to boot up before sending any requires, might need to increase the default time!
- name: Sleep while OpenSearch starts
uses: peternied/action-sleep@v1
with:
seconds: 30
# Verify that the server is operational
- name: Check OpenSearch Running on Linux
if: ${{ runner.os != 'Windows'}}
run: curl https://localhost:9200/_cat/plugins -u 'admin:admin' -k -v
shell: bash
- if: always()
run: cat ./opensearch-${{ env.OPENSEARCH_VERSION }}-SNAPSHOT/logs/opensearch.log
shell: bash
# OSD bootstrap
- name: Run Dashboard with Security Dashboards Plugin
uses: ./.github/actions/install-dashboards
with:
plugin_name: security-dashboards-plugin
# Configure the Dashboard for OIDC setup
- name: Configure and Run OpenSearch Dashboards with Cypress Test Cases
if: ${{ runner.os == 'Linux' }}
run: |
cd ./OpenSearch-Dashboards
rm -rf ./config/opensearch_dashboards.yml
cat << 'EOT' > ./config/opensearch_dashboards.yml
server.host: "localhost"
opensearch.hosts: ["https://localhost:9200"]
opensearch.ssl.verificationMode: none
opensearch.username: "kibanaserver"
opensearch.password: "kibanaserver"
opensearch.requestHeadersWhitelist: [ authorization,securitytenant ]
opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: ["Private", "Global"]
opensearch_security.readonly_mode.roles: ["kibana_read_only"]
opensearch_security.cookie.secure: false
opensearch_security.openid.connect_url: "http://127.0.0.1:8080/auth/realms/master/.well-known/openid-configuration"
opensearch_security.openid.client_id: "opensearch"
opensearch_security.openid.client_secret: "${{ env.TEST_KEYCLOAK_CLIENT_SECRET }}"
opensearch_security.auth.type: ["openid"]
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.ui.openid.login.buttonname: "OIDC"
home.disableWelcomeScreen: true
EOT
echo 'HERE IS THE DASHBOARD CONFIG FILE: '
cat ./config/opensearch_dashboards.yml
nohup yarn start --no-base-path --no-watch | tee dashboard.log &
# Check if OSD is ready with a max timeout of 600 seconds
- name : Check If OpenSearch Dashboards Is Ready
if: ${{ runner.os == 'Linux' }}
run: |
cd ./OpenSearch-Dashboards
echo "Start checking OpenSearch Dashboards."
for i in {1..60}; do
if grep -q "bundles compiled successfully after" "dashboard.log"; then
echo "OpenSearch Dashboards compiled successfully."
break
fi
if [ $i -eq 60 ]; then
echo "Timeout for 600 seconds reached. OpenSearch Dashboards did not finish compiling."
exit 1
fi
sleep 10
done
- name: Run Cypress
run : |
yarn add cypress --save-dev
yarn cypress:run --browser chrome --headless --spec 'test/cypress/e2e/oidc/*.js'