Skip to content

Commit c091051

Browse files
committed
ZENKO-2659 E2E test user authentication
1 parent ebbb826 commit c091051

File tree

18 files changed

+1039
-41
lines changed

18 files changed

+1039
-41
lines changed

.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
"plugin:react/recommended",
5151
"plugin:jest/recommended",
5252
"plugin:flowtype/recommended",
53-
"plugin:react-hooks/recommended"
53+
"plugin:react-hooks/recommended",
54+
"plugin:cypress/recommended"
5455
],
5556
"settings": {
5657
"react": {

cypress.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"baseUrl": "http://127.0.0.1:8383",
3+
"video": false
4+
}

cypress/integration/auth_spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* eslint jest/expect-expect: 0 */
2+
3+
describe('Authentication with keycloak', () => {
4+
describe('User authenticated', () => {
5+
beforeEach(cy.kcLogin);
6+
7+
it(`should render user full name: ${Cypress.env('KEYCLOAK_USER_FULLNAME')}`, () => {
8+
const kcUserFullname = Cypress.env('KEYCLOAK_USER_FULLNAME');
9+
if (!kcUserFullname) {
10+
throw new Error('missing CYPRESS_KEYCLOAK_USER_FULLNAME environment variable');
11+
}
12+
13+
cy.visit('/');
14+
cy.get('.sc-navbar').should('exist');
15+
// NOTE: this value is based on "eve/workers/keycloakconfig/keycloak-realm.json"
16+
cy.get('.sc-navbar').should('contain', kcUserFullname);
17+
});
18+
19+
afterEach(cy.kcLogout);
20+
});
21+
22+
describe('User not authenticated', () => {
23+
it('should not render user name', () => {
24+
cy.visit('/');
25+
cy.get('.sc-navbar').should('not.exist');
26+
cy.url();
27+
});
28+
});
29+
});

cypress/plugins/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/// <reference types="cypress" />
2+
// ***********************************************************
3+
// This example plugins/index.js can be used to load plugins
4+
//
5+
// You can change the location of this file or turn off loading
6+
// the plugins file with the 'pluginsFile' configuration option.
7+
//
8+
// You can read more here:
9+
// https://on.cypress.io/plugins-guide
10+
// ***********************************************************
11+
12+
// This function is called when a project is opened or re-opened (e.g. due to
13+
// the project's config changing)
14+
15+
/**
16+
* @type {Cypress.PluginConfig}
17+
*/
18+
module.exports = (on, config) => {
19+
// `on` is used to hook into various events Cypress emits
20+
// `config` is the resolved Cypress config
21+
}

cypress/support/commands.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Cypress.Commands.add('kcLogin', (username, password) => {
2+
Cypress.log({ name: 'keycloak login' });
3+
4+
const kcUsername = username || Cypress.env('KEYCLOAK_USERNAME');
5+
const kcPassword = password || Cypress.env('KEYCLOAK_PASSWORD');
6+
const kcRoot = Cypress.env('KEYCLOAK_ROOT');
7+
const kcRealm = Cypress.env('KEYCLOAK_REALM');
8+
const kcClientID = Cypress.env('KEYCLOAK_CLIENT_ID');
9+
10+
if (!kcUsername || !kcPassword || !kcRoot || !kcRealm || !kcClientID) {
11+
throw new Error('missing CYPRESS_KEYCLOAK_USERNAME, CYPRESS_KEYCLOAK_PASSWORD, CYPRESS_KEYCLOAK_ROOT, CYPRESS_KEYCLOAK_REALM or CYPRESS_KEYCLOAK_CLIENT_ID environment variable');
12+
}
13+
14+
const getStartBody = {
15+
url: `${kcRoot}/auth/realms/${kcRealm}/protocol/openid-connect/auth`,
16+
followRedirect: false,
17+
qs: {
18+
scope: 'openid',
19+
response_type: 'code',
20+
approval_prompt: 'auto',
21+
redirect_uri: `${Cypress.config('baseUrl')}/login/callback`,
22+
client_id: kcClientID,
23+
},
24+
};
25+
return cy.request(getStartBody).then(response => {
26+
const html = document.createElement('html');
27+
html.innerHTML = response.body;
28+
29+
const form = html.getElementsByTagName('form')[0];
30+
const url = form.action;
31+
const postLoginBody = {
32+
method: 'POST',
33+
url,
34+
followRedirect: false,
35+
form: true,
36+
body: {
37+
username: kcUsername,
38+
password: kcPassword,
39+
},
40+
};
41+
return cy.request(postLoginBody);
42+
});
43+
});
44+
45+
Cypress.Commands.add('kcLogout', () => {
46+
Cypress.log({ name: 'keycloak logout' });
47+
48+
const kcRoot = Cypress.env('KEYCLOAK_ROOT');
49+
const kcRealm = Cypress.env('KEYCLOAK_REALM');
50+
51+
if (!kcRoot || !kcRealm) {
52+
throw new Error('missing CYPRESS_KEYCLOAK_ROOT and/or CYPRESS_KEYCLOAK_REALM environment variable');
53+
}
54+
55+
cy.clearSession();
56+
return cy.request({
57+
url: `${kcRoot}/auth/realms/${kcRealm}/protocol/openid-connect/logout`,
58+
});
59+
});
60+
61+
Cypress.Commands.add('clearSession', () => {
62+
Cypress.log({ name: 'Clear Session' });
63+
cy.window().then(window => window.sessionStorage.clear());
64+
});

cypress/support/index.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// ***********************************************************
2+
// This example support/index.js is processed and
3+
// loaded automatically before your test files.
4+
//
5+
// This is a great place to put global configuration and
6+
// behavior that modifies Cypress.
7+
//
8+
// You can change the location of this file or turn off
9+
// automatically serving support files with the
10+
// 'supportFile' configuration option.
11+
//
12+
// You can read more here:
13+
// https://on.cypress.io/configuration
14+
// ***********************************************************
15+
16+
// Import commands.js using ES2015 syntax:
17+
import './commands';
18+
19+
// Alternatively you can use CommonJS syntax:
20+
// require('./commands')

eve/main.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ branches:
1010
models:
1111
- env: &deploy-env
1212
SCALITY_OCI_REPO: registry.scality.com/scality/zenko-ui
13+
- env: &keycloak-env
14+
KEYCLOAK_ROOT: "http://127.0.0.1:8080"
15+
KEYCLOAK_REALM: "myrealm"
16+
KEYCLOAK_CLIENT_ID: "myclient"
17+
KEYCLOAK_USERNAME: "bartsimpson"
18+
KEYCLOAK_PASSWORD: "123"
19+
KEYCLOAK_USER_FIRSTNAME: "Bart"
20+
KEYCLOAK_USER_LASTNAME: "Simpson"
1321
- Git: &clone
1422
name: fetch source
1523
repourl: '%(prop:git_reference)s'
@@ -39,6 +47,10 @@ stages:
3947
path: eve/workers/worker.yaml
4048
images:
4149
build: eve/workers/build
50+
keycloakconfig: eve/workers/keycloakconfig
51+
vars:
52+
keycloakconfig:
53+
env: *keycloak-env
4254
steps:
4355
- Git: *clone
4456
- ShellCommand: *yarn-install
@@ -48,6 +60,23 @@ stages:
4860
haltOnFailure: True
4961
- ShellCommand: *yarn-build
5062
- ShellCommand: *docker-build
63+
- ShellCommand:
64+
name: run end-to-end tests
65+
command: >-
66+
docker run -d -p 8383:8383 ${SCALITY_OCI_REPO}:%(prop:commit_short_revision)s;
67+
set -exu;
68+
bash wait_for_local_port.bash 8080 40;
69+
bash wait_for_local_port.bash 8383 40;
70+
CYPRESS_KEYCLOAK_USER_FULLNAME="${KEYCLOAK_USER_FIRSTNAME} ${KEYCLOAK_USER_LASTNAME}"
71+
CYPRESS_KEYCLOAK_USERNAME=${KEYCLOAK_USERNAME}
72+
CYPRESS_KEYCLOAK_PASSWORD=${KEYCLOAK_PASSWORD}
73+
CYPRESS_KEYCLOAK_ROOT=${KEYCLOAK_ROOT}
74+
CYPRESS_KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID}
75+
CYPRESS_KEYCLOAK_REALM=${KEYCLOAK_REALM} yarn run cypress:run;
76+
haltOnFailure: True
77+
env:
78+
<<: *deploy-env
79+
<<: *keycloak-env
5180
post-merge:
5281
worker: *worker
5382
steps:

