Skip to content

Commit c091051

Browse files
committedJul 7, 2020
ZENKO-2659 E2E test user authentication
1 parent ebbb826 commit c091051

18 files changed

+1039
-41
lines changed
 

‎.eslintrc.json

+2-1
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

+4
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

+29
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

+21
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

+64
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

+20
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

+29
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

+1-1
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

+10
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
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

+18
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"]
+35
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 $@
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
{
2+
"id" : "id1",
3+
"realm" : "your_realm_name",
4+
"enabled" : true,
5+
"groups" : [ ],
6+
"defaultRoles" : [ "uma_authorization", "offline_access" ],
7+
"requiredCredentials" : [ "password" ],
8+
"users" : [ {
9+
"id" : "c3f558f4-6294-42af-934b-71fe9f122ca5",
10+
"createdTimestamp" : 1593468883202,
11+
"username" : "your_username",
12+
"enabled" : true,
13+
"totp" : false,
14+
"emailVerified" : true,
15+
"firstName" : "your_first_name",
16+
"lastName" : "your_last_name",
17+
"email" : "sampleaccount1@sampling.com",
18+
"attributes" : {
19+
"instanceIds" : [ "c304a58e-9d8c-412d-b451-5afc906263dc" ],
20+
"role" : [ "user" ]
21+
},
22+
"credentials" : [ {
23+
"id" : "0c82f429-068d-4f13-a0e3-608b4393c87f",
24+
"type" : "password",
25+
"createdDate" : 1593468895101,
26+
"secretData" : "{\"value\":\"C3EIxV4fsfvDIj6jM0N48qk+j2LAsPXDVJ3VFSLEHMS+1Ah1HIZDAvuqA8AQd/8j12CvboFw6Bv/00KeDyC+bA==\",\"salt\":\"F2M/n/GExVWSwHMvoTOKUA==\"}",
27+
"credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\"}"
28+
} ],
29+
"disableableCredentialTypes" : [ ],
30+
"requiredActions" : [ ],
31+
"realmRoles" : [ "uma_authorization", "offline_access" ],
32+
"clientRoles" : {
33+
"account" : [ "view-profile", "manage-account" ]
34+
},
35+
"notBefore" : 0,
36+
"groups" : [ ]
37+
} ],
38+
"clients" : [ {
39+
"id" : "368a7d78-07cc-41c2-8510-b485629597ce",
40+
"clientId" : "your_client_name",
41+
"rootUrl" : "http://127.0.0.1:8383",
42+
"adminUrl" : "http://127.0.0.1:8383",
43+
"surrogateAuthRequired" : false,
44+
"enabled" : true,
45+
"alwaysDisplayInConsole" : false,
46+
"clientAuthenticatorType" : "client-secret",
47+
"secret" : "938dbad2-46ea-4d5a-89bb-bc8a542402d0",
48+
"redirectUris" : [ "http://127.0.0.1:8383/*" ],
49+
"webOrigins" : [ "http://127.0.0.1:8383" ],
50+
"notBefore" : 0,
51+
"bearerOnly" : false,
52+
"consentRequired" : false,
53+
"standardFlowEnabled" : true,
54+
"implicitFlowEnabled" : false,
55+
"directAccessGrantsEnabled" : true,
56+
"serviceAccountsEnabled" : false,
57+
"publicClient" : true,
58+
"frontchannelLogout" : false,
59+
"protocol" : "openid-connect",
60+
"attributes" : { },
61+
"authenticationFlowBindingOverrides" : { },
62+
"fullScopeAllowed" : true,
63+
"nodeReRegistrationTimeout" : -1,
64+
"protocolMappers" : [ {
65+
"id" : "6e0abb44-b801-49f9-9e64-48d59f226e18",
66+
"name" : "instanceids_mapper",
67+
"protocol" : "openid-connect",
68+
"protocolMapper" : "oidc-usermodel-attribute-mapper",
69+
"consentRequired" : false,
70+
"config" : {
71+
"multivalued" : "true",
72+
"userinfo.token.claim" : "true",
73+
"user.attribute" : "instanceIds",
74+
"id.token.claim" : "true",
75+
"access.token.claim" : "true",
76+
"claim.name" : "instanceIds"
77+
}
78+
}, {
79+
"id" : "3ffa942d-7e5b-4c1b-95f3-253c84103d4d",
80+
"name" : "role_mapper",
81+
"protocol" : "openid-connect",
82+
"protocolMapper" : "oidc-usermodel-attribute-mapper",
83+
"consentRequired" : false,
84+
"config" : {
85+
"user.attribute" : "role",
86+
"id.token.claim" : "true",
87+
"access.token.claim" : "true",
88+
"claim.name" : "role",
89+
"userinfo.token.claim" : "true"
90+
}
91+
} ],
92+
"defaultClientScopes" : [ "web-origins", "role_list", "profile", "roles", "email" ],
93+
"optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
94+
} ],
95+
"clientScopes" : [ {
96+
"id" : "95fbe161-21aa-48fa-b758-9bd375b0bb26",
97+
"name" : "email",
98+
"description" : "OpenID Connect built-in scope: email",
99+
"protocol" : "openid-connect",
100+
"attributes" : {
101+
"include.in.token.scope" : "true",
102+
"display.on.consent.screen" : "true",
103+
"consent.screen.text" : "${emailScopeConsentText}"
104+
},
105+
"protocolMappers" : [ {
106+
"id" : "63956872-465e-4e66-a078-5a7bb80bb4db",
107+
"name" : "email verified",
108+
"protocol" : "openid-connect",
109+
"protocolMapper" : "oidc-usermodel-property-mapper",
110+
"consentRequired" : false,
111+
"config" : {
112+
"userinfo.token.claim" : "true",
113+
"user.attribute" : "emailVerified",
114+
"id.token.claim" : "true",
115+
"access.token.claim" : "true",
116+
"claim.name" : "email_verified",
117+
"jsonType.label" : "boolean"
118+
}
119+
}, {
120+
"id" : "15dbd4b1-8e80-4dea-b920-0304a8798dc4",
121+
"name" : "email",
122+
"protocol" : "openid-connect",
123+
"protocolMapper" : "oidc-usermodel-property-mapper",
124+
"consentRequired" : false,
125+
"config" : {
126+
"userinfo.token.claim" : "true",
127+
"user.attribute" : "email",
128+
"id.token.claim" : "true",
129+
"access.token.claim" : "true",
130+
"claim.name" : "email",
131+
"jsonType.label" : "String"
132+
}
133+
} ]
134+
}, {
135+
"id" : "3bfd2985-6d71-49a9-b2eb-b8006702d83a",
136+
"name" : "profile",
137+
"description" : "OpenID Connect built-in scope: profile",
138+
"protocol" : "openid-connect",
139+
"attributes" : {
140+
"include.in.token.scope" : "true",
141+
"display.on.consent.screen" : "true",
142+
"consent.screen.text" : "${profileScopeConsentText}"
143+
},
144+
"protocolMappers" : [ {
145+
"id" : "fcfa7294-ef3a-4506-a985-d0161bbbf5ba",
146+
"name" : "username",
147+
"protocol" : "openid-connect",
148+
"protocolMapper" : "oidc-usermodel-property-mapper",
149+
"consentRequired" : false,
150+
"config" : {
151+
"userinfo.token.claim" : "true",
152+
"user.attribute" : "username",
153+
"id.token.claim" : "true",
154+
"access.token.claim" : "true",
155+
"claim.name" : "preferred_username",
156+
"jsonType.label" : "String"
157+
}
158+
}, {
159+
"id" : "aa388da9-d7e8-4550-9442-ad1683a8b1cd",
160+
"name" : "picture",
161+
"protocol" : "openid-connect",
162+
"protocolMapper" : "oidc-usermodel-attribute-mapper",
163+
"consentRequired" : false,
164+
"config" : {
165+
"userinfo.token.claim" : "true",
166+
"user.attribute" : "picture",
167+
"id.token.claim" : "true",
168+
"access.token.claim" : "true",
169+
"claim.name" : "picture",
170+
"jsonType.label" : "String"
171+
}
172+
}, {
173+
"id" : "05fd2f4b-7a19-43f1-b517-df720cd2411c",
174+
"name" : "profile",
175+
"protocol" : "openid-connect",
176+
"protocolMapper" : "oidc-usermodel-attribute-mapper",
177+
"consentRequired" : false,
178+
"config" : {
179+
"userinfo.token.claim" : "true",
180+
"user.attribute" : "profile",
181+
"id.token.claim" : "true",
182+
"access.token.claim" : "true",
183+
"claim.name" : "profile",
184+
"jsonType.label" : "String"
185+
}
186+
}, {
187+
"id" : "57e373b4-71da-4397-a64a-ed2f8d517b0d",
188+
"name" : "full name",
189+
"protocol" : "openid-connect",
190+
"protocolMapper" : "oidc-full-name-mapper",
191+
"consentRequired" : false,
192+
"config" : {
193+
"id.token.claim" : "true",
194+
"access.token.claim" : "true",
195+
"userinfo.token.claim" : "true"
196+
}
197+
}, {
198+
"id" : "2ff0b568-7eb3-4df0-a314-b5b4ba01b7d8",
199+
"name" : "updated at",
200+
"protocol" : "openid-connect",
201+
"protocolMapper" : "oidc-usermodel-attribute-mapper",
202+
"consentRequired" : false,
203+
"config" : {
204+
"userinfo.token.claim" : "true",
205+
"user.attribute" : "updatedAt",
206+
"id.token.claim" : "true",
207+
"access.token.claim" : "true",
208+
"claim.name" : "updated_at",
209+
"jsonType.label" : "String"
210+
}
211+
} ]
212+
}, {
213+
"id" : "ea283116-8683-490b-93c3-3ee5e5b02119",
214+
"name" : "role_list",
215+
"description" : "SAML role list",
216+
"protocol" : "saml",
217+
"attributes" : {
218+
"consent.screen.text" : "${samlRoleListScopeConsentText}",
219+
"display.on.consent.screen" : "true"
220+
},
221+
"protocolMappers" : [ {
222+
"id" : "7ac1e70d-7282-4111-82aa-2736de9bf12f",
223+
"name" : "role list",
224+
"protocol" : "saml",
225+
"protocolMapper" : "saml-role-list-mapper",
226+
"consentRequired" : false,
227+
"config" : {
228+
"single" : "false",
229+
"attribute.nameformat" : "Basic",
230+
"attribute.name" : "Role"
231+
}
232+
} ]
233+
}, {
234+
"id" : "7f2a0f28-1027-4cd5-9915-22d19d8d8107",
235+
"name" : "roles",
236+
"description" : "OpenID Connect scope for add user roles to the access token",
237+
"protocol" : "openid-connect",
238+
"attributes" : {
239+
"include.in.token.scope" : "false",
240+
"display.on.consent.screen" : "true",
241+
"consent.screen.text" : "${rolesScopeConsentText}"
242+
},
243+
"protocolMappers" : [ {
244+
"id" : "ae3e18bd-49b3-439a-9290-54552f7d08cd",
245+
"name" : "realm roles",
246+
"protocol" : "openid-connect",
247+
"protocolMapper" : "oidc-usermodel-realm-role-mapper",
248+
"consentRequired" : false,
249+
"config" : {
250+
"user.attribute" : "foo",
251+
"access.token.claim" : "true",
252+
"claim.name" : "realm_access.roles",
253+
"jsonType.label" : "String",
254+
"multivalued" : "true"
255+
}
256+
}, {
257+
"id" : "6c6a86ac-8f63-4ad7-8be0-ee61235a35c3",
258+
"name" : "audience resolve",
259+
"protocol" : "openid-connect",
260+
"protocolMapper" : "oidc-audience-resolve-mapper",
261+
"consentRequired" : false,
262+
"config" : { }
263+
}, {
264+
"id" : "0b07106f-fc89-4349-99fe-0f046af43fdc",
265+
"name" : "client roles",
266+
"protocol" : "openid-connect",
267+
"protocolMapper" : "oidc-usermodel-client-role-mapper",
268+
"consentRequired" : false,
269+
"config" : {
270+
"user.attribute" : "foo",
271+
"access.token.claim" : "true",
272+
"claim.name" : "resource_access.${client_id}.roles",
273+
"jsonType.label" : "String",
274+
"multivalued" : "true"
275+
}
276+
} ]
277+
} ],
278+
"defaultDefaultClientScopes" : [ "profile", "web-origins", "roles", "email", "role_list" ]
279+
}

