Skip to content

Commit

Permalink
ZENKO-2659 E2E test user authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas2bert committed Jul 7, 2020
1 parent ebbb826 commit c091051
Show file tree
Hide file tree
Showing 18 changed files with 1,039 additions and 41 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"plugin:react/recommended",
"plugin:jest/recommended",
"plugin:flowtype/recommended",
"plugin:react-hooks/recommended"
"plugin:react-hooks/recommended",
"plugin:cypress/recommended"
],
"settings": {
"react": {
Expand Down
4 changes: 4 additions & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"baseUrl": "http://127.0.0.1:8383",
"video": false
}
29 changes: 29 additions & 0 deletions cypress/integration/auth_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint jest/expect-expect: 0 */

describe('Authentication with keycloak', () => {
describe('User authenticated', () => {
beforeEach(cy.kcLogin);

it(`should render user full name: ${Cypress.env('KEYCLOAK_USER_FULLNAME')}`, () => {
const kcUserFullname = Cypress.env('KEYCLOAK_USER_FULLNAME');
if (!kcUserFullname) {
throw new Error('missing CYPRESS_KEYCLOAK_USER_FULLNAME environment variable');
}

cy.visit('/');
cy.get('.sc-navbar').should('exist');
// NOTE: this value is based on "eve/workers/keycloakconfig/keycloak-realm.json"
cy.get('.sc-navbar').should('contain', kcUserFullname);
});

afterEach(cy.kcLogout);
});

describe('User not authenticated', () => {
it('should not render user name', () => {
cy.visit('/');
cy.get('.sc-navbar').should('not.exist');
cy.url();
});
});
});
21 changes: 21 additions & 0 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************

// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)

/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
64 changes: 64 additions & 0 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
Cypress.Commands.add('kcLogin', (username, password) => {
Cypress.log({ name: 'keycloak login' });

const kcUsername = username || Cypress.env('KEYCLOAK_USERNAME');
const kcPassword = password || Cypress.env('KEYCLOAK_PASSWORD');
const kcRoot = Cypress.env('KEYCLOAK_ROOT');
const kcRealm = Cypress.env('KEYCLOAK_REALM');
const kcClientID = Cypress.env('KEYCLOAK_CLIENT_ID');

if (!kcUsername || !kcPassword || !kcRoot || !kcRealm || !kcClientID) {
throw new Error('missing CYPRESS_KEYCLOAK_USERNAME, CYPRESS_KEYCLOAK_PASSWORD, CYPRESS_KEYCLOAK_ROOT, CYPRESS_KEYCLOAK_REALM or CYPRESS_KEYCLOAK_CLIENT_ID environment variable');
}

const getStartBody = {
url: `${kcRoot}/auth/realms/${kcRealm}/protocol/openid-connect/auth`,
followRedirect: false,
qs: {
scope: 'openid',
response_type: 'code',
approval_prompt: 'auto',
redirect_uri: `${Cypress.config('baseUrl')}/login/callback`,
client_id: kcClientID,
},
};
return cy.request(getStartBody).then(response => {
const html = document.createElement('html');
html.innerHTML = response.body;

const form = html.getElementsByTagName('form')[0];
const url = form.action;
const postLoginBody = {
method: 'POST',
url,
followRedirect: false,
form: true,
body: {
username: kcUsername,
password: kcPassword,
},
};
return cy.request(postLoginBody);
});
});

Cypress.Commands.add('kcLogout', () => {
Cypress.log({ name: 'keycloak logout' });

const kcRoot = Cypress.env('KEYCLOAK_ROOT');
const kcRealm = Cypress.env('KEYCLOAK_REALM');

if (!kcRoot || !kcRealm) {
throw new Error('missing CYPRESS_KEYCLOAK_ROOT and/or CYPRESS_KEYCLOAK_REALM environment variable');
}

cy.clearSession();
return cy.request({
url: `${kcRoot}/auth/realms/${kcRealm}/protocol/openid-connect/logout`,
});
});

Cypress.Commands.add('clearSession', () => {
Cypress.log({ name: 'Clear Session' });
cy.window().then(window => window.sessionStorage.clear());
});
20 changes: 20 additions & 0 deletions cypress/support/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands';

// Alternatively you can use CommonJS syntax:
// require('./commands')
29 changes: 29 additions & 0 deletions eve/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ branches:
models:
- env: &deploy-env
SCALITY_OCI_REPO: registry.scality.com/scality/zenko-ui
- env: &keycloak-env
KEYCLOAK_ROOT: "http://127.0.0.1:8080"
KEYCLOAK_REALM: "myrealm"
KEYCLOAK_CLIENT_ID: "myclient"
KEYCLOAK_USERNAME: "bartsimpson"
KEYCLOAK_PASSWORD: "123"
KEYCLOAK_USER_FIRSTNAME: "Bart"
KEYCLOAK_USER_LASTNAME: "Simpson"
- Git: &clone
name: fetch source
repourl: '%(prop:git_reference)s'
Expand Down Expand Up @@ -39,6 +47,10 @@ stages:
path: eve/workers/worker.yaml
images:
build: eve/workers/build
keycloakconfig: eve/workers/keycloakconfig
vars:
keycloakconfig:
env: *keycloak-env
steps:
- Git: *clone
- ShellCommand: *yarn-install
Expand All @@ -48,6 +60,23 @@ stages:
haltOnFailure: True
- ShellCommand: *yarn-build
- ShellCommand: *docker-build
- ShellCommand:
name: run end-to-end tests
command: >-
docker run -d -p 8383:8383 ${SCALITY_OCI_REPO}:%(prop:commit_short_revision)s;
set -exu;
bash wait_for_local_port.bash 8080 40;
bash wait_for_local_port.bash 8383 40;
CYPRESS_KEYCLOAK_USER_FULLNAME="${KEYCLOAK_USER_FIRSTNAME} ${KEYCLOAK_USER_LASTNAME}"
CYPRESS_KEYCLOAK_USERNAME=${KEYCLOAK_USERNAME}
CYPRESS_KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
CYPRESS_KEYCLOAK_ROOT=${KEYCLOAK_ROOT}
CYPRESS_KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID}
CYPRESS_KEYCLOAK_REALM=${KEYCLOAK_REALM} yarn run cypress:run;
haltOnFailure: True
env:
<<: *deploy-env
<<: *keycloak-env
post-merge:
worker: *worker
steps:
Expand Down
2 changes: 1 addition & 1 deletion eve/workers/build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -

