Fixes SAML provider AuthnContext Constraints fields (#2231)
* no multiline for now * multiline work in progress * changed to JSON.stringify * both multiline fields working * check for undefined to prevent JSON issue * streamline saml and oidc provider tests * final tests and misc fixes Co-authored-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
e672849935
commit
45b6be4fe8
7 changed files with 122 additions and 58 deletions
|
@ -26,7 +26,6 @@ describe("OIDC identity provider test", () => {
|
|||
const authorizationUrl = `${keycloakServer}/realms/master/protocol/openid-connect/auth`;
|
||||
|
||||
describe("OIDC Identity provider creation", () => {
|
||||
const identityProviderName = "github";
|
||||
const oidcProviderName = "oidc";
|
||||
const secret = "123";
|
||||
|
||||
|
@ -36,25 +35,14 @@ describe("OIDC identity provider test", () => {
|
|||
sidebarPage.goToIdentityProviders();
|
||||
});
|
||||
|
||||
it("should create provider", () => {
|
||||
createProviderPage.checkGitHubCardVisible().clickGitHubCard();
|
||||
|
||||
createProviderPage.checkAddButtonDisabled();
|
||||
createProviderPage
|
||||
.fill(identityProviderName)
|
||||
.clickAdd()
|
||||
.checkClientIdRequiredMessage(true);
|
||||
createProviderPage.fill(identityProviderName, secret).clickAdd();
|
||||
masthead.checkNotificationMessage(createSuccessMsg, true);
|
||||
|
||||
sidebarPage.goToIdentityProviders();
|
||||
listingPage.itemExist(identityProviderName);
|
||||
});
|
||||
|
||||
it("should create an OIDC provider using discovery url", () => {
|
||||
createProviderPage
|
||||
.clickCreateDropdown()
|
||||
.clickItem(oidcProviderName)
|
||||
.checkVisible(oidcProviderName)
|
||||
.clickCard(oidcProviderName);
|
||||
|
||||
createProviderPage.checkAddButtonDisabled();
|
||||
|
||||
createProviderPage
|
||||
.fillDiscoveryUrl(discoveryUrl)
|
||||
.shouldBeSuccessful()
|
||||
.fill(oidcProviderName, secret)
|
||||
|
@ -88,11 +76,6 @@ describe("OIDC identity provider test", () => {
|
|||
listingPage.itemExist(oidcProviderName).deleteItem(oidcProviderName);
|
||||
modalUtils.checkModalTitle(deletePrompt).confirmModal();
|
||||
masthead.checkNotificationMessage(deleteSuccessMsg, true);
|
||||
listingPage
|
||||
.itemExist(identityProviderName)
|
||||
.deleteItem(identityProviderName);
|
||||
modalUtils.checkModalTitle(deletePrompt).confirmModal();
|
||||
masthead.checkNotificationMessage(deleteSuccessMsg, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,7 @@ import CreateProviderPage from "../support/pages/admin_console/manage/identity_p
|
|||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import AddMapperPage from "../support/pages/admin_console/manage/identity_providers/AddMapperPage";
|
||||
|
||||
describe("Identity provider test", () => {
|
||||
describe("SAML identity provider test", () => {
|
||||
const loginPage = new LoginPage();
|
||||
const sidebarPage = new SidebarPage();
|
||||
const masthead = new Masthead();
|
||||
|
@ -16,19 +16,22 @@ describe("Identity provider test", () => {
|
|||
const addMapperPage = new AddMapperPage();
|
||||
|
||||
const createSuccessMsg = "Identity provider successfully created";
|
||||
const saveSuccessMsg = "Provider successfully updated";
|
||||
|
||||
const createMapperSuccessMsg = "Mapper created successfully.";
|
||||
const saveMapperSuccessMsg = "Mapper saved successfully.";
|
||||
|
||||
const deletePrompt = "Delete provider?";
|
||||
const deleteSuccessMsg = "Provider successfully deleted";
|
||||
|
||||
const classRefName = "acClassRef-1";
|
||||
const declRefName = "acDeclRef-1";
|
||||
|
||||
const keycloakServer = Cypress.env("KEYCLOAK_SERVER");
|
||||
const samlDiscoveryUrl = `${keycloakServer}/realms/master/protocol/saml/descriptor`;
|
||||
|
||||
describe("SAML identity provider creation", () => {
|
||||
const identityProviderName = "github";
|
||||
const samlProviderName = "saml";
|
||||
const secret = "123";
|
||||
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
|
@ -36,31 +39,30 @@ describe("Identity provider test", () => {
|
|||
sidebarPage.goToIdentityProviders();
|
||||
});
|
||||
|
||||
it("should create provider", () => {
|
||||
createProviderPage.checkGitHubCardVisible().clickGitHubCard();
|
||||
|
||||
it("should create a SAML provider using entity descriptor", () => {
|
||||
createProviderPage
|
||||
.checkVisible(samlProviderName)
|
||||
.clickCard(samlProviderName);
|
||||
createProviderPage.checkAddButtonDisabled();
|
||||
createProviderPage
|
||||
.fill(identityProviderName)
|
||||
.clickAdd()
|
||||
.checkClientIdRequiredMessage(true);
|
||||
createProviderPage.fill(identityProviderName, secret).clickAdd();
|
||||
masthead.checkNotificationMessage(createSuccessMsg, true);
|
||||
|
||||
sidebarPage.goToIdentityProviders();
|
||||
listingPage.itemExist(identityProviderName);
|
||||
});
|
||||
|
||||
it("should create a SAML provider using SSO service url", () => {
|
||||
createProviderPage
|
||||
.clickCreateDropdown()
|
||||
.clickItem(samlProviderName)
|
||||
.fillDiscoveryUrl(samlDiscoveryUrl)
|
||||
.shouldBeSuccessful()
|
||||
.clickAdd();
|
||||
masthead.checkNotificationMessage(createSuccessMsg, true);
|
||||
});
|
||||
|
||||
it("should add auth constraints to existing SAML provider", () => {
|
||||
sidebarPage.goToIdentityProviders();
|
||||
listingPage.goToItemDetails(samlProviderName);
|
||||
createProviderPage
|
||||
.fillAuthnContextClassRefs(classRefName)
|
||||
.clickClassRefsAdd()
|
||||
.fillAuthnContextDeclRefs(declRefName)
|
||||
.clickDeclRefsAdd()
|
||||
.clickSave();
|
||||
masthead.checkNotificationMessage(saveSuccessMsg, true);
|
||||
});
|
||||
|
||||
it("should add SAML mapper of type Advanced Attribute to Role", () => {
|
||||
sidebarPage.goToIdentityProviders();
|
||||
listingPage.goToItemDetails(samlProviderName);
|
||||
|
@ -153,11 +155,6 @@ describe("Identity provider test", () => {
|
|||
listingPage.itemExist(samlProviderName).deleteItem(samlProviderName);
|
||||
modalUtils.checkModalTitle(deletePrompt).confirmModal();
|
||||
masthead.checkNotificationMessage(deleteSuccessMsg, true);
|
||||
listingPage
|
||||
.itemExist(identityProviderName)
|
||||
.deleteItem(identityProviderName);
|
||||
modalUtils.checkModalTitle(deletePrompt).confirmModal();
|
||||
masthead.checkNotificationMessage(deleteSuccessMsg, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,13 @@ export default class CreateProviderPage {
|
|||
private discoveryEndpoint = "discoveryEndpoint";
|
||||
private authorizationUrl = "authorizationUrl";
|
||||
private addButton = "createProvider";
|
||||
private saveButton = "save";
|
||||
private ssoServiceUrl = "sso-service-url";
|
||||
private authnContextClassRefs = "classref-field";
|
||||
private authnContextDeclRefs = "declref-field";
|
||||
private addProvider = "Add provider";
|
||||
private addClassRef = "Add AuthnContext ClassRef";
|
||||
private addDeclRef = "Add AuthnContext DeclRef";
|
||||
|
||||
checkVisible(name: string) {
|
||||
cy.findByTestId(`${name}-card`).should("exist");
|
||||
|
@ -47,8 +53,23 @@ export default class CreateProviderPage {
|
|||
return this;
|
||||
}
|
||||
|
||||
clickSave() {
|
||||
cy.findByTestId(this.saveButton).click();
|
||||
return this;
|
||||
}
|
||||
|
||||
clickClassRefsAdd() {
|
||||
cy.contains(this.addClassRef).click();
|
||||
return this;
|
||||
}
|
||||
|
||||
clickDeclRefsAdd() {
|
||||
cy.contains(this.addDeclRef).click();
|
||||
return this;
|
||||
}
|
||||
|
||||
clickCreateDropdown() {
|
||||
cy.contains("Add provider").click();
|
||||
cy.contains(this.addProvider).click();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -77,6 +98,18 @@ export default class CreateProviderPage {
|
|||
return this;
|
||||
}
|
||||
|
||||
fillAuthnContextClassRefs(value: string) {
|
||||
cy.findByTestId(this.authnContextClassRefs).type("x");
|
||||
cy.findByTestId(this.authnContextClassRefs).clear().type(value).blur();
|
||||
return this;
|
||||
}
|
||||
|
||||
fillAuthnContextDeclRefs(value: string) {
|
||||
cy.findByTestId(this.authnContextDeclRefs).type("x");
|
||||
cy.findByTestId(this.authnContextDeclRefs).clear().type(value).blur();
|
||||
return this;
|
||||
}
|
||||
|
||||
fillSsoServiceUrl(value: string) {
|
||||
cy.findByTestId(this.ssoServiceUrl).type("x");
|
||||
cy.findByTestId(this.ssoServiceUrl).clear().type(value).blur();
|
||||
|
|
|
@ -141,12 +141,34 @@ export default function DetailSettings() {
|
|||
|
||||
reset(fetchedProvider);
|
||||
setProvider(fetchedProvider);
|
||||
|
||||
if (fetchedProvider.config!.authnContextClassRefs) {
|
||||
form.setValue(
|
||||
"config.authnContextClassRefs",
|
||||
JSON.parse(fetchedProvider.config?.authnContextClassRefs)
|
||||
);
|
||||
}
|
||||
|
||||
if (fetchedProvider.config!.authnContextDeclRefs) {
|
||||
form.setValue(
|
||||
"config.authnContextDeclRefs",
|
||||
JSON.parse(fetchedProvider.config?.authnContextDeclRefs)
|
||||
);
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const save = async (provider?: IdentityProviderRepresentation) => {
|
||||
const p = provider || getValues();
|
||||
if (p.config?.authnContextClassRefs)
|
||||
p.config.authnContextClassRefs = JSON.stringify(
|
||||
p.config.authnContextClassRefs
|
||||
);
|
||||
if (p.config?.authnContextDeclRefs)
|
||||
p.config.authnContextDeclRefs = JSON.stringify(
|
||||
p.config.authnContextDeclRefs
|
||||
);
|
||||
try {
|
||||
await adminClient.identityProviders.update(
|
||||
{ alias },
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
SelectVariant,
|
||||
} from "@patternfly/react-core";
|
||||
|
||||
import { TextField } from "../component/TextField";
|
||||
import { MultiLineInput } from "../../components/multi-line-input/MultiLineInput";
|
||||
import { HelpItem } from "../../components/help-enabler/HelpItem";
|
||||
|
||||
const comparisonValues = ["exact", "minimum", "maximum", "better"];
|
||||
|
@ -61,14 +61,40 @@ export const ReqAuthnConstraints = () => {
|
|||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
<TextField
|
||||
field="config.authnContextClassRefs"
|
||||
label="authnContextClassRefs"
|
||||
/>
|
||||
<TextField
|
||||
field="config.authnContextDeclRefs"
|
||||
label="authnContextDeclRefs"
|
||||
/>
|
||||
<FormGroup
|
||||
label={t("authnContextClassRefs")}
|
||||
fieldId="kc-authnContextClassRefs"
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText="identity-providers-help:authnContextClassRefs"
|
||||
fieldLabelId="authnContextClassRefs"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<MultiLineInput
|
||||
name="config.authnContextClassRefs"
|
||||
aria-label={t("identify-providers:authnContextClassRefs")}
|
||||
addButtonLabel="identity-providers:addAuthnContextClassRef"
|
||||
data-testid="classref-field"
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={t("authnContextDeclRefs")}
|
||||
fieldId="kc-authnContextDeclRefs"
|
||||
labelIcon={
|
||||
<HelpItem
|
||||
helpText="identity-providers-help:authnContextDeclRefs"
|
||||
fieldLabelId="authnContextDeclRefs"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<MultiLineInput
|
||||
name="config.authnContextDeclRefs"
|
||||
aria-label={t("identify-providers:authnContextDeclRefs")}
|
||||
addButtonLabel="identity-providers:addAuthnContextDeclRef"
|
||||
data-testid="declref-field"
|
||||
/>
|
||||
</FormGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ export const DisplayOrder = () => {
|
|||
defaultValue=""
|
||||
render={({ onChange, value }) => (
|
||||
<TextInput
|
||||
id="displayOrder"
|
||||
type="number"
|
||||
value={value}
|
||||
data-testid="displayOrder"
|
||||
|
|
|
@ -147,7 +147,9 @@ export default {
|
|||
storedTokensReadable: "Stored tokens readable",
|
||||
comparison: "Comparison",
|
||||
authnContextClassRefs: "AuthnContext ClassRefs",
|
||||
addAuthnContextClassRef: "Add AuthnContext ClassRef",
|
||||
authnContextDeclRefs: "AuthnContext DeclRefs",
|
||||
addAuthnContextDeclRef: "Add AuthnContext DeclRef",
|
||||
trustEmail: "Trust Email",
|
||||
accountLinkingOnly: "Account linking only",
|
||||
hideOnLoginPage: "Hide on login page",
|
||||
|
|
Loading…
Reference in a new issue