‎eve/workers/worker.yaml

+18-2
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,33 @@ spec:
99
image: {{ images.build }}
1010
resources:
1111
requests:
12-
cpu: "3"
12+
cpu: "2"
1313
memory: 4Gi
1414
limits:
15-
cpu: "3"
15+
cpu: "2"
1616
memory: 4Gi
1717
env:
1818
- name: DOCKER_HOST
1919
value: localhost
2020
volumeMounts:
2121
- name: workspace
2222
mountPath: /home/eve/workspace
23+
- name: keycloak
24+
image: {{ images.keycloakconfig }}
25+
resources:
26+
requests:
27+
cpu: "1"
28+
memory: 1Gi
29+
limits:
30+
cpu: "1"
31+
memory: 1Gi
32+
{% if vars.keycloakconfig.env is defined %}
33+
env:
34+
{% for key, value in vars.keycloakconfig.env.items() %}
35+
- name: "{{ key }}"
36+
value: "{{ value }}"
37+
{% endfor %}
38+
{% endif %}
2339
- name: dind-daemon
2440
image: docker:18.09.2-dind
2541
resources:

‎package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"test": "jest",
88
"test:lint": "eslint --ext js --ext jsx src",
99
"start:dev": "webpack-dev-server --config webpack.dev.js",
10-
"build": "webpack --config webpack.prod.js"
10+
"build": "webpack --config webpack.prod.js",
11+
"cypress:run": "cypress run",
12+
"cypress:open": "cypress open"
1113
},
1214
"keywords": [],
1315
"author": "",
@@ -22,9 +24,11 @@
2224
"babel-eslint": "^10.0.3",
2325
"babel-loader": "^8.0.6",
2426
"css-loader": "^3.4.2",
27+
"cypress": "^4.8.0",
2528
"enzyme": "^3.11.0",
2629
"enzyme-adapter-react-16": "^1.15.2",
2730
"eslint": "^6.8.0",
31+
"eslint-plugin-cypress": "^2.11.1",
2832
"eslint-plugin-flowtype": "^4.6.0",
2933
"eslint-plugin-flowtype-errors": "^4.1.0",
3034
"eslint-plugin-import": "^2.20.1",

