Allow New Admin Console to run as a WAR on Keycloak server. (#439)
* Allow app to run as a WAR on Keycloak server. * New client creation json that works for both dev and prod * fixed tests * Try Mark's trick to get realm_test to run. * Make tests use keycloakBefore() * Fix duplicate import * fix github actions Co-authored-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
21c0cfcdad
commit
398ca19ec1
20 changed files with 130 additions and 63 deletions
3
.github/workflows/cypress.yml
vendored
3
.github/workflows/cypress.yml
vendored
|
@ -30,7 +30,8 @@ jobs:
|
|||
run: ./start.js & sleep 40
|
||||
|
||||
- name: Run Admin Console
|
||||
run: npx http-server ./build -P http://localhost:8180/auth/ & sleep 30
|
||||
run: mkdir ./build/adminv2 && mv ./build/js ./build/adminv2/
|
||||
run: npx http-server ./build -P http://localhost:8180/ & sleep 30
|
||||
|
||||
- name: Admin Console client
|
||||
run: ./import.js
|
||||
|
|
|
@ -3,6 +3,7 @@ import Masthead from "../support/pages/admin_console/Masthead";
|
|||
import ListingPage from "../support/pages/admin_console/ListingPage";
|
||||
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
||||
import CreateClientScopePage from "../support/pages/admin_console/manage/client_scopes/CreateClientScopePage";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
let itemId = "client_scope_crud";
|
||||
const loginPage = new LoginPage();
|
||||
|
@ -12,10 +13,9 @@ const listingPage = new ListingPage();
|
|||
const createClientScopePage = new CreateClientScopePage();
|
||||
|
||||
describe("Client Scopes test", function () {
|
||||
|
||||
describe("Client Scope creation", function () {
|
||||
beforeEach(function () {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToClientScopes();
|
||||
});
|
||||
|
@ -44,14 +44,14 @@ describe("Client Scopes test", function () {
|
|||
|
||||
createClientScopePage.fillClientScopeData(itemId).save();
|
||||
|
||||
masthead.checkNotificationMessage("Client scope created");
|
||||
masthead.checkNotificationMessage("Client scope created");
|
||||
|
||||
sidebarPage.goToClientScopes();
|
||||
|
||||
// Delete
|
||||
listingPage.itemExist(itemId).deleteItem(itemId); // There should be a confirmation pop-up
|
||||
|
||||
masthead.checkNotificationMessage("The client scope has been deleted");
|
||||
masthead.checkNotificationMessage("The client scope has been deleted");
|
||||
|
||||
listingPage // It is not refreshing after delete
|
||||
.itemExist(itemId, false);
|
||||
|
|
|
@ -7,6 +7,7 @@ import ModalUtils from "../support/util/ModalUtils";
|
|||
import AdvancedTab from "../support/pages/admin_console/manage/clients/AdvancedTab";
|
||||
import AdminClient from "../support/util/AdminClient";
|
||||
import InitialAccessTokenTab from "../support/pages/admin_console/manage/clients/InitialAccessTokenTab";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
let itemId = "client_crud";
|
||||
const loginPage = new LoginPage();
|
||||
|
@ -19,7 +20,7 @@ const modalUtils = new ModalUtils();
|
|||
describe("Clients test", function () {
|
||||
describe("Client creation", function () {
|
||||
beforeEach(function () {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToClients();
|
||||
});
|
||||
|
@ -107,7 +108,7 @@ describe("Clients test", function () {
|
|||
let client: string;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToClients();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
|||
import LoginPage from "../support/pages/LoginPage";
|
||||
import ViewHeaderPage from "../support/pages/ViewHeaderPage";
|
||||
import AdminClient from "../support/util/AdminClient";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
describe("Group test", () => {
|
||||
const loginPage = new LoginPage();
|
||||
|
@ -20,7 +21,7 @@ describe("Group test", () => {
|
|||
|
||||
describe("Group creation", () => {
|
||||
beforeEach(function () {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToGroups();
|
||||
});
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import LoginPage from "../support/pages/LoginPage";
|
||||
import Masthead from "../support/pages/admin_console/Masthead";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
const username = "admin";
|
||||
const password = "admin";
|
||||
|
@ -8,18 +9,14 @@ const loginPage = new LoginPage();
|
|||
const masthead = new Masthead();
|
||||
|
||||
describe("Logging In", function () {
|
||||
|
||||
beforeEach(function () {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
});
|
||||
|
||||
it("displays errors on wrong credentials", function () {
|
||||
loginPage
|
||||
.logIn("wrong", "user{enter}");
|
||||
|
||||
loginPage
|
||||
.checkErrorMessage("Invalid username or password.")
|
||||
.isLogInPage();
|
||||
loginPage.logIn("wrong", "user{enter}");
|
||||
|
||||
loginPage.checkErrorMessage("Invalid username or password.").isLogInPage();
|
||||
});
|
||||
|
||||
it("logs in", function () {
|
||||
|
|
|
@ -2,6 +2,7 @@ import ListingPage from "../support/pages/admin_console/ListingPage";
|
|||
import LoginPage from "../support/pages/LoginPage";
|
||||
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
||||
import Masthead from "../support/pages/admin_console/Masthead";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
|
@ -24,7 +25,7 @@ const goToAcctMgtTest = () => {
|
|||
|
||||
describe("Masthead tests in desktop mode", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
});
|
||||
|
||||
|
@ -51,7 +52,7 @@ describe("Masthead tests in desktop mode", () => {
|
|||
|
||||
describe("Masthead tests with kebab menu", () => {
|
||||
beforeEach(() => {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
masthead.setMobileMode(true);
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@ import ListingPage from "../support/pages/admin_console/ListingPage";
|
|||
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
||||
import CreateRealmRolePage from "../support/pages/admin_console/manage/realm_roles/CreateRealmRolePage";
|
||||
import AssociatedRolesPage from "../support/pages/admin_console/manage/realm_roles/AssociatedRolesPage";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
let itemId = "realm_role_crud";
|
||||
const loginPage = new LoginPage();
|
||||
|
@ -18,7 +19,7 @@ const associatedRolesPage = new AssociatedRolesPage();
|
|||
describe("Realm roles test", function () {
|
||||
describe("Realm roles creation", function () {
|
||||
beforeEach(function () {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToRealmRoles();
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@ import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
|||
import CreateRealmPage from "../support/pages/admin_console/CreateRealmPage";
|
||||
import Masthead from "../support/pages/admin_console/Masthead";
|
||||
import AdminClient from "../support/util/AdminClient";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
const masthead = new Masthead();
|
||||
const loginPage = new LoginPage();
|
||||
|
@ -13,7 +14,7 @@ describe("Realms test", function () {
|
|||
const testRealmName = "Test realm";
|
||||
describe("Realm creation", function () {
|
||||
beforeEach(function () {
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
});
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
|||
import ProviderPage from "../support/pages/admin_console/manage/providers/ProviderPage";
|
||||
import Masthead from "../support/pages/admin_console/Masthead";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
|
@ -41,19 +42,10 @@ const disableModalTitle = "Disable user federation provider?";
|
|||
|
||||
describe("User Fed Kerberos tests", () => {
|
||||
beforeEach(() => {
|
||||
/*
|
||||
Prevent unpredictable 401 errors from failing individual tests.
|
||||
These are most often occurring during the login process:
|
||||
GET /admin/serverinfo/
|
||||
GET /admin/master/console/whoami
|
||||
*/
|
||||
cy.on("uncaught:exception", (err, runnable) => {
|
||||
return false;
|
||||
});
|
||||
cy.visit("");
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToUserFederation();
|
||||
});
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToUserFederation();
|
||||
});
|
||||
|
||||
it("Create Kerberos provider from empty state", () => {
|
||||
// if tests don't start at empty state, e.g. user has providers configured locally,
|
||||
|
|
|
@ -3,6 +3,7 @@ import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
|||
import ProviderPage from "../support/pages/admin_console/manage/providers/ProviderPage";
|
||||
import Masthead from "../support/pages/admin_console/Masthead";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
|
@ -58,16 +59,7 @@ const disableModalTitle = "Disable user federation provider?";
|
|||
|
||||
describe("User Fed LDAP tests", () => {
|
||||
beforeEach(() => {
|
||||
/*
|
||||
Prevent unpredictable 401 errors from failing individual tests.
|
||||
These are most often occurring during the login process:
|
||||
GET /admin/serverinfo/
|
||||
GET /admin/master/console/whoami
|
||||
*/
|
||||
cy.on("uncaught:exception", (err, runnable) => {
|
||||
return false;
|
||||
});
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToUserFederation();
|
||||
});
|
||||
|
|
|
@ -5,6 +5,7 @@ import Masthead from "../support/pages/admin_console/Masthead";
|
|||
import ListingPage from "../support/pages/admin_console/ListingPage";
|
||||
import UserDetailsPage from "../support/pages/admin_console/manage/users/UserDetailsPage";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import { keycloakBefore } from "../support/util/keycloak_before";
|
||||
|
||||
describe("Users test", () => {
|
||||
const loginPage = new LoginPage();
|
||||
|
@ -19,16 +20,7 @@ describe("Users test", () => {
|
|||
|
||||
describe("User creation", () => {
|
||||
beforeEach(() => {
|
||||
/*
|
||||
Prevent unpredictable 401 errors from failing individual tests.
|
||||
These are most often occurring during the login process:
|
||||
GET /admin/serverinfo/
|
||||
GET /admin/master/console/whoami
|
||||
*/
|
||||
cy.on("uncaught:exception", () => {
|
||||
return false;
|
||||
});
|
||||
cy.visit("");
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToUsers();
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ export default class ListingPage {
|
|||
|
||||
searchItem(searchValue: string, wait = true) {
|
||||
if (wait) {
|
||||
const searchUrl = `/admin/realms/master/*${searchValue}*`;
|
||||
const searchUrl = `/auth/admin/realms/master/*${searchValue}*`;
|
||||
cy.intercept(searchUrl).as("search");
|
||||
}
|
||||
cy.get(this.searchInput).type(searchValue);
|
||||
|
|
15
cypress/support/util/keycloak_before.ts
Normal file
15
cypress/support/util/keycloak_before.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export const keycloakBefore = () => {
|
||||
/*
|
||||
Prevent unpredictable 401 errors from failing individual tests.
|
||||
These are most often occurring during the login process:
|
||||
GET /admin/serverinfo/
|
||||
GET /admin/master/console/whoami
|
||||
*/
|
||||
cy.on("uncaught:exception", (err, runnable) => {
|
||||
console.log("-------------------");
|
||||
console.log(err);
|
||||
console.log("--------------------");
|
||||
return false;
|
||||
});
|
||||
cy.visit("");
|
||||
};
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link id="favicon" rel="icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/index.css" />
|
||||
<link id="favicon" rel="icon" href="./favicon.ico" />
|
||||
<link rel="stylesheet" href="./index.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="description" content="Web site to manage keycloak" />
|
||||
<title>Keycloak Administration Console</title>
|
||||
|
|
66
security-admin-console-v2-combined.json
Normal file
66
security-admin-console-v2-combined.json
Normal file
|
@ -0,0 +1,66 @@
|
|||
{
|
||||
"clientId": "security-admin-console-v2",
|
||||
"rootUrl": "",
|
||||
"adminUrl": "",
|
||||
"baseUrl": "",
|
||||
"surrogateAuthRequired": false,
|
||||
"enabled": true,
|
||||
"alwaysDisplayInConsole": false,
|
||||
"clientAuthenticatorType": "client-secret",
|
||||
"redirectUris": [
|
||||
"/adminv2/*",
|
||||
"http://localhost:8080/*"
|
||||
],
|
||||
"webOrigins": [
|
||||
"*"
|
||||
],
|
||||
"notBefore": 0,
|
||||
"bearerOnly": false,
|
||||
"consentRequired": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"serviceAccountsEnabled": false,
|
||||
"publicClient": true,
|
||||
"frontchannelLogout": false,
|
||||
"protocol": "openid-connect",
|
||||
"attributes": {
|
||||
"saml.assertion.signature": "false",
|
||||
"saml.force.post.binding": "false",
|
||||
"saml.multivalued.roles": "false",
|
||||
"saml.encrypt": "false",
|
||||
"backchannel.logout.revoke.offline.tokens": "false",
|
||||
"saml.server.signature": "false",
|
||||
"saml.server.signature.keyinfo.ext": "false",
|
||||
"exclude.session.state.from.auth.response": "false",
|
||||
"backchannel.logout.session.required": "true",
|
||||
"client_credentials.use_refresh_token": "false",
|
||||
"saml_force_name_id_format": "false",
|
||||
"saml.client.signature": "false",
|
||||
"tls.client.certificate.bound.access.tokens": "false",
|
||||
"saml.authnstatement": "false",
|
||||
"display.on.consent.screen": "false",
|
||||
"saml.onetimeuse.condition": "false"
|
||||
},
|
||||
"authenticationFlowBindingOverrides": {},
|
||||
"fullScopeAllowed": true,
|
||||
"nodeReRegistrationTimeout": -1,
|
||||
"defaultClientScopes": [
|
||||
"web-origins",
|
||||
"role_list",
|
||||
"roles",
|
||||
"profile",
|
||||
"email"
|
||||
],
|
||||
"optionalClientScopes": [
|
||||
"address",
|
||||
"phone",
|
||||
"offline_access",
|
||||
"microprofile-jwt"
|
||||
],
|
||||
"access": {
|
||||
"view": true,
|
||||
"configure": true,
|
||||
"manage": true
|
||||
}
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
module.exports = {
|
||||
extends: "@snowpack/app-scripts-react",
|
||||
proxy: {
|
||||
"/admin": "http://localhost:8180/auth/admin/",
|
||||
"/auth/admin": "http://localhost:8180/auth/admin/",
|
||||
},
|
||||
plugins: ["@snowpack/plugin-postcss", "@snowpack/plugin-webpack"],
|
||||
buildOptions: {
|
||||
baseUrl: "/adminv2",
|
||||
clean: true,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { ReactNode, useEffect } from "react";
|
||||
import { Page } from "@patternfly/react-core";
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
HashRouter as Router,
|
||||
Route,
|
||||
Switch,
|
||||
useParams,
|
||||
|
|
|
@ -129,7 +129,7 @@ export const Header = () => {
|
|||
<UserDropdown />
|
||||
</PageHeaderToolsItem>
|
||||
</PageHeaderToolsGroup>
|
||||
<Avatar src="/img_avatar.svg" alt="Avatar image" />
|
||||
<Avatar src="./img_avatar.svg" alt="Avatar image" />
|
||||
</PageHeaderTools>
|
||||
);
|
||||
};
|
||||
|
@ -183,7 +183,7 @@ export const Header = () => {
|
|||
logo={
|
||||
<Link to="/">
|
||||
<Brand
|
||||
src="/logo.svg"
|
||||
src="./logo.svg"
|
||||
id="masthead-logo"
|
||||
alt="Logo"
|
||||
className="keycloak__pageheader_brand"
|
||||
|
|
|
@ -6,17 +6,20 @@ export default async function (): Promise<KcAdminClient> {
|
|||
|
||||
const kcAdminClient = new KcAdminClient();
|
||||
|
||||
const authContext = "/auth";
|
||||
const keycloakAuthUrl = window.location.origin + authContext;
|
||||
const devMode = !window.location.pathname.startsWith("/adminv2");
|
||||
try {
|
||||
await kcAdminClient.init(
|
||||
{ onLoad: "check-sso", pkceMethod: "S256" },
|
||||
{
|
||||
url: "http://localhost:8180/auth/",
|
||||
url: devMode ? "http://localhost:8180/auth" : keycloakAuthUrl,
|
||||
realm: realm,
|
||||
clientId: "security-admin-console-v2",
|
||||
}
|
||||
);
|
||||
kcAdminClient.setConfig({ realmName: realm });
|
||||
kcAdminClient.baseUrl = "";
|
||||
kcAdminClient.baseUrl = authContext;
|
||||
} catch (error) {
|
||||
alert("failed to initialize keycloak");
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ const EmptyDashboard = () => {
|
|||
<PageSection variant="light">
|
||||
<EmptyState variant="large">
|
||||
<Brand
|
||||
src="/icon.svg"
|
||||
src="./icon.svg"
|
||||
alt="Keycloak icon"
|
||||
className="keycloak__dashboard_icon"
|
||||
/>
|
||||
|
|
Loading…
Reference in a new issue