COPY ./pensieve_packages.list ./buildbot_worker_packages.list /tmp/
COPY ./zenko_packages.list ./buildbot_worker_packages.list ./cypress_packages.list /tmp/
RUN apt-get update \
&& cat /tmp/*packages.list | xargs apt-get install -y

Expand Down
10 changes: 10 additions & 0 deletions eve/workers/build/cypress_packages.list
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
libgtk2.0-0
libgtk-3-0
libnotify-dev
libgconf-2-4
libnss3
libxss1
libasound2
libxtst6
xauth
xvfb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
nodejs
yarn=1.9.4-1
netcat
18 changes: 18 additions & 0 deletions eve/workers/keycloakconfig/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM jboss/keycloak:10.0.2

USER root

# install jq
RUN microdnf install wget
RUN wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
RUN chmod +x ./jq
RUN cp jq /usr/bin

COPY keycloak-realm.json /config/keycloak-realm.json
COPY entrypoint.sh /

WORKDIR /config

ENTRYPOINT ["/entrypoint.sh"]

CMD ["-b 0.0.0.0 -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=/config/keycloak-realm.json"]
35 changes: 35 additions & 0 deletions eve/workers/keycloakconfig/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

# set -e stops the execution of a script if a command or pipeline has an error
set -e

# modifying keycloak-realm.json
JQ_FILTERS_REALM="."

if [[ "$KEYCLOAK_REALM" ]] ; then
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .realm=\"$KEYCLOAK_REALM\""
fi

if [[ "$KEYCLOAK_CLIENT_ID" ]] ; then
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .clients[0].clientId=\"$KEYCLOAK_CLIENT_ID\""
fi

if [[ "$KEYCLOAK_USERNAME" ]] ; then
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .users[0].username=\"$KEYCLOAK_USERNAME\""
fi

if [[ "$KEYCLOAK_USER_FIRSTNAME" ]] ; then
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .users[0].firstName=\"$KEYCLOAK_USER_FIRSTNAME\""
fi

if [[ "$KEYCLOAK_USER_LASTNAME" ]] ; then
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .users[0].lastName=\"$KEYCLOAK_USER_LASTNAME\""
fi

if [[ $JQ_FILTERS_REALM != "." ]]; then
jq "$JQ_FILTERS_REALM" keycloak-realm.json > keycloak-realm.json.tmp
mv keycloak-realm.json.tmp keycloak-realm.json
fi

# LAUNCH keycloak entrypoint
/opt/jboss/tools/docker-entrypoint.sh $@
Loading

0 comments on commit c091051

Please sign in to comment.