‎public/assets/config.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"managementEndpoint": "http://127.0.0.1:5000",
3-
"oidcAuthority": "http://localhost:8080/auth/realms/myrealm",
3+
"oidcAuthority": "http://127.0.0.1:8080/auth/realms/myrealm",
44
"oidcClientId": "myclient",
55
"stsEndpoint": "https://sts.amazonaws.com",
66
"s3Endpoint": "https://s3.amazonaws.com"

‎wait_for_local_port.bash

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bash
2+
wait_for_local_port() {
3+
local port=$1
4+
local timeout=$2
5+
local count=0
6+
local ret=1
7+
echo "waiting for localhost:$port"
8+
while [[ "$ret" -eq "1" && "$count" -lt "$timeout" ]] ; do
9+
nc -z -w 1 localhost $port
10+
ret=$?
11+
if [ ! "$ret" -eq "0" ]; then
12+
echo -n .
13+
sleep 1
14+
count=$(($count+1))
15+
fi
16+
done
17+
18+
echo ""
19+
20+
if [[ "$count" -eq "$timeout" ]]; then
21+
echo "Server did not start in less than $timeout seconds. Exiting..."
22+
exit 1
23+
fi
24+
25+
echo "Server got ready in ~${count} seconds. Starting test now..."
26+
}
27+
28+
wait_for_local_port $1 $2

‎yarn.lock

+474-35
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.