eve/workers/build/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
99
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
1010
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
1111

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
libgtk2.0-0
2+
libgtk-3-0
3+
libnotify-dev
4+
libgconf-2-4
5+
libnss3
6+
libxss1
7+
libasound2
8+
libxtst6
9+
xauth
10+
xvfb
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
nodejs
22
yarn=1.9.4-1
3+
netcat

eve/workers/keycloakconfig/Dockerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM jboss/keycloak:10.0.2
2+
3+
USER root
4+
5+
# install jq
6+
RUN microdnf install wget
7+
RUN wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
8+
RUN chmod +x ./jq
9+
RUN cp jq /usr/bin
10+
11+
COPY keycloak-realm.json /config/keycloak-realm.json
12+
COPY entrypoint.sh /
13+
14+
WORKDIR /config
15+
16+
ENTRYPOINT ["/entrypoint.sh"]
17+
18+
CMD ["-b 0.0.0.0 -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=singleFile -Dkeycloak.migration.file=/config/keycloak-realm.json"]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
3+
# set -e stops the execution of a script if a command or pipeline has an error
4+
set -e
5+
6+
# modifying keycloak-realm.json
7+
JQ_FILTERS_REALM="."
8+
9+
if [[ "$KEYCLOAK_REALM" ]] ; then
10+
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .realm=\"$KEYCLOAK_REALM\""
11+
fi
12+
13+
if [[ "$KEYCLOAK_CLIENT_ID" ]] ; then
14+
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .clients[0].clientId=\"$KEYCLOAK_CLIENT_ID\""
15+
fi
16+
17+
if [[ "$KEYCLOAK_USERNAME" ]] ; then
18+
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .users[0].username=\"$KEYCLOAK_USERNAME\""
19+
fi
20+
21+
if [[ "$KEYCLOAK_USER_FIRSTNAME" ]] ; then
22+
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .users[0].firstName=\"$KEYCLOAK_USER_FIRSTNAME\""
23+
fi
24+
25+
if [[ "$KEYCLOAK_USER_LASTNAME" ]] ; then
26+
JQ_FILTERS_REALM="$JQ_FILTERS_REALM | .users[0].lastName=\"$KEYCLOAK_USER_LASTNAME\""
27+
fi
28+
29+
if [[ $JQ_FILTERS_REALM != "." ]]; then
30+
jq "$JQ_FILTERS_REALM" keycloak-realm.json > keycloak-realm.json.tmp
31+
mv keycloak-realm.json.tmp keycloak-realm.json
32+
fi
33+
34+
# LAUNCH keycloak entrypoint
35+
/opt/jboss/tools/docker-entrypoint.sh $@

0 commit comments

Comments
